mcpField
M
Modex: Model Context Protocol Server & Client Library in Clojure

Modex: Model Context Protocol Server & Client Library in Clojure

本地服务
petrustheron.com开发工具12182 周前更新

关于 Modex: Model Context Protocol Server & Client Library in Clojure

Modex 是一个 Clojure 库,用于构建 MCP 服务与客户端,可为 AI 模型添加工具、资源和提示词。它直接使用 Clojure 实现,不依赖 Anthropic 的 Java SDK。项目面向 Clojure 开发者,目前以 stdio 传输为主。

主要功能

  1. 01使用原生 Clojure 实现 MCP 服务与客户端
  2. 02通过 tool 与 tools 宏定义工具及参数
  3. 03内置参数校验的工具调用(invoke-tool)
  4. 04基于 stdio 的 JSON-RPC 2.0 传输
  5. 05支持 nREPL 实时修改运行中的进程

适用场景

  1. 01将 Datomic 数据库的查询能力暴露给 Claude Desktop
  2. 02在 Claude Desktop 中以工具形式调用 Clojure 函数
  3. 03用 Clojure 快速搭建本地 MCP 服务原型

MCP 相关

Modex 可构建 MCP 服务,将工具暴露给 MCP 客户端,例如 Claude Desktop。它也包含客户端实现。项目基于 2024-11-05 版本的 MCP 规范,大部分兼容。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Modex:Clojure 中的模型上下文协议服务端与客户端库

Modex(MOdel + ContEXt)是一个 Clojure 库,可让你为 AI 添加新的工具、资源和提示词。

Modex 实现了 模型上下文协议 的(大部分)内容,可使用“原生” Clojure 构建 MCP 服务端和客户端。

由于它是原生 Clojure,你无需处理 Anthropic 的 MCP Java SDK。

Modex 实现了 2024-11-05 版 MCP 规范中的 stdio 传输,因此无需使用 mcp-proxy 之类的代理来在 SSE <=> stdio 之间进行转换。

Modex 实际运行截图

Claude Desktop 可以通过其 MCP 客户端与 Modex MCP 服务通信:

图片

目录

  1. 快速入门
  2. 什么是 MCP?
  3. Modex 能做什么?
  4. 详细分步说明
  5. 实现
  6. 项目状态
  7. 设计理由
  8. 常见问题
  9. 许可证

示例工具

  • Datomic MCP 使用 Modex 暴露 Datomic 工具,让模型能够在开发或生产环境中查询数据库架构和数据。

快速入门

  1. git clone [email protected]:theronic/modex.git
  2. cd modex
  3. ./build.sh 会在 target/modex-mcp-0.2.2.jar 构建一个 uberjar。
  4. 打开 Claude Desktop 配置文件:~/Library/Application\ Support/Claude/claude_desktop_config.json
  5. 配置一个新的 MCP 服务,使其运行 uberjar 的_完整路径_:
{
  "mcpServers": {
    "modex-mcp-hello-world": {
      "command": "java",
      "args": ["-jar", "/Users/your-username/code/modex/target/modex-mcp-0.2.2.jar"]
    }
  },
  "globalShortcut": ""
}
  1. 重启 Claude Desktop 以启用新的 MCP 服务和工具 :)(Cmd+R 刷新不会重新加载配置,只会重启工具)
  2. 告诉 Claude“运行 inc 工具并传入 123”,授权该工具,你应该会看到输出 124。

什么是 MCP?

MCP 可让你为 AI 模型添加工具、资源和提示词:

  • 工具是它可以执行的操作,例如查询数据库(如 Datomic)。
  • 资源是它可以读取的文件和数据,例如 PDF 银行对账单。
  • 提示词是模板化的消息和工作流。

使用场景

datomic-mcp 使用 Modex 将我们的生产 Datomic 数据库暴露给 Claude Desktop 等 MCP 客户端。AI 模型会通过读取数据库架构并运行查询来检查服务器状态和 IP,从而智能地诊断生产环境中的支持请求;它可以尝试连接服务器,并比较集群中虚拟机的期望状态与实际状态。

我希望今后能使用 Modex 和其他 MCP 工具,将大部分重复出现的支持请求自动化。

Modex 能做什么?

完整示例

src/modex/mcp/core.clj 中有一个 MCP 服务示例,其中定义了一些基本工具。

你的 MCP 客户端(例如 Claude Desktop)可以连接到此服务,并使用其中暴露的工具为 AI 模型提供额外上下文。

数据结构

工具

在内部,工具就是一个带有若干 Parameter 参数的 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 客户端描述工具。

  • MCP 规范目前仅支持 :string 和 :number 工具参数类型。
  • 在 :or 映射中出现的参数即为可选参数。
  • 缺失的参数文档字符串默认使用参数名称字符串。
(require '[modex.mcp.tools :as tools])

(def add-tool
  (tools/tool
    ; feels like defrecord.
    (add [{:keys [x y]
           :type {x :number
                  y :number}
           :or   {y 0} ; y is optional due to its presence in the :or map.
           :doc  {x "First number"
                  y "Second number"}}]
         [(+ x y)]))) ; tools should return a vector (to support multiple values).
使用 invoke-tool 调用工具(含验证):

调用时使用参数映射,就像 MCP 客户端发起 tools/call 请求一样:

(tools/invoke-tool add-tool {:x 5 :y 6}) ; Modex will map these arguments and call the handler.
=> {:success true, :results [11]} ; note :results is vector to support multiple values.
直接调用工具处理程序以跳过验证和错误处理:
(tools/invoke-handler (:handler add-tool) {:x 5 :y 6})
=> [11] ; note vector result to support multiple values.
使用 tools 宏定义工具集

tools 宏会为每个工具定义调用 tool 宏,并返回一个以工具名称(关键字)为键的工具映射:

(def my-tools
  "Define your tools here."
  (tools/tools
    (greet
      "Greets a person by name." ; tools can have a docstring
      [{:keys [first-name last-name]
        :doc {first-name "A person's first name."
              last-name  "A person's last name (optional)."}
        :type {first-name :string
               last-name  :string}
        :or {last-name nil}}] ; last-name is optional, implied by presence in `:or` map.
      ; tools should return collection.
      [(str "Hello from Modex, "
            (if last-name ; args can be optional
              (str first-name " " last-name)
              first-name) "!")])
    
    (add
      "Adds two numbers."
      ; Tool handler args also support deprecated vector arg-style,
      ; but this is superseded by the newer map-destructuring style:
      [^{:type :number :doc "First number to add."} a
       ^{:type :number :doc "Second number to add."} b]
      [(+ a b)])

    (subtract
      "Subtracts two numbers (- a b)"
      [^{:type :number :doc "First number."} a
       ^{:type :number :doc "Second number."} b]
      [(- a b)])

    (error-handling
      "This tool throws intentionally. Modex will handle errors for you."
      []
      (throw (ex-info "Modex will handle exceptions." {})))))
创建 Modex MCP 服务和工具:
(require '[modex.mcp.server :as server])
(def my-mcp-server
  "Here we create a reified instance of AServer. Only tools are presently supported."
  (server/->server
    {:name       "Modex MCP Server"
     :version    "0.0.2"
     :initialize (fn [_init-params] ; init-params, but may contain client capabilities in future.
                   "Do long-running setup & blocking I/O here, like connecting to prod database.")
     :tools      my-tools
     :prompts    nil    ; Prompts are WIP.
     :resources  nil})) ; Resources are WIP.
启动 MCP 服务
(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]) ; init-params is empty for now, but may contain client capabilities in future.

  (list-tools [this])
  (call-tool [this tool-name arg-map])

  (list-resources [this])
  (list-prompts [this]))

详细分步说明

第 1 步:构建 Uberjar

运行之前,必须先构建。构建会生成一个 uberjar,类似于 Java 可执行文件。

clojure -T:build uber

或者运行执行此操作的辅助脚本:

./build.sh

(你可能需要运行 chmod +x build.sh)

第 2 步:打开 Claude Desktop 配置文件

打开 Claude Desktop 配置文件 claude_desktop_config.json。在 MacOS 上,该文件应位于:

~/Library/Application\ Support/Claude/claude_desktop_config.json
第 3 步:配置 MCP 服务

在 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 管道与其通信。

第 4 步:重启 Claude Desktop

现在,你应该可以询问 Claude“运行 foo”或“foo 会说什么?”,它会运行 foo 工具并回复“你好,AI!”。

实现

Modex 使用 Clojure 实现了 MCP 客户端和服务,并且 基本 符合 2024-11-05 MCP 规范。

消息采用 JSON-RPC 2.0 线格式编码。

消息有 3 种类型:

  • 请求包含 {:keys [id method ?params]}
  • 响应包含 {:keys [id result ?error]}
  • 通知包含 {:keys [method ?params}

MCP 支持两种传输类型:

  • stdio/stdout —— 已在 Modex 中实现。
  • Server-Sent Events (SSE) —— 尚未实现。适用于受限网络

项目状态

  • 测试通过
  • 易用性(AServer / AClient 协议?)
  • 工具
  • 用于实时修改运行中进程的 nREPL
  • 资源
  • 提示词
  • [in progress] SSE 支持
  • [in progress] 流式 HTTP 支持(2025-03-26 MCP 规范)

设计原因

现有一个使用 SSE 的库 mcp-clj,因此需要通过 mcp-proxy 将 SSE 转发到 stdio,或将 stdio 转发到 SSE。我对此很不满,于是创建了 Modex。

常见问题

MCP 客户端(例如 Claude Desktop)连接时,我可以修改服务吗?

目前还不行,不过我很快会添加 nREPL,这样 Claude Desktop 连接到进程时,你就可以对更改进行求值,而不必重新构建 uberjar。

顺便说一下,我试过让它运行 clojure -M -m modex.mcp.server,但你无法设置 Claude Desktop 的工作目录。

因此,目前我会重新构建 uberjar 并重启 Claude Desktop。之后会修复。

感谢付费使用 Modex 的客户:

  • Nextdoc —— Salesforce 文档流式处理
  • Huppi —— 小型企业会计软件

许可证

简而言之:

  • 非商业用途免费:可免费使用、修改和分享,但需遵循 GPLv3,并保持开源。
  • 商业用途:想将修改内容保密?一次性支付 $20,即可获得永久商业许可证。这笔费用用于支付我的 AI 令牌成本,让我能继续公开开发。

本工具采用 GNU 通用公共许可证 v3.0(GPLv3) 授权。您可以自由使用、修改和分发本工具,但任何衍生作品也必须采用 GPLv3 授权并开源。这样可确保社区能够持续免费使用本工具,同时要求对任何修改保持透明。

如果您希望在专有项目中使用或修改本工具,且不以 GPLv3 发布修改内容,则可以购买商业许可证。购买后,您可以将修改内容保密,用于个人或商业用途。 如需获取商业许可证,请通过 [email protected] 联系我。

作者

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。