Claude Code、Codex など AI Coding Agent は MCP Tools をどう呼ぶか:JSON-RPC、Tool Schema、実行権限(2026)
協議の稿は Schema と Function Calling の分担を書いた。本稿は Coding Agent にだけ落とす:モデルが引数を埋め、宿主が JSON-RPC を送る。接続、列挙、Schema、権限は四手順であり、「MCP を繋いで」という一文ではない。
読む前に
| 手順 | 何を鎖すか | 誰が実行するか |
|---|---|---|
| 設定 | .mcp.json / config.toml | stdio か http。url には type が要る |
| 発見 | tools/list + inputSchema | 宿主が列ぶ。モデルは伝送を見ない |
| 呼び出し | tools/call の arguments | モデルが JSON を埋め、宿主が RPC を送る |
| 権限 | mcp__server__tool / enabled_tools | 接続 ≠ 自動実行 |
MCP は宿主とサーバの協議。モデルが見るのはツール名と引数 Schema。
MCP を呼ぶのは宿主であり、モデルではない
Claude Code、Codex、Cursor は MCP クライアントだ。セッション開始後、宿主はサーバへ繋がり、JSON-RPC 2.0 の tools/list を送り、各ツールの inputSchema をモデルへ渡す。モデルが出すのは引数 JSON だけだ。tools/call を送り副作用を走らせるのは宿主だ。その跳躍がなければ、MCP は設定ファイルに過ぎない。
- 設定:サーバの起動。stdio は手元の過程。http は遠隔。どちらも対象であり、口約束ではない。
- Schema:
order_idはinputSchemaを通る。広い object は鍵の発明を招く。 - 権限:Claude は
mcp__サーバ__ツールで規則を書く。Codex はenabled_toolsと承認。Cursor はmcpAllowlist。サーバを繋いでも門は開かない。
協議層の Schema と Function Calling は MCP Tool Schema vs Function Calling。Coding Agent 自身のツール JSON は AI Coding Agent と JSON ツール呼び出し。Schema が門である理由は AI に JSON Schema が必要な理由。本稿は三語を定義し直さない。宿主が MCP を走らせる話だけ書く。
第一の対象:サーバ設定
Claude Code のプロジェクト設定は倉庫根の .mcp.json。版管理に入れてよい。手元の私有は ~/.claude.json。url には type が要る。http(streamable-http は別名)か sse / ws。url だけで type が無いと、公式は壊れた stdio として飛ばす。架空の注文サービス。本物の秘密は貼らない:
{
"mcpServers": {
"orders": {
"type": "stdio",
"command": "node",
"args": ["./servers/orders-mcp.js"]
}
}
}
Codex は同じ事実を ~/.codex/config.toml、または信頼したプロジェクトの .codex/config.toml に書く。表は [mcp_servers.orders]。stdio は command / args。遠隔は url。Cursor は .cursor/mcp.json か利用者ファイル。編集器と CLI が共有する。プロジェクトに新たに現れたサーバは、Claude Code では承認待ちで止まる。自動では繋がらない。
第二の対象:tools/list と inputSchema
繋がったあと、宿主はまずツールを問う。これは JSON-RPC であり、モデルが自分で送る HTTP ではない:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
サーバは表を返す。各行は名前、説明、JSON Schema。仕様は tools 能力の宣言を求める。一覧は認可で変わり得る。接続ごとに揺れてはならない。Coding Agent はその表をモデルが見るツールへ変える。Claude Code の呼び出し名は mcp__orders__lookup_order。プラグイン由来のサーバはプラグイン名も嵌める。ツールが多いとき、公式は遅延読み込みと検索で展開する。表全体を既定で文脈へ入れない。
{
"name": "lookup_order",
"description": "Look up an order by ID. Confirm before any refund.",
"inputSchema": {
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
},
"required": ["order_id"],
"additionalProperties": false
}
}
第三の対象:モデルが埋め、宿主が tools/call
モデルが見るのは宿主が出した名前だ。Claude Code のセッションでは、呼び出しはこうなる:
{
"type": "tool_use",
"id": "call_3c91",
"name": "mcp__orders__lookup_order",
"input": { "order_id": "A-1042" }
}
宿主は input を inputSchema に通し、サーバへ送る RPC へ訳す。線上の名前は登録名 lookup_order。mcp__ 接頭辞は付けない:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "lookup_order",
"arguments": { "order_id": "A-1042" }
}
}
成功なら content を返す。失敗なら isError を真にし、理由を対象として書く。散文の一文だけを捨てない。モデルが読むのは書き戻しであり、ソケットではない。
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{ "type": "text", "text": "{\"order_id\":\"A-1042\",\"status\":\"paid\"}" }
],
"isError": false
}
}
第四の対象:実行権限
MCP 仕様は、ツール呼び出しを拒めるべきだと書く。Coding Agent はその拒否を規則として書く。指示文にはしない。Claude Code は完全な呼び出し名を使う:
{
"permissions": {
"allow": ["mcp__orders__lookup_order"],
"ask": ["mcp__orders__create_note"],
"deny": ["mcp__orders__refund_order"]
}
}
公式の順はなお deny、ask、allow。裸の mcp__* の deny は MCP を文脈から外す。Codex は enabled_tools を白名簿、disabled_tools を後段の黒名簿にし、既定の承認は auto / prompt / approve。ツールごとに上書きできる。Cursor は既定で毎回尋ねる。permissions.json の mcpAllowlist は orders:lookup_order と書く。Shell / Git / ファイルの三門は Coding Agent の権限モデル。MCP は第四の表であり、三門の代わりではない。
MCP を対象にする五手順
「MCP を繋いで」から始めない。対象を書く:
- まずサーバ設定を書く。stdio か http を選ぶ。url に type。秘密は環境変数。倉庫へ入れない。
- 自分で tools/list を走らせる。名前と required を記す。Schema の無いツールはモデルへ渡さない。
- inputSchema を締める。pattern、enum、
additionalProperties: false。照会に返金の鍵を増やさない。 - ツールごとに権限を書く。読み取りの照会は allow。書き込みは ask。返金は deny。Codex は先に enabled_tools で表を刈る。
- 成功した一回を三つの JSON として残す:tool_use、tools/call、result。揃えば通っている。
Schema を門にする話は Agents API + JSON Schema。本稿が求めるのは、Coding Agent 上の MCP の各手順が対象であり、宿主が送ることだ。
MCP の逸脱を見直すなら、三つの JSON を広げる
失敗の多くは、名前、Schema、権限が揃っていないことだ。モデルが呼べないことではない。
inputSchemaとargumentsを 整形 し、欠けと余分な鍵を見る。- JSONPath 抽出 で
$.params.nameと$.input.order_idを抜く。 - 通った呼び出しと拒まれた呼び出しを JSON Diff。規則と Schema を先に直し、指示は後。
- 宿主名
mcp__orders__lookup_orderと RPC 名lookup_orderを照らす。プラグインサーバはプラグイン段も要る。 - 設定、トークン、セッション記録を公開フォーマッタに貼らない。JSONSort はブラウザ内で動く。
三つの軌跡が Schema で再建できて初めて、MCP を集めている。「接続を押した」を集めているのではない。
よくある落とし穴
- 繋がれば呼べると思う。接続は過程か HTTP が通っただけだ。list、Schema、権限が無ければ、モデルはまだ呼べない。
- MCP を Function Calling だと思う。モデルにとってはどちらも JSON を埋めることだ。宿主にとっては MCP は JSON-RPC の一跳びが増える。協議の稿は語を分けた。ここではその跳びを見ることだけ求める。
- url に type を書かない。Claude Code は壊れた stdio として飛ばす。遠隔サーバは消える。
- サーバだけ配り、ツールを刈らない。大きな表が文脈へ入る。公式の遅延と enabled_tools はそのためだ。
- 「すべての MCP を自動承認」を既定にする。Cursor の一括承認、Claude の bypass、Codex の全面 auto は隔離環境向けだ。日常はツールごとに書く。
- プロジェクトの .mcp.json を手元の私物だと思う。版管理に入る。他の人は承認待ちを見る。秘密は利用者スコープへ。
FAQ
Coding Agent は自分で JSON-RPC を送るか?
送らない。モデルが埋めるのはツール名と arguments。id、method、params は宿主が組む。ログの tools/call はクライアントであり、モデルではない。
inputSchema と権限、どちらが先か?
形が先、実行が後。Schema が通らねば RPC を送らない。通っても ask や deny は起き得る。鎖すものが違う。
stdio と http の選び方は?
手元のファイルや過程なら stdio。托管サービスなら http。Claude Code は遠隔に http を勧める。SSE は旧い。WebSocket はサーバが事象を押すときに向く。
ツールが多すぎるときは?
Claude Code は MCP ツールを遅らせ、検索で展開できる。Codex は enabled_tools で表を刈る。五十個を一度に入れない。
Subagent はこれらの MCP を使えるか?
製品による。Claude Code の権限と allowed-tools は完全な呼び出し名が要る。Agents API の下位エージェントは MCP を継ぎ、function は継がない。一枚の表がすべての子セッションへ写ると仮定しない。
結論
Coding Agent の MCP 呼び出しは、モデルがサーバを叩くことではない。宿主がツールを列び、モデルが JSON を埋め、宿主が tools/call する。Schema と権限は二つの門だ。
A-1042 がどのツール名、どの Schema、どの権限規則を通るかを先に書く。三つの対象を指せれば、MCP は通っている。モデルは変わる。三つを先に安定させる。
続きを読む
- MCP Tool Schema vs Function Calling 協議の対比。Coding Agent の呼び方ではない
- Coding Agent に権限制御が必要な理由 Shell / Git / ファイルシステムの三門
- AI Coding Agent は JSON でどうツールを呼ぶか 組み込みツールの JSON。まだ MCP ではない
- Agents API + JSON Schema 実践 安定、検証、実行
- AI に JSON Schema が必要な理由 Schema / Function Calling / Structured Output
- JSONSort のローカル道具箱 整形、検証、Diff
- すべての記事 JSON と AI 開発のメモ
更新記録: 初回公開