Modex(MOdel + ContEXt)是一个Clojure库,它允许您通过新的工具、资源和提示来增强您的AI。
Modex实现了模型上下文协议的大部分内容,以构建“原生”Clojure的MCP服务器和客户端。
由于它是原生Clojure,因此无需处理Anthropic的MCP Java SDK。
Modex实现了2024-11-05 MCP规范中的stdio传输,因此不需要像mcp-proxy这样的代理来在SSE和stdio之间进行转换。
Claude Desktop可以通过其MCP客户端与一个Modex MCP服务器通信:
git clone git@github.com:theronic/modex.gitcd modex./build.sh 在target/modex-mcp-0.2.2.jar生成一个uberjar。~/Library/Application\ Support/Claude/claude_desktop_config.json{
"mcpServers": {
"modex-mcp-hello-world": {
"command": "java",
"args": ["-jar", "/Users/your-username/code/modex/target/modex-mcp-0.2.2.jar"]
}
},
"globalShortcut": ""
}
MCP允许您通过工具、资源和提示来增强您的AI模型:
Modex被datomic-mcp使用,它公开了我们的生产Datomic数据库给像Claude Desktop这样的MCP客户端。AI模型通过读取我们的数据库模式并运行检查服务器状态和IP地址的查询来智能地诊断生产环境中的支持查询,从而尝试达到VM的理想状态并与集群中的实际状态进行比较。
随着时间的推移,我希望使用Modex和其他MCP工具自动化我们重复的支持查询。
在src/modex/mcp/core.clj中有一个MCP服务器示例,定义了一个具有基本工具的MCP服务器。
您的MCP客户端(例如Claude Desktop)可以连接到此服务器,并使用公开的工具为您的AI模型提供额外的上下文。
内部,一个工具只是一个带有多个参数的Tool记录:
(defrecord Tool [name doc args handler])(defrecord Parameter [name doc type required default])然而,使用下面的tool和tools宏定义工具更为方便。
tool宏描述单个工具:tool宏类似于defrecord,其中处理器定义接受一个形如{:keys [arg1 arg2 ...]}的参数映射,但带有额外的(可选的)映射:type、:or和:doc。这些元数据用于向MCP客户端描述工具。
:string和:number类型的工具参数。:or映射中意味着可选性。(require '[modex.mcp.tools :as tools])
(def add-tool
(tools/tool
; 类似于defrecord。
(add [{:keys [x y]
:type {x :number
y :number}
:or {y 0} ; 由于出现在:or映射中,y是可选的。
:doc {x "第一个数字"
y "第二个数字"}}]
[(+ x y)]))) ; 工具应返回一个向量(以支持多个值)。
invoke-tool调用工具,包括验证:调用使用一个参数映射,就像MCP客户端对tools/call请求那样:
(tools/invoke-tool add-tool {:x 5 :y 6}) ; Modex将映射这些参数并调用处理器。
=> {:success true, :results [11]} ; 注意:results是一个向量,以支持多个值。
(tools/invoke-handler (:handler add-tool) {:x 5 :y 6})
=> [11] ; 注意结果向量以支持多个值。
tools宏定义工具集tools宏只是为每个工具定义调用tool宏,并返回一个以工具名称(关键字)为键的工具映射:
(def my-tools
"在这里定义您的工具。"
(tools/tools
(greet
"通过名字问候一个人。" ; 工具可以有文档字符串
[{:keys [first-name last-name]
:doc {first-name "一个人的名字。"
last-name "一个人的姓氏(可选)。"}
:type {first-name :string
last-name :string}
:or {last-name nil}}] ; last-name是可选的,由出现在`:or`映射中暗示。
; 工具应返回集合。
[(str "来自Modex的问候,"
(if last-name ; 参数可以是可选的
(str first-name " " last-name)
first-name) "!")])
(add
"添加两个数字。"
; 工具处理器参数也支持已弃用的向量参数样式,
; 但已被更新的映射解构样式取代:
[^{:type :number :doc "要相加的第一个数字。"} a
^{:type :number :doc "要相加的第二个数字。"} b]
[(+ a b)])
(subtract
"减去两个数字 (- a b)"
[^{:type :number :doc "第一个数字。"} a
^{:type :number :doc "第二个数字。"} b]
[(- a b)])
(error-handling
"这个工具故意抛出异常。Modex会为您处理异常。"
[]
(throw (ex-info "Modex将处理异常。" {})))))
(require '[modex.mcp.server :as server])
(def my-mcp-server
"这里我们创建一个AServer的实例。目前只支持工具。"
(server/->server
{:name "Modex MCP服务器"
:version "0.0.2"
:initialize (fn [_init-params] ; 初始化参数,但在未来可能包含客户端能力。
"在这里进行长时间运行的设置和阻塞I/O操作,比如连接到生产数据库。")
:tools my-tools
:prompts nil ; 提示正在进行中。
:resources nil})) ; 资源正在进行中。
(server/start-server! my-mcp-server)
或者将其放入您的-main函数中。
Modex公开了一个AServer协议和一个DSL,用于定义描述MCP服务器的工具协议,这些服务器公开工具、资源和提示。
AServer协议:
(defprotocol AServer
(protocol-version [this])
(server-name [this])
(version [this])
(capabilities [this])
(initialize [this _init-params]) ; 初始化参数目前为空,但在未来可能包含客户端能力。
(list-tools [this])
(call-tool [this tool-name arg-map])
(list-resources [this])
(list-prompts [this]))
在您可以运行之前,必须先构建它。构建输出一个Uberjar,类似于Java可执行文件。
clojure -T:build uber
或者运行帮助程序完成此操作:
./build.sh
(您可能需要运行chmod +x build.sh)
打开您的Claude Desktop配置文件claude_desktop_config.json,在MacOS上应该位于:
~/Library/Application\ Support/Claude/claude_desktop_config.json
在mcpServers下添加一个元素,使其看起来像这样:
{
"mcpServers": {
"modex": {
"command": "java",
"args": ["-jar", "/Users/your-username/code/modex/target/modex-mcp-0.2.2.jar"]
}
},
"globalShortcut": ""
}
这告诉Claude Desktop有一个名为modex的工具,可以通过运行java -jar /path/to/your/uber.jar来连接。
这种方式是,您的本地MCP客户端(即Claude Desktop),启动您的MCP服务器进程并通过stdin/stdout管道与其通信。
现在,您应该能够询问Claude“运行foo”,或“foo说些什么?”它将运行foo工具并回复“你好,AI!”。
Modex实现了Clojure中的MCP客户端和服务器,大部分符合2024-11-05 MCP规范。
消息使用JSON-RPC 2.0线格式编码。
有三种消息类型:
{:keys [id method ?params]}{:keys [id result ?error]}{:keys [method ?params}MCP支持两种传输类型:
存在一个现有的库mcp-clj,它使用SSE,因此需要mcp-proxy来代理从SSE <=> stdio。我对此感到不满,所以我制作了Modex。
目前还不能,但我很快会添加nREPL,这样您就可以在Claude Desktop连接到进程时评估更改,而无需重建uberjar。
顺便说一下,我试图让它运行clojure -M -m modex.mcp.server,但无法设置Claude Desktop的工作目录。
所以目前,我重建uberjar并重启Claude Desktop。将会修复。
总结如下:
此工具根据GNU通用公共许可证第3.0版(GPLv3)许可。您有权使用、修改和分发它,只要任何衍生作品也根据GPLv3许可并保持开源。这确保了该工具对社区免费可用,同时要求对任何更改保持透明。
如果您希望在专有项目中使用或修改此工具——而不将其更改发布到GPLv3下—— 您可以购买商业许可。这允许您将修改保留在个人或商业用途中。 要获取商业许可,请联系我modex@petrus.co.za。