AI 開発

Claude Code、Codex など AI Coding Agent は MCP Tools をどう呼ぶか:JSON-RPC、Tool Schema、実行権限(2026)

約 16 分

協議の稿は 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 を繋いで」から始めない。対象を書く:

  1. まずサーバ設定を書く。stdio か http を選ぶ。url に type。秘密は環境変数。倉庫へ入れない。
  2. 自分で tools/list を走らせる。名前と required を記す。Schema の無いツールはモデルへ渡さない。
  3. inputSchema を締める。pattern、enum、additionalProperties: false。照会に返金の鍵を増やさない。
  4. ツールごとに権限を書く。読み取りの照会は allow。書き込みは ask。返金は deny。Codex は先に enabled_tools で表を刈る。
  5. 成功した一回を三つの 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 は通っている。モデルは変わる。三つを先に安定させる。

続きを読む

更新記録: 初回公開