Modex: Model Context Protocol Server & Client Library in Clojure について
Modex は、AI モデルにツール、リソース、プロンプトを追加する MCP サーバーとクライアントを構築するための Clojure ライブラリです。Anthropic の Java SDK に依存せず、ネイティブな Clojure で実装されています。Clojure 開発者を対象とし、現時点では stdio トランスポートに対応しています。
主な機能
- 01ネイティブ Clojure による MCP サーバーとクライアントの実装
- 02tool と tools マクロによるツールとパラメータの定義
- 03ツール呼び出し時の引数検証
- 04stdio 上での JSON-RPC 2.0 メッセージング
- 05nREPL による実行中プロセスへのライブ変更
活用シーン
- 01Datomic データベースの検索ツールを Claude Desktop に公開
- 02MCP クライアントから Clojure 関数をツールとして呼び出し
- 03Clojure でのローカル MCP サーバーのプロトタイプ作成
MCP 対応
Modex は、Claude Desktop などの MCP クライアントにツールを公開する MCP サーバーを構築します。クライアント実装も含みます。2024-11-05 版の MCP 仕様にほぼ準拠しているとされています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Modex:Clojure 製の Model Context Protocol サーバーおよびクライアントライブラリ
Modex(MOdel + ContEXt)は、AI に新しいツール、リソース、プロンプトを追加できる Clojure ライブラリです。
Modex は、Clojure でネイティブに MCP サーバーおよびクライアントを構築するため、Model Context Protocol の大部分を実装しています。
Clojure ネイティブのため、Anthropic の MCP Java SDK を扱う必要はありません。
Modex は、2024-11-05 MCP 仕様の stdio トランスポートを実装しているため、SSE と stdio の間を相互に変換するための
mcp-proxy のようなプロキシは不要です。
Modex の動作画面
Claude Desktop は、MCP クライアントを介して Modex MCP サーバーと通信できます。
目次
ツールの例
- Datomic MCP は Modex を使って Datomic のツールを公開し、モデルが開発環境または本番環境の DB スキーマやデータをクエリできるようにします。
クイックスタート
git clone [email protected]:theronic/modex.gitcd modex./build.shを実行すると、target/modex-mcp-0.2.2.jarに uberjar が作成されます。- Claude Desktop の設定ファイル
~/Library/Application\ Support/Claude/claude_desktop_config.jsonを開きます。 - uberjar を_フルパス_で実行する新しい MCP サーバーを設定します。
{
"mcpServers": {
"modex-mcp-hello-world": {
"command": "java",
"args": ["-jar", "/Users/your-username/code/modex/target/modex-mcp-0.2.2.jar"]
}
},
"globalShortcut": ""
}
- Claude Desktop を再起動して、新しい MCP サーバーとツールを有効にします :)(Cmd+R で更新しても設定は再読み込みされず、ツールが再起動するだけです)
- Claude に「inc ツールを 123 で実行して」と伝え、ツールを許可すると、出力として 124 が表示されます。
MCP とは?
MCP を使うと、AI モデルにツール、リソース、プロンプトを追加できます。
- ツールは、データベース(例:Datomic)へのクエリなど、AI が実行できるものです。
- リソースは、PDF の銀行明細書など、AI が読み取れるファイルやデータです。
- プロンプトは、テンプレート化されたメッセージやワークフローです。
ユースケース
Modex は datomic-mcp で使用されており、本番環境の Datomic データベースを Claude Desktop のような MCP クライアントに公開します。AI モデルは、データベーススキーマを読み取り、サーバーの状態や IP を確認するクエリを実行して、本番環境のサポートに関する問い合わせを適切に診断します。これにより、サーバーへの接続を試みたり、VM の期待される状態とクラスター内の実際の状態を比較したりできます。
今後、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 は、MCP サーバーを記述するツールプロトコルを定義するための DSL と AServer プロトコルを公開します。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 をビルドする
実行する前に、まずビルドする必要があります。ビルドすると、Java 実行可能ファイルのような uberjar が生成されます。
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 ツールが実行され、「Hello, AI!」という応答が返ってくるはずです。
実装
Modex は、2024-11-05 MCP Spec におおむね準拠した Clojure 製の MCP クライアントとサーバーを実装しています。
メッセージは JSON-RPC 2.0 のワイヤーフォーマットでエンコードされます。
メッセージの種類は 3 つあります。
- リクエストは
{:keys [id method ?params]}の形式です - レスポンスは
{:keys [id result ?error]}の形式です - 通知は
{:keys [method ?params}の形式です
MCP は 2 種類のトランスポートをサポートしています。
- stdio/stdout — Modex で実装済みです。
- Server-Sent Events(SSE)— まだ実装されていません。制限のあるネットワークで役立ちます
プロジェクトの状況
- テストに合格
- 使いやすさ(AServer / AClient プロトコル?)
- ツール
- 実行中のプロセスをその場で変更するための nREPL
- リソース
- プロンプト
- [進行中] SSE サポート
- [進行中] ストリーミング HTTP サポート(2025-03-26 MCP 仕様)
背景
SSE を使用する既存のライブラリ mcp-clj があります。そのため、SSE と stdio の間を中継するには mcp-proxy が必要です。これに不便を感じたため、Modex を作成しました。
よくある質問
MCP クライアント(Claude Desktop など)の接続中にサーバーを変更できますか?
まだできませんが、近いうちに nREPL を追加する予定です。これにより、uberjar を再ビルドせずに、Claude Desktop がプロセスに接続している間に変更を eval できます。
ちなみに、clojure -M -m modex.mcp.server で実行できるようにしようとしましたが、Claude Desktop の作業ディレクトリは設定できません。
そのため現在は、uberjar を再ビルドして Claude Desktop を再起動しています。いずれ修正します。
Modex の有料顧客の皆さま、ありがとうございます:
ライセンス
概要:
- 非営利目的での使用は無料:GPLv3 のもとで、無料で使用、変更、共有できます。ただし、オープンソースのままにしてください。
- 商用利用:変更を非公開にしたい場合は、20ドルを一度お支払いいただくと、永続的な商用ライセンスを取得できます。この費用は、これを公開しながら開発を続けるための AI トークン代に充てられます。
このツールは、GNU General Public License v3.0 (GPLv3) のもとでライセンスされています。派生物も GPLv3 のもとでライセンスされ、オープンソースとして公開されることを条件に、自由に使用、変更、配布できます。これにより、変更内容の透明性を求めながら、このツールをコミュニティで引き続き無料で利用できるようにしています。
このツールを、変更内容を GPLv3 のもとで公開せずにプロプライエタリなプロジェクトで使用または変更したい場合は、 商用ライセンスを購入できます。これにより、個人または商用目的で変更内容を非公開にできます。 商用ライセンスの取得については、[email protected] までお問い合わせください。
作者
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。