MCP とは?Model Context Protocol、JSON-RPC、AI Agent とツール呼び出し完全ガイド

2026年9月7日時点:MCP の意味、JSON-RPC 2.0 の読み方、Host / Client / Server の役割、LLM Tool Calling と tools/list・tools/call の対応。

先に結論:MCP(Model Context Protocol)は Function Calling の別名でも、モデルでもない。AI アプリ(Host)と外部ツールプロセス(MCP Server)のあいだのオープンプロトコルで、メッセージは JSON-RPC 2.0 である。モデルは依然、各社の Tool Calling / Function Calling を話す。Host が tools/list をモデルの tools 配列に訳し、モデルの tool_calls を tools/call に訳す。この三層が重なって、2026年に多い Agent のツール呼び出しになる。

本稿は2026年9月7日時点の内容です。現行仕様は 2026-07-28:プロトコル層にセッションはなく、initialize ハンドシェイクもなく、各リクエストが _meta を持ち、能力発見は server/discover です。8月の《Agent JSON データフロー》はまだ旧版の initialize 例を使っています。読むときはこのガイドを現行としてください。Server のコードを変える必要があるかは、《MCP 2026 移行ガイド》を見てください。

MCP とは何か

Model Context Protocol は、AI アプリケーションが外部コンテキストを発見し、読み、呼び出すためのオープン標準です。Anthropic が 2024年11月に公開し、のちにガバナンスは Agentic AI Foundation へ移りました。規定するのはコンテキストの交換方法です。どのモデルを使うか、多段 Agent をどうオーケストレーションするか、ビジネスロジックをどう書くかは規定しません。

USB-C だと思ってください:ソケットの形は統一。後ろにディスク、ディスプレイ、電源のどれを挿すかは対象外です。MCP が揃えるのは Host ↔ Server のソケットです。ファイルシステム、GitHub、社内の注文 API、本サイトのような JSON 検証——どれも Server です。

言い方実際の意味よくある誤読
MCPHost とツールプロセスのあいだの JSON-RPC プロトコルモデル、Agent フレームワーク、または OpenAI の Tools API
MCP Servertools / resources / prompts を公開するプログラム必ず公開インターネット上に置く、または REST API を置き換える
MCP ClientHost 内で 1 つの Server を担当する接続マネージャ言語モデルそのもの
MCP HostCursor、VS Code、Claude Desktop のような AI アプリMCP 仕様または SDK

層は二つです。データ層は JSON-RPC 2.0(メソッド、パラメータ、エラーコード、通知)。トランスポート層は、その JSON フレームの運び方——同一マシンなら stdio、リモートなら Streamable HTTP。トランスポートを替えても、メッセージの形は変わりません。だから MCP のデバッグは、まず「封筒は JSON-RPC、業務ペイロードもよく JSON」と切り分けるところから始まります。

Host、Client、Server

仕様の三角は、日常の「クライアント / サーバー」と混ぜやすいです:

  • Host:ユーザーが開いた AI アプリ。Client を作り、ツール Schema をモデルに渡し、実行前に認可と検証をし、結果を会話へ書き戻します。
  • Client:Host 内部の接続オブジェクト。1 つの Server に 1 つの Client。VS Code がファイルシステムと Sentry に同時接続しているなら、実行時は Client が二つです。
  • Server:コンテキストを出すプログラム。Host と同機(stdio)でも、別マシン(Streamable HTTP)でもよい。「Server」は役割であり、公開ホスト名が必須という意味ではありません。

モデルはこの三角に入りません。GPT-5.5、Claude 4.8、Gemini 3.7 が見るのは、Host が訳した tools 配列です。JSON-RPC は見えず、Mcp-Session-Id も見えません(2026-07-28 でセッションヘッダはなくなりました)。「モデルが MCP を話す」はマーケティングの言い方です。実装上は、あいだに必ず Host があります。

JSON-RPC 2.0 の読み方

JSON-RPC は、JSON でリモート手続き呼び出しをする約束です——REST より「関数を呼ぶ」に近い。MCP がこれを選んだのは、メソッド名が安定し(tools/list、tools/call)、リクエスト / レスポンス / 通知の切り分けがはっきりし、封筒全体がモデル向きの JSON だからです。

フィールド誰が使う意味
jsonrpcすべてのメッセージ常に "2.0"
idリクエストとレスポンス突き合わせ用。通知には id がない
methodリクエスト / 通知例:tools/call、server/discover
paramsリクエストパラメータオブジェクト。2026-07-28 以降はよく _meta を含む
result / errorレスポンスどちらか一方。成功は result、失敗は error

仕様 2026-07-28 の tools/call はこう見えます。注意:ハンドシェイクなし、セッションヘッダなし。バージョンとクライアント識別は _meta にあり、どの Server インスタンスでもこのフレームを処理できます。

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "validate_json",
    "arguments": {
      "payload": {"orderId": "A-1001", "total": 42.5},
      "schemaId": "order.v1"
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {
        "name": "json-toolbox-host",
        "version": "1.0.0"
      }
    }
  }
}

成功レスポンスも同じ封筒です。業務結果は result.content にあり、よく type: "text" です。そのテキスト自体が JSON 文字列であることもあります——外側がプロトコル、内側がペイロード。デバッグでは、まず id をリクエストと合わせ、それから内側を Schema 検証してください。

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "{\"valid\":true,\"schemaId\":\"order.v1\"}"
      }
    ]
  }
}

失敗は JSON-RPC の error オブジェクトです:code、message、任意の data。2026-07-28 は「リソースが存在しない」を MCP 独自の -32002 から標準の -32602(Invalid Params)へ変えました。旧エラーコードを直書きしているクライアントは見逃します。通知(notification)には id がなく、応答も待ちません——ツール一覧の変化などです。

Tools、Resources、Prompts

Server は三種類のプリミティブを公開できます。Agent が日常いちばん使うのは Tools。残り二つは忘れられやすいですが、モデルの推測を一回減らせることが多いです。

プリミティブ発見使用用途
Toolstools/listtools/call実行可能な動作:DB 照会、API 呼び出し、ファイル書き込み、JSON 検証
Resourcesresources/listresources/readURI でコンテキストを読む:Schema ファイル、ログのスライス、設定
Promptsprompts/listprompts/get再利用できるプロンプトテンプレート。任意パラメータ付き

ツールの核は name、description、inputSchema です。inputSchema は JSON Schema です(2026-07-28 から 2020-12。ルートは依然 type: "object"。oneOf / $ref / $defs は使える)。任意の outputSchema が戻り値の形を縛ります。Host はほぼ 1:1 で inputSchema をモデル API の parameters / input_schema に載せます。

{
  "name": "validate_json",
  "title": "Validate JSON",
  "description": "Check a JSON payload against a named schema. Returns valid and errors.",
  "inputSchema": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "payload": { "type": "object", "description": "Already parsed JSON object, not a raw string" },
      "schemaId": { "type": "string", "description": "Stable schema id such as order.v1" }
    },
    "required": ["payload", "schemaId"]
  }
}

Resources は「先に読んでから考える」向きです。schema://order.v1 をコンテキストへ読むほうが、会話で 200 行の Schema をモデルに覚えさせるより安い。Prompts はチームの定型オープナー向きです。Roots、Sampling、Logging は 2026-07-28 で非推奨です:ワークスペースパスはツール引数かリソース URI で渡し、Server は Host に補完を求めず、ログは stderr か OpenTelemetry へ出してください。

Tool Calling との重ね方

三つの名前がよく一つのものとして書かれます。データフロー上は同じ層ではありません——《Agent JSON データフロー》が各ホップを分解しています。ここではマッピングだけ覚えます:

層両端典型的なメッセージ
Function Calling / Tool Callingモデル API ↔ Hosttools[] + tool_calls.arguments
MCPHost ↔ ServerJSON-RPC tools/list、tools/call
JSON Schema契約であり、トランスポートではないinputSchema / parameters

Function Calling は初期の OpenAI の名前。Tool Calling は後の汎用名です(Claude tools、Gemini Function Calling、OpenAI Tools API)。開発者から見れば一つの流れです:Host が Schema を送り、モデルが JSON 引数付きの呼び出しを返し、Host が実行して JSON 結果を会話へ戻します。

MCP はこの層を置き換えません。MCP なしで、Host がプロセス内のローカル関数を Tool Calling だけで呼ぶのも正当です。MCP があると、ツールは発見でき、プロセスをまたげ、Host を替えて再利用できる Server になります。企業 Agent はほぼ常に二層を重ねます。スクリプトとデモは Tool Calling だけで足りることが多いです。

マッピングで踏みやすい穴は二つです。モデル API の arguments はよく文字列で、MCP の params.arguments はオブジェクトです。そして tools/list の name は、モデルと tools/call へそのまま渡してください——途中で「わかりやすい」別名に変えないでください。検証は本物の tools/call の前に行います。《Tool Calling と JSON Schema 検証》を見てください。

一回の完全なツール呼び出し

ユーザーが「order.v1 でこの注文 JSON を検証して」と言います。2026-07-28 では、端から端までこうなります:

  1. Host → Server:server/discover(キャッシュできる)で相手に tools があることを確認。または次のリクエストを送り、バージョン違いなら再試行。
  2. Host → Server:tools/list が inputSchema 付きの一覧を返す。結果に ttlMs / cacheScope が付くことがある。
  3. Host → モデル:一覧を tools[].parameters に写す(依然 JSON Schema)。
  4. モデル → Host:tool_calls。name は validate_json。arguments はよく文字列化した JSON。
  5. Host が検証:JSON.parse のあと inputSchema で確認。失敗したらエラーを tool 結果として書き、本物の Server には触れない。
  6. Host → Server:tools/call。arguments はオブジェクト。_meta にプロトコルバージョン。
  7. Server → Host:result.content。必要なら Host が outputSchema でもう一度見る。
  8. Host → モデル:role: tool の JSON 文字列。モデルがユーザー向けの文を書くか、次のツールターンへ進む。
User natural language
    │
    ▼
Host ──JSON Schema──► LLM Tool Calling
    │                      │
    │                      ▼
    │                 arguments JSON
    ▼                      │
MCP JSON-RPC ◄──── tools/call only after validation
    │
    ▼
result JSON ──► tool message ──► model’s final answer

リモートトランスポートでは、HTTP ヘッダに MCP-Protocol-Version、Mcp-Method、Mcp-Name が要り、body と一致しなければ Server は拒否すべきです。ロードバランサは JSON を分解せず、ヘッダだけ見て回せます。本機の stdio にはこれらのヘッダはありません。JSON-RPC のメソッド名は同じです。

2026-07-28 で覚えること

7月仕様は MCP 公開以来いちばん大きな改訂で、2026年7月28日が正式公開日です。「MCP とは何か」では下のリストだけ覚えてください。Server のコードを変える必要があるかは、依然として移行記事の決定木です。

  • ハンドシェイクなし、プロトコルセッションなし:initialize / initialized と Mcp-Session-Id はなくなりました。各リクエストは自己完結です。アプリ状態は basket_id(または同様のもの)を普通の引数として明示し、自分で繋いでください。トランスポートが覚えてくれると思わないでください。
  • 発見は server/discover:任意ですが、一回で対応バージョン、capabilities、serverInfo が取れます。一覧結果に ttlMs が付き、長い SSE だけがツール変更を知る手段ではなくなりました。
  • Schema は JSON Schema 2020-12:入力ルートは object のまま。合成と参照は使える。外部 $ref は自動解決しないでください。出力 Schema は object 限定ではなくなりました。
  • Roots / Sampling / Logging は非推奨:1年の猶予内はメソッドはまだ動きます。新しい Server は、Host に補完を求める Sampling を実装しないでください。
  • Extensions:Tasks と MCP Apps は公式拡張であり、コアの必須ではありません。長い仕事は task handle + tasks/get を使い、自分でセッションを発明しないでください。

まだ 2025-11-25 の Host / Server は initialize を使い続けます。混在接続では、双方が交渉した protocolVersion を見てください。この記事のセッションなしフレームを旧 Server に送らないでください。どの Server を入れるかは《2026 MCP Server ランキング》を見てください。

いまどう使うか

  1. コードを書く前に三層を描く:モデル API の Tool Calling、Host のオーケストレーション、MCP Server。スクリプトなら前の二層で止めてよい。IDE をまたいでツールを再利用するときが、Server を書くときです。
  2. 公式 SDK を使い、JSON-RPC フレームを手書きしない:@modelcontextprotocol/sdk と各言語の公式パッケージが、発見、トランスポート、エラーコードをすでに扱います。手書き SSE や非公開フィールドは、移行ガイドで「コードを変える必要がある」典型例です。
  3. inputSchema を、単独で検証できる契約として書く:additionalProperties: false、required、enum、長さ上限。モデルはフィールドを落とし、数字を文字列にします。実行前に同じ Schema で一度止めてください。
  4. 本機は stdio、リモートは Streamable HTTP:個人のデバッグに HTTP は不要です。チーム共有、多数クライアント、ゲートウェイを通すときにリモートへ出し、OAuth と最小権限を足してください。
  5. 一覧はキャッシュし、結果は切り詰める:ttlMs を守ってください。スタック原文をモデルへ流し戻さないでください。窓が大きくても、汚れた JSON は次のターンを汚します——《1M Token コンテキストウィンドウ》を見てください。
  6. 本番 Server を叩く前に、ブラウザでフィクスチャを合わせる:inputSchema、良い例 / 悪い例の arguments、Server 戻りサンプルを JSON として保存し、本サイトで検証と Diff をしてください。データはアップロードしません。REST 契約を試すのと同じ習慣です。

よくある質問

MCP はモデルか、フレームワークか?

どちらでもありません。MCP は Host と外部ツールプロセスのあいだのオープンプロトコルで、メッセージは JSON-RPC 2.0 です。モデルは依然各社 API が提供し、オーケストレーションは Host / Agent ランタイムの仕事です。「MCP モデル」というものはありません。

すでに Tool Calling があるなら、MCP は要りますか?

ツールがプロセス内にあり、Host に直書きされているなら、Tool Calling だけで足ります。アプリをまたいだ再利用、プロセス隔離、動的な発見が要るときに MCP を足してください。2026年の IDE Agent はたいてい二層とも動かします。一回きりの CLI スクリプトには MCP がないことが多いです。

MCP は JSON-RPC か、REST か?

データ層は JSON-RPC 2.0 であり、「ツールごとに HTTP パスが一つ」ではありません。リモートトランスポートは Streamable HTTP でもよいですが、body は依然 JSON-RPC オブジェクトで、メソッドは method と Mcp-Method ヘッダの両方にあります。REST リソースのように MCP を分割しないでください。

2026-07-28 のあとでも initialize を書きますか?

新仕様に initialize / initialized はなく、Mcp-Session-Id もありません。バージョンとクライアント識別は、各リクエストの _meta に入れます。2025-11-25 の旧 Server だけと話すなら、旧ハンドシェイクを続けてください。交渉された protocolVersion に従い、二つの封筒を混ぜないでください。

MCP は OpenAPI を置き換えますか?

置き換えません。OpenAPI は HTTP API を記述し、MCP は Agent ランタイムがツールを発見し呼ぶ方法を記述します。よくあるやり方は、REST は OpenAPI のまま、外側に薄い MCP Server をラップし、パスを tools/call へ写すことです。

MCP が使う JSON をローカルでどう確認しますか?

inputSchema、モデル arguments のサンプル、tools/call の戻りサンプルをファイルに保存してください。ブラウザの JSON ツールボックスで構文と構造を検証し、二つの Schema 版を Diff してください。データはブラウザから出ません。

まとめ

MCP は 2026年 Agent のツールソケットです:JSON-RPC 2.0 が Host と Server のあいだで発見と呼び出しを運び、モデル側は依然 Tool Calling、JSON Schema が両方の契約です。モデルでも、フレームワークでも、OpenAPI の代替でもありません。仕様 2026-07-28 はセッションをプロトコルから外したので、リクエストは自己完結でなければなりません。Tools / Resources / Prompts の三つのプリミティブは変わっていません。

このガイドは層分けだけです。各ホップのバイト形はデータフロー記事、旧 Server のコード変更要否は移行記事、入れる Server はランキング記事です。本番に繋ぐ前に、Schema とサンプル JSON をローカルで検証してください——モデルは替えられます。フィールド名と required は動かしてはいけません。