本文へスキップ
株式会社オブライト
Software Development2026-07-29約13分で読めます

MCP 2026-07-28 仕様公開 — ステートレス化で何が変わり、既存サーバーの何が壊れるか

2026年7月28日公開のMCP新仕様を解説。initializeハンドシェイクとセッションIDの廃止、server/discover、Multi Round-Trip Requests、Tasks拡張、認可強化、Roots/Sampling/Loggingの非推奨を移行観点で整理。


2026年7月28日、Model Context Protocol(MCP)の新仕様 2026-07-28 が公開された。前版 2025-11-25 からの最大の変更はプロトコルのステートレス化で、initialize ハンドシェイクとセッションIDが廃止され、すべてのリクエストが自己完結する形になった。サーバーレスやエッジ環境への配置が容易になる一方、既存のMCPサーバー実装には確実に手が入る。ここでは変更点を、移行時に何が壊れるかという観点で整理する。

変更点サマリー

項目2025-11-252026-07-28
接続開始initialize / notifications/initialized のハンドシェイク廃止。各リクエストの _meta にバージョンと機能を載せる
バージョン交渉initialize時に1回server/discover(サーバー実装必須)で事前取得、またはリクエスト毎
セッションMcp-Session-Id ヘッダーによるプロトコルレベルのセッション廃止。状態はサーバー発行のハンドルをツール引数で渡す
変更通知HTTP GET+resources/subscribesubscriptions/listen の単一ストリームに統合
サーバー起点の要求sampling/createMessage elicitation/create roots/listMulti Round-Trip Requests(resultType: "input_required")に置換
長時間処理コアの experimental tasks公式拡張 io.modelcontextprotocol/tasks に分離
結果の形任意全結果に resultType 必須(complete / input_required

1. ステートレス化 — initializeハンドシェイクの廃止

従来は接続時に initialize を送り、notifications/initialized で確立し、以降のリクエストはその文脈を前提にしていた。新仕様ではこのハンドシェイクが丸ごと消え、すべてのリクエストが _meta に自分の文脈を載せて自己完結する

- io.modelcontextprotocol/protocolVersion — そのリクエストのプロトコルバージョン
- io.modelcontextprotocol/clientCapabilities — クライアントの機能
- io.modelcontextprotocol/clientInfo — クライアントの識別情報(SHOULD)
- サーバー側は各結果の _metaio.modelcontextprotocol/serverInfo を載せる(SHOULD)

バージョンが噛み合わない場合は UnsupportedProtocolVersionError を返す。実装上の意味は明快で、リクエスト間で状態を持つ前提のサーバーはそのままでは動かない。ハンドシェイク時に受け取った capabilities をインスタンス変数に保持しているコードは、リクエスト単位で読む形へ書き換えることになる。

2. server/discover — バージョン選択の入口

ハンドシェイクがなくなった代わりに、サーバーは server/discover RPCの実装が必須(MUST)になった。対応プロトコルバージョン・capabilities・identity を広告するためのもので、クライアントは他のリクエストの前に呼んで事前にバージョンを選ぶこともできるし、STDIO では後方互換性の探り(旧仕様サーバーかどうかの判定)にも使える。任意呼び出し(MAY)である点がポイントで、呼ばれない前提でもサーバーは正しく応答できなければならない

3. セッションIDの廃止と状態の持ち方

Streamable HTTP トランスポートから Mcp-Session-Id ヘッダーが削除され、tools/list resources/list prompts/list接続ごとに内容が変わってはいけないことになった。同じサーバーに同じリクエストを投げれば誰でも同じ一覧が返る、という前提である。

では会話をまたぐ状態はどう持つか。仕様の答えは「サーバーが発行したハンドルを、通常のツール引数として渡す」である。ログイン後のカーソル、進行中のジョブID、一時ファイルの参照といったものは、プロトコル層ではなくツールのスキーマの中で明示的に扱う。セッションに暗黙で状態を寄せていた実装ほど設計変更が大きくなる。

4. 通知は subscriptions/listen に一本化

HTTP GET エンドポイントと resources/subscribe / resources/unsubscribe が廃止され、subscriptions/listen という単一の長寿命POSTレスポンスストリームに統合された。クライアントは受け取る通知の種類(toolsListChanged / promptsListChanged / resourcesListChanged / resourceSubscriptions)を明示的にオプトインし、サーバーは通知に io.modelcontextprotocol/subscriptionId を付けて返す。

注意したいのは、notifications/progressnotifications/message のようなリクエストスコープの通知はこのストリームには流れないという点である。これらは関係するリクエストのレスポンスストリーム上を流れ続ける。進捗通知の受け口を subscriptions/listen に移そうとすると誤る。またログレベルは logging/setLevel が廃止され、リクエスト毎に _metaio.modelcontextprotocol/logLevel で指定する。このフィールドを含まないリクエストに対してサーバーは notifications/message を出してはならない(MUST NOT)。

5. Multi Round-Trip Requests(MRTR)

ステートレス化に伴い、サーバーからクライアントへ能動的にリクエストを投げる仕組み(roots/list sampling/createMessage elicitation/create)が成り立たなくなった。置き換えが MRTR パターンである。

- サーバーは処理途中で情報が必要になったら InputRequiredResultresultType: "input_required")を返し、inputRequests に必要な要求を並べる
- クライアントは inputResponses を付けて元のリクエストを再送する
- 全結果に resultType が必須になり、completeinput_required を必ず名乗る
- 旧仕様サーバーがフィールドを省いた場合、クライアントは complete として扱わなければならない(MUST)

副作用として、notifications/elicitation/complete と URLモード elicitation の elicitationId(いずれも 2025-11-25 で追加)が削除された。再送で結果を知る設計になったため、完了通知と相関IDが不要になったからである。リトライをまたいで相関させたいサーバーは、自前の識別子を requestState に埋める。

6. 拡張機能フレームワークと Tasks

コアの外に公式拡張を置く枠組みが入り、ClientCapabilities / ServerCapabilitiesextensions フィールドが追加された。experimental だった tasks はコアから外れ、公式拡張 io.modelcontextprotocol/tasks として再設計されている。

- ブロッキングの tasks/result を廃止し、tasks/get によるポーリングへ
- クライアントからの入力用に tasks/update を追加
- tasks/list は削除
- サーバーはリクエスト毎のオプトインなしにタスクハンドルを返せる

長時間処理をコアの機能として実装していた場合は、拡張として capabilities を宣言し直す必要がある。MCPサーバーを実際に組み込む手順はClaude Code × MCP 連携ガイドで扱っている。

7. 認可の強化

OAuth 2.0 / OIDC 周りは、企業のIdP(Entra、Okta等)と素直に繋ぐための実務的な締め直しが入った。

変更内容
iss の検証認可サーバーは RFC 9207 に沿って認可レスポンスに iss を含めるべき(SHOULD)。クライアントは認可コード引き換え前に記録済みの issuer と照合しなければならない(MUST)
動的クライアント登録(DCR)RFC 7591 のDCRを非推奨化し、Client ID Metadata Documents を推奨。DCR未対応の認可サーバー向けに互換維持
application_type動的クライアント登録時の指定を必須化し、OIDCのリダイレクトURI衝突を回避
クレデンシャルの束縛発行元の認可サーバーに紐づけて保存し、別の認可サーバーで再利用しない。認可サーバーが変わったら再登録する(MUST)

8. 非推奨になった機能

今回の版から機能ライフサイクルと非推奨ポリシー(Active / Deprecated / Removed の3状態、最低12か月の非推奨期間、非推奨機能レジストリ)が正式に導入された。以下は仕様には残るが、新規実装での採用は避けるべきものである。

非推奨推奨される代替
Rootsディレクトリやファイルはツール引数・リソースURI・サーバー設定で渡す
SamplingLLMプロバイダのAPIと直接統合する
Loggingstdio なら stderr へ出す、または OpenTelemetry を使う
HTTP+SSE トランスポート(2025-03-26 で非推奨)Streamable HTTP へ移行
includeContext"thisServer" / "allServers"省略するか "none" を使う

9. 見落としやすい細かな変更

- 一覧結果のキャッシュ必須化: tools/list 等の結果に ttlMscacheScopepublic / private)が必須。ポーリング削減のための鮮度ヒント
- ツールの並び順: tools/list は決定的な順序で返すべき(SHOULD)。クライアント側キャッシュとプロンプトキャッシュのヒット率のため
- リクエストヘッダー: Streamable HTTP のPOSTに Mcp-MethodMcp-Name が必須。ツール引数から独自ヘッダーを渡す x-mcp-header も追加
- SSEの再開機能を削除: Last-Event-ID とイベントIDによる再送は廃止。ストリームが切れたら新しいリクエストIDで投げ直す(MUST)
- エラーコードの整理: -32000-32019 は実装定義、-32020-32099 は仕様予約。リソース未検出は -32002 から -32602(Invalid Params)へ変更
- スキーマの緩和: inputSchema / outputSchema が JSON Schema 2020-12 の任意のキーワードを許容、structuredContent は任意のJSON値へ
- トレース: _metatraceparent / tracestate / baggage による OpenTelemetry のトレースコンテキスト伝播を規約化
- ping の削除: 死活監視をプロトコル層に頼っていた実装は代替が必要

既存MCPサーバーの移行チェックリスト

- initialize で受け取った情報に依存している箇所を洗い出し、リクエスト毎の _meta 読み取りに置き換えたか
- server/discover を実装したか(MUST)
- Mcp-Session-Id に依存した状態管理を、サーバー発行ハンドル+ツール引数へ移したか
- tools/list 等が接続ごとに違う結果を返していないか
- ttlMs / cacheScope を一覧結果に付けたか
- 全結果に resultType を付けたか
- サーバー起点リクエスト(sampling / elicitation / roots)をMRTRへ置き換えたか
- タスク機能を io.modelcontextprotocol/tasks 拡張として宣言し直したか
- 通知の購読を subscriptions/listen に移し、進捗通知はレスポンスストリームに残したか
- ログレベルを _metalogLevel から読む形にし、指定のないリクエストで notifications/message を出していないか
- 認可でクレデンシャルを issuer 単位で保存しているか、iss を検証しているか
- SSE再開に依存したクライアント実装がないか(切断時の再送に切り替える)

どのタイミングで移行するか

非推奨ポリシーで最低12か月の猶予が明文化されたため、Roots / Sampling / Logging を使っている実装が即座に動かなくなるわけではない。一方でステートレス化そのものは互換性のない変更で、resultType の付与や server/discover の実装は新仕様に対応する時点で必須になる。優先順位としては、まずコア(ステートレス化・resultTypeserver/discover)に対応し、非推奨機能の置き換えは猶予期間内に順次進めるのが現実的である。逆に、これから新規にMCPサーバーを書くなら、最初から非推奨機能に触れない設計にしておきたい。

よくある質問

既存のMCPサーバーは新仕様のクライアントから使えなくなりますか?

すぐに使えなくなるわけではありません。クライアントは STDIO では server/discover を後方互換性の探りとして使えますし、resultType を省いた旧仕様サーバーの結果は complete として扱うことが仕様で定められています。ただし新仕様のクライアントとサーバーが揃って初めて利用できる機能(MRTR、拡張、キャッシュヒント等)があるため、実利用の観点では移行が前提になります。

ステートレス化のいちばん大きな実務的メリットは何ですか?

セッションを保持しないため、サーバーレスやエッジ環境にそのまま置けることです。従来は接続単位の状態をどこかに保持する必要があり、水平スケール時にセッションアフィニティやセッションストアが必要でした。リクエストが自己完結することで、通常のHTTP APIと同じ運用に寄せられます。

sampling がなくなると、サーバーからLLMを呼ぶ処理はどう書きますか?

仕様が示す移行先は、LLMプロバイダのAPIと直接統合することです。つまりMCPサーバー自身がモデルAPIのクライアントになります。ユーザーへの追加入力要求(従来の elicitation 相当)は MRTR に置き換わり、input_required を返してクライアントの再送を待つ形になります。

セッションIDがないと、認証済みの状態はどう保持しますか?

認可は従来どおり OAuth のアクセストークンで各リクエストに付与されます。プロトコルレベルのセッションが不要になっただけで、認証情報が失われるわけではありません。会話をまたぐ業務的な状態(進行中のジョブ等)については、サーバーが発行したハンドルをツール引数として明示的にやり取りする設計に変えます。

仕様の日付表記はバージョン番号として扱ってよいですか?

MCPの仕様リビジョンは日付形式で識別され、今回は 2026-07-28、前版は 2025-11-25 です。実装では protocolVersion にこの文字列を載せてやり取りするため、日付そのものがバージョン識別子として機能します。

まとめ

2026-07-28 版は、MCPを「双方向ステートフルなプロトコル」から「リクエスト/レスポンスのHTTP APIらしいもの」へ寄せる大きな転換である。サーバーレス配置やスケールの容易さと引き換えに、initializeハンドシェイク・セッションID・サーバー起点リクエスト・SSE再開といった前提が消えた。既存実装の移行では、状態をどこに置き直すか(サーバー発行ハンドル)と、サーバーからの問い合わせをどうMRTRに畳み込むかの2点が設計上の山場になる。

この記事に関連する無料ツール(登録不要・その場で結果)

お気軽にご相談ください

お問い合わせ