davidpham87/mcp-bb-clj
If you are the rightful owner of mcp-bb-clj and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
An MCP server/client written in Clojure for Babashka, implementing the Model Context Protocol using Babashka libraries.
mcp-bb-clj
An MCP server/client written in clojure for babashka
Implementation of MCP protocol (https://modelcontextprotocol.io/specification/2025-06-18/schema) using only babashka (clojure) libraries https://book.babashka.org/#libraries
Split implementation:
- Data manipulation through pure functions
- Expose the function using http-skit server.
- Make a client as well.
Inspiration:
Tools
The server comes with several built-in tools:
- cljfmt: Formats Clojure code using cljfmt.
- Input:
code(string)
- Input:
- zprint: Formats Clojure code or EDN using zprint.
- Input:
code(string),options(optional EDN string)
- Input:
- find-malformed-delimiters: Checks Clojure code for malformed delimiters.
- Input:
code(string)
- Input:
- clj-kondo: Lints Clojure code using clj-kondo.
- Input:
code(string) - Prerequisite: The
clj-kondobinary must be installed and available in the system PATH.
- Input:
- echo: Echoes the input text.
- Malli Tools: Tools for working with Malli schemas (
validate-schema,generate-sample,infer-schema).
Adding new Tools and Prompts
Adding a Tool
To add a new tool, define it as a map and register it in src/mcp_bb_clj/core.clj.
-
Define the tool:
A tool definition requires a
:name,:description,:inputSchema(JSON Schema), and an:implementationfunction.Example:
(def my-tool {:name "my-tool" :description "A custom tool description" :inputSchema {:type "object" :properties {"arg" {:type "string"}} :required ["arg"]} :implementation (fn [{:keys [arg]}] {:content [{:type "text" :text (str "You said: " arg)}]})}) -
Register the tool:
Add the tool to the
mcp-server/add-tool!call insrc/mcp_bb_clj/core.clj.(mcp-server/add-tool! mcp-server {:tools [echo-tool my-tool]})
Adding a Prompt
Prompts can be defined similarly and used as templates.
-
Define the prompt:
(def my-prompt {:name "explain-code" :description "Explains the provided code." :arguments {:type "object" :properties {"code" {:type "string"}} :required ["code"]} :messages [{:role "user" :content "Explain this code:\n\n{{code}}"}]})