MCP Inspectorの新旧バージョン互換性の仕組み
MCP Inspectorがサーバーをlegacy/modernの2世代に分けて扱う仕組みと、ログ・タスク・セッションなど機能ごとに挙動がどう変わるかを解説します。
MCP Inspectorのプロトコル世代設定とは何か
MCP Inspectorは、接続先サーバーが2026-07-28の仕様改訂より前(legacy)か、それ以降(modern)かをprotocolEraという設定値で管理しています。トランスポート(stdioかHTTPか)とは独立した設定で、同じHTTP URLをlegacyとしてもmodernとしても検査できるのが特徴です。Web版・CLI・TUIのどのクライアントでも設定方法は共通で、Web版なら「Server Settings」、設定ファイルならprotocolEraフィールドで指定します。
この設定が必要になった理由は単純です。2026-07-28の改訂でinitialize/notifications/initializedのハンドシェイクが廃止され、すべてのリクエストが_metaにプロトコルバージョンとクライアント機能を積むステートレス方式に変わりました。旧仕様のサーバーと新仕様のサーバーが混在する間、デバッグツールのInspectorは両方の話し方をサーバーごとに切り替えられる必要があります。
legacy・auto・modernの3つの接続モード
| モード | 接続時の挙動 |
|---|---|
legacy(既定) | 接続時の挙動素のinitializeのみ。プロービングは一切行わない |
auto | 接続時の挙動先にserver/discoverを試し、modern以外の応答ならフォールバックでinitialize |
modern | 接続時の挙動2026-07-28のみに固定。フォールバックなしで非modernサーバーは失敗する |
既定値がautoではなくlegacyである点は、公式が明確に理由を説明しています。デバッグツールが接続のたびに自動でプロービングを行うと、静かに待ち続けるlegacyのstdioサーバーに対してserver/discoverプローブが止まってしまい、しかも記録したいトラフィックの記録(トランスクリプト)を汚してしまうためです。autoやmodernを選ぶのは利用者の明示的な操作にし、Protocolタブに映る内容が「自分が設定したクライアントの挙動どおりである」ことを保証しています。
接続が確立すると、ネゴシエートされた世代は接続ヘッダーと「Connection Info」に表示されます。modern接続ではserver/discoverがcapabilities(extensions含む)・instructions・supportedVersionsも返し、サーバー名とバージョンは結果の_meta内io.modelcontextprotocol/serverInfoに載ります。
ログ・リソース購読はどう変わるか
ロギングは世代間で最も差が分かりやすい部分です。
ログレベルの決まり方
legacy
logging/setLevelを1回送ると、そのセッションが終わるまでサーバーが指定レベル以上のnotifications/messageを送り続けます。Logsタブには「Set Active Level」セレクタと「Set」ボタンが並びます。
modern
logging/setLevelは廃止され、各リクエストの_meta["io.modelcontextprotocol/logLevel"]にレベルを載せた分だけログが返ります。Logsタブは「Log Level per Request」に変わります。
modernでレベルをOffにするとlogLevelキー自体が送られず、同じツール呼び出しでもログが一切出ません。この無音はバグではなく仕様どおりの挙動です。サーバーがlogLevelの無いリクエストにnotifications/messageを返すことは、仕様で禁じられています。
Inspectorのサーバーごとの既定値はdebug(最も詳細なレベル)です。デバッグ用途なので最初から全部出す設計で、modernLogLevel: "off"を設定すると既定を無効に戻せます。同じ改訂でLogging機能自体がDeprecated(非推奨)に分類されており、仕様上はstderr(stdioの場合)かOpenTelemetryへの移行が案内されています。
リソース購読も同様です。legacyはresources/subscribeを送るだけのセッションフラグ的な扱いですが、modernはsubscriptions/listenという長命なストリームに置き換わり、購読が確認されるとnotifications/subscriptions/acknowledgedが返ります。Inspectorの「Subscriptions」セクションにはストリームの状態を示すバッジが追加され、Connecting...からListeningへ遷移する様子が見えます。ストリームが切れた場合、Inspectorはsubscriptions/listenを再送して自動的に再接続します。
Tasksタブの表示条件そのものが世代で変わる
Tasks(長時間実行タスク)の扱いは、UIタブの出し方自体が世代によって異なる珍しいケースです。legacyでは、サーバーがcapabilities.tasksを広告していればTasksタブが現れ、tasks/listで一覧を取得しtasks/getでポーリングします。完了したペイロードはブロッキングのtasks/resultで取得し、キャンセルはtasks/cancelです。
modernではTasksは拡張機能(io.modelcontextprotocol/tasks)として扱われるため、タブはcapabilities.tasksではなくネゴシエートされた拡張機能の有無で出し分けられます。tasks/listが存在しないので、Refreshはクライアントが既に把握しているハンドルを再ポーリングするだけです。
modernでタスクが完了するまで
- 1
ツールをタスクとして実行する
tools/callがCreateTaskResult(resultType: "task")を返します。Protocolタブでも確認できます。 - 2
tasks/getでポーリングする
Inspectorが使うのは
tasks/getだけです。ブロッキングのtasks/resultは呼ばれません。 - 3
追加入力が必要ならinput_requiredになる
埋め込まれたelicitation(追加入力要求)が、リクエスト待ちのときに開くpending-requestモーダルに出ます。回答は
tasks/updateで送ります。 - 4
次のポーリングで完了する
完了したタスクは結果をインラインで返します。
仕様の変更履歴では、Tasksはコアプロトコルの実験的機能から公式拡張へ移され、tasks/resultのブロッキング取得がtasks/getのポーリングに置き換わりました。移行の経緯はMCP Tasksが拡張機能に移った理由にまとめています。
modernのTasksを試すには、テスト用サーバー構成のtasks-modern-http.jsonを使います。modern_taskとmodern_input_taskの2つのツールが入っています。後者はinput_requiredを経由して追加入力を求める流れを試せます。
複数ラウンドのツール結果(MRTR)はInspector上でどう進むか
modern世代では、ツールが最終結果の代わりにinput_requiredを返し、elicitation・sampling(サーバーからのモデル呼び出し要求)・roots/listのいずれかを埋め込めます。クライアントは埋め込まれたリクエストに応答し、新しいJSON-RPC idでtools/callをやり直してcompleteに到達するまで続けます。これがMulti-Round Tool Results(MRTR)です。
Inspectorはこの往復を手動で進行させる設計です。各ラウンドはinput_requiredタグの付いたpending-requestモーダルで一時停止し、利用者が回答するまで進みません。Protocolビューはこの一連のやり取りを個別の呼び出しとしてではなく、1つのMRTR会話としてまとめて表示します。なお、legacyで使われていたcollect_elicitationパターン(サーバーがserver.elicitInputを呼ぶ方式)は、modern接続ではサーバーからクライアントへのリクエストが許可されていないためエラーになります。MRTRはこのパターンの後継です。
mrtr-showcase-http.jsonは、MRTRの典型パターンを1つのmodernサーバーにまとめた構成です。
| ツール | 試せること |
|---|---|
mrtr_confirm | 試せることelicitation 1ラウンド |
mrtr_two_step | 試せることelicitation 2ラウンド(requestStateで引き回す) |
mrtr_sample | 試せること埋め込みのsampling要求(Samplingパネルへ) |
mrtr_roots | 試せること埋め込みのroots/list(設定済みのrootsで自動応答、モーダルなし) |
mrtr_edge | 試せることinputRequestsだけのラウンド、続いてrequestStateだけのラウンド |
mrtr_loop | 試せること完了しない。クライアントのMRTR_MAX_ROUNDS上限で止まる |
仕様側では、すべての結果に必須のresultTypeが付きます。通常の結果は"complete"、MRTRの途中結果は"input_required"です。旧世代のサーバーが返すresultTypeの無い結果は、クライアントが"complete"として扱います。フィールドの全体像はMCPのresultTypeフィールドが整理しています。
エラー表示・ヘッダーはmodernでどう詳しくなるか
modern世代ではMcp-*のHTTPヘッダー群と、より細かいJSON-RPCエラー分類が標準化されました。Inspectorはこれを2つのタブで役割分担して見せます。NetworkタブはHTTP層のビューで、ミラーリングされたMcp-*ヘッダーがハイライトされます。ProtocolタブはJSON-RPC層のビューで、仕様上の各エラーが総称的な失敗ではなく個別に描画されます。
代表的な4つのエラーコードは次のとおりです。
| HTTPステータス | JSON-RPCコード | 意味 |
|---|---|---|
| 400 | JSON-RPCコード-32020 | 意味必須のミラーリングヘッダーが欠落・不一致(HeaderMismatch) |
| 400 | JSON-RPCコード-32021 | 意味リクエストにクライアント機能の宣言が欠けている |
| 400 | JSON-RPCコード-32022 | 意味サポート外バージョン(data.supportedに対応版が入る) |
| 404 | JSON-RPCコード-32601 | 意味メソッドが見つからない |
これらのコードは、仕様の草案段階から番号が振り直されています。HeaderMismatchは-32001から-32020、MissingRequiredClientCapabilityは-32003から-32021、UnsupportedProtocolVersionは-32004から-32022です。-32020〜-32099はMCP仕様の予約範囲で、-32000〜-32019は実装定義のまま残されました。古い資料のコードを見たら、この振り替えを疑う価値があります。リソースが見つからないエラーも、-32002から-32602(Invalid Params)に変わりました。
tools/callが-32602で拒否された場合も、modernでは「Unknown Tool(存在しないツール名)」と「Invalid Parameters(それ以外の-32602)」を別々のエラーパネルとして描画します。両世代とも-32602自体は同じですが、legacyでは1つの汎用JSON-RPC失敗としか表示されず、メッセージを読んで原因を判別する必要があります。
引数をHTTPヘッダーに写すツールはどう見えるか
modernでは、Streamable HTTPのPOSTにMcp-MethodとMcp-Nameヘッダーが必須になりました。ツールの引数にx-mcp-headerの注釈を付けると、その引数の値をMcp-Param-*ヘッダーにも写させられます(SEP-2243)。
Inspectorは、この約束の両面をToolsタブに出します。
- 注釈が正しいツールは、詳細パネルに「Mirrored request headers (SEP-2243)」が現れます。たとえば
city -> Mcp-Param-Cityです。 - 注釈が不正なツールは、サイドバーの「Excluded (SEP-2243)」の下に取り消し線つきで並び、理由がホバーで読めます。ヘッダー名が
"Bad Header"だとスペースがRFC 9110のトークンとして不正になる、といった例です。
準拠クライアントは、不正な注釈のツールをtools/listから落とさなければなりません(MUST)。Inspectorは黙って隠さず、落とした理由まで見せます。xmcpheader-modern-http.jsonで再現できます。
セッションの有無が自作サーバーの実装に効いてくる
接続の持ち方
legacy
サーバーがMcp-Session-Idを割り当て、クライアントはHTTPのDELETEで明示的に破棄します。
modern
セッションIDが無く、クライアントSDKはDELETEを送りません。切断はローカルで完結します。
仕様の変更履歴では、プロトコルレベルのセッションとMcp-Session-Idヘッダーの削除が最初に挙がっています。tools/listなどの一覧エンドポイントも、接続ごとに内容が変わらなくなりました。
これは自作のテストサーバーを書くときに実務上の制約になります。リクエストごとに使い捨てで構築されるstatelessなmodernハンドラーは呼び出し間で状態を保持できません。公式のテスト用サーバー構成でも、modern版のリソース購読設定はlegacy版と違ってupdate_resourceツールを持たせていません。使い捨てのサーバーインスタンスに対する変更が次の読み取りから見えなくなるためです。
呼び出しをまたぐ状態が必要なサーバーには、仕様側に逃げ道があります。サーバーが発行した明示的なハンドルを、通常のツール引数として受け渡す設計です。インメモリの変数に頼る状態管理は、modernでは前提にできません。さらに、SSEストリームの再開(Last-Event-ID)とメッセージの再送も削除されました。応答ストリームが途中で切れたら、そのリクエストは失われ、クライアントが新しいリクエストIDで出し直します。MCPのセッションID廃止がプロトコル全体に与える影響はMCPのセッションID廃止の理由にまとめています。
表示の差はどの仕様変更に由来するか
Inspectorの画面差は、2026-07-28改訂の変更履歴にほぼそのまま対応します。画面で見えた違いから、読むべき仕様の項目を引き当てる早見表です。
| Inspectorで見える差 | 仕様の変更 |
|---|---|
接続がinitializeからserver/discoverに | 仕様の変更ハンドシェイク廃止と、リクエストごとの_meta(SEP-2575) |
| Logsタブが「Log Level per Request」に | 仕様の変更logging/setLevelの削除(SEP-2575) |
| Subscriptionsに状態バッジ | 仕様の変更subscriptions/listenへの置き換え(SEP-2575) |
| Tasksタブの出し方と取得方法 | 仕様の変更Tasksの拡張機能化(SEP-2663) |
input_requiredのモーダル | 仕様の変更MRTRの導入(SEP-2322) |
DELETEが飛ばない | 仕様の変更セッションの削除(SEP-2567) |
| Excluded表示とミラーされたヘッダー | 仕様の変更x-mcp-header(SEP-2243) |
同じ改訂では、Roots・Sampling・LoggingがDeprecatedに分類されました(SEP-2577)。機能は引き続き動き、削除までの非推奨期間は最低12か月と定められています。
modern接続で検査するときは、ほかにも2点に注意が要ります。logging/setLevelと同じ項目で、pingとnotifications/roots/list_changedも削除されました。pingで生存確認をしていた手順は、modernでは成り立ちません。またtools/list・prompts/list・resources/list・resources/read・resources/templates/listの結果には、ttlMsとcacheScopeが必須のフィールドとして付きます。modernサーバーの一覧結果には、このフィールドが含まれます。
Inspectorで両世代を再現する最小手順
テスト用サーバー構成を、次のコマンドでビルドします。
git clone https://github.com/modelcontextprotocol/inspector
cd inspector && npm install && npm run build
cd clients/web && npm run test-servers:buildビルド後は、test-servers/configs/の設定ファイルをInspectorに読み込ませます。
| 試したいこと | legacy | modern |
|---|---|---|
| ログレベル | legacylogging-legacy-http.json | modernlogging-modern-http.json |
| リソース購読 | legacysubscriptions-legacy-http.json | modernsubscriptions-modern-http.json |
| Tasks | legacytasks-legacy-http.json | moderntasks-modern-http.json |
| MRTR | legacyなし | modernmrtr-showcase-http.json |
| ヘッダーのミラー | legacyなし | modernxmcpheader-modern-http.json |
| HTTPエラーの分類 | legacyなし | modernmodern-network-http.json |
自作サーバーの世代が分からないときは、modernで接続して明示的に失敗するかどうかを見ます。上の表のとおり、modernにはフォールバックがないので、失敗すればmodernではないと判断できます。
まとめ
MCP Inspectorは、protocolEraの1つの設定で2026-07-28改訂の前後のサーバーを同じ画面で検査できます。既定のlegacyは何も探りに行かない安全側の設定なので、modern前提のサーバーを調べるときは、autoかmodernに切り替えたかどうかが結果の読み違いに直結します。