MCP仕様2026-07-28版の最新アップデート、ステートレス化の要点

MCP仕様の最新版2026-07-28、変更の中心はステートレス化

MCP仕様の2026-07-28版は、前回の2025-11-25版以降の変更をまとめたもので、中心はステートレス化です。MCPはAIと外部ツールを連携する共通規格で、今回のバージョンでは接続の作り方と状態の持ち方が大きく変わりました。サービス側が用意するサーバーの例は、関連記事の「X MCPとは?公式サーバーの設定とX APIの料金・書き込みの範囲」にあります。

今回のバージョンでは、接続をまたぐ状態をプロトコルが持たなくなりました。従来は接続のはじめにinitializeで互いの能力を伝え、その後のやり取りをセッションIDで結びつけていました。

また、Streamable HTTP転送からMcp-Session-Idヘッダーが削除され、リクエストがそれぞれ単独で完結するようになっています。呼び出しをまたいで状態が必要な場合は、サーバーが発行したハンドルを通常のツール引数に含めてやり取りします。

一覧取得にも変更があります。tools/list・resources/list・prompts/listは接続ごとに結果が変わらなくなりました。キャッシュ向けの規則も新たに加わっています。

  • tools/listは毎回同じ順序で出力することが推奨されています。チェンジログによると目的は、クライアント側でキャッシュできるようにすることと、LLMのプロンプトキャッシュにおけるヒット率を上げることの2つです
  • 一覧系とresources/readの結果にはttlMsとcacheScopeが必須になった
  • ttlMsは鮮度の目安をミリ秒で表す値で、クライアントが応答をキャッシュしてポーリングを減らすために使うことができる
  • cacheScopeは共有の中継機構が応答をキャッシュしてよいかを表す値で、publicかprivateのどちらかをとる

削除された要素と置き換わった仕組みの対応は次のとおりです。pingとnotifications/roots/list_changedは、置き換え先なしで削除されました。

2026-07-28版で削除された主な要素と、置き換わった仕組み(公式チェンジログによる)

削除されたもの 置き換わった仕組み
プロトコルレベルのセッション/Mcp-Session-Idヘッダー サーバーが発行したハンドルを通常のツール引数に含める
initialize / notifications/initialized 各リクエストが_metaでバージョンと能力を申告
SSEストリームの再開/メッセージ再送(Last-Event-ID) 新しいリクエストIDで発行し直す
HTTP GETエンドポイント/resources/subscribe等 subscriptions/listen(長寿命のPOSTレスポンスストリーム1本)
サーバー起点のリクエスト(sampling/createMessage等) MRTR(途中結果で情報を求め、再送で受け取る)
logging/setLevel リクエストごとに_metaでログ水準を指定
ping・notifications/roots/list_changed 削除(置き換え先なし)
This document lists changes made to the Model Context Protocol (MCP) specification since the previous revision, 2025-11-25. / Remove protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport. List endpoints (tools/list, resources/list, prompts/list) no longer vary per-connection. Servers that need cross-call state use explicit, server-minted handles passed as ordinary tool arguments (SEP-2567). / Servers SHOULD return tools from tools/list in a deterministic order to enable client-side caching and improve LLM prompt cache hit rates. / Require ttlMs and cacheScope fields on results returned by tools/list, prompts/list, resources/list, resources/read, and resources/templates/list via a new CacheableResult interface. ttlMs is a freshness hint (in milliseconds) allowing clients to cache responses and reduce polling; cacheScope ("public" or "private") controls whether shared intermediaries may cache the response. — 対象となる版、セッション廃止、一覧の決定的順序とキャッシュ関連フィールドに関する記述より
公式情報を見る →

initialize廃止後はバージョンを_metaで毎回申告

initializeを廃止した2026-07-28版では、クライアントが各リクエストの_metaでバージョンと能力を毎回申告します。通信の前に対応バージョンや機能を互いに伝え合う手順をハンドシェイクと言い、MCPではinitializeとnotifications/initializedのやり取りがこの手順にあたっていました。2026-07-28版では、この2つが削除されています。

すべてのリクエストは_metaにプロトコルバージョンとクライアント能力を含めます。キーはio.modelcontextprotocol/protocolVersionとio.modelcontextprotocol/clientCapabilitiesです。

クライアントは各リクエストのio.modelcontextprotocol/clientInfoで、サーバーは各結果の_metaにあるio.modelcontextprotocol/serverInfoで自らの情報を通知することが推奨されています。また、バージョンが合わないときはUnsupportedProtocolVersionErrorというエラーが出力されます。

あわせてserver/discoverが追加されました。サーバーはserver/discoverを必ず実装し、対応するプロトコルバージョン・能力・識別情報を伝えます。クライアントは他のリクエストより前にserver/discoverを呼んでバージョンを選んでもよく、STDIO(標準入出力でやり取りする接続方式)では後方互換性を判定するために使うこともできます。

Make MCP stateless: remove the initialize/notifications/initialized handshake. Every request now carries its protocol version and client capabilities in _meta (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities). Clients SHOULD identify themselves on each request (io.modelcontextprotocol/clientInfo), and servers SHOULD identify themselves in each result's _meta (io.modelcontextprotocol/serverInfo). Version mismatches return UnsupportedProtocolVersionError (SEP-2575). / Add server/discover: servers MUST implement this RPC to advertise their supported protocol versions, capabilities, and identity. Clients MAY call it before any other request for up-front version selection, or use it as a backward-compatibility probe on STDIO (SEP-2575). — ステートレス化の内容と、server/discover の追加および呼び出し方に関する記述より
公式情報を見る →

Streamable HTTPでSSEと通知はどう変わるか

Streamable HTTPでは、SSEによる再開とメッセージ再送が削除され、通知ストリームもsubscriptions/listenにまとまりました。SSE(Server-Sent Events)は、サーバーからクライアントへ1本のHTTP接続を保ったままデータを送信し続ける仕組みです。

Streamable HTTP転送では、SSEの流れが途切れてもLast-Event-IDヘッダーとSSEイベントIDで続きから受け取れました。2026-07-28版はSSEの再開機能とメッセージの再送を削除しています。応答ストリームが切れた場合に処理中のリクエストは失われるため、クライアントは同じ内容を新しいリクエストIDで出し直さなければなりません。

通知の受け取り方も1本にまとまりました。HTTP GETの受け口とresources/subscribe・resources/unsubscribeがsubscriptions/listenに置き換わっています。

subscriptions/listenは長寿命のPOSTレスポンスストリーム1本を使って、申し込んだ種類の変更通知をサーバーからクライアントへ流す仕組みです。申し込める種類は次の4つです。

  • toolsListChanged(ツール一覧の変更)
  • promptsListChanged(プロンプト一覧の変更)
  • resourcesListChanged(リソース一覧の変更)
  • resourceSubscriptions(リソースの購読)

サーバーは申し込みを受け付けたことを応答し、以後の通知にio.modelcontextprotocol/subscriptionIdを含めます。リクエストに紐づく通知であるnotifications/progressやnotifications/messageは、従来どおり関係するリクエストの応答ストリームを流れます。subscriptions/listenには流れません。

Remove SSE stream resumability and message redelivery (the Last-Event-ID header and SSE event IDs) from the Streamable HTTP transport. A broken response stream loses the in-flight request; clients MUST re-issue it as a new request with a new request ID (SEP-2575). / Replace the HTTP GET endpoint and resources/subscribe/resources/unsubscribe with subscriptions/listen: a single long-lived POST-response stream for opted-in server-to-client change notifications. Clients opt in to specific types (toolsListChanged, promptsListChanged, resourcesListChanged, resourceSubscriptions); the server acknowledges and tags notifications with io.modelcontextprotocol/subscriptionId. Request-scoped notifications such as notifications/progress and notifications/message continue to flow on the response stream of the request they relate to, not the subscriptions/listen stream (SEP-2575). — SSE再開の削除と、通知の受け取り方の変更およびリクエスト単位の通知との区別に関する記述より
公式情報を見る →

ステートレス設計に合わせたMRTRの仕様変更

サーバー起点のリクエストを送信する従来の方式は、MRTRに置き換わりました。従来はサーバーがroots/list・sampling/createMessage・elicitation/createといったリクエストをクライアントへ送信していました。

MRTR(Multi Round-Trip Requests)は、サーバーが必要な情報の要求を結果に含めて返し、クライアントが再送で答える方式です。流れは次のとおりです。

  1. サーバーはInputRequiredResultを出力する。必要な情報の要求はinputRequestsに入り、resultTypeは"input_required"になる
  2. クライアントは元のリクエストを再送し、inputResponsesで応答する

すべての結果ではresultTypeが必須になりました。値は通常の結果が"complete"でMRTRの途中結果が"input_required"です。古いバージョンのサーバーからresultTypeのない結果が届いた場合も、クライアントは"complete"とみなさなければなりません。

追加情報が必要なときの流れ(従来とMRTRの対比)

段階 従来(サーバー起点) MRTR
きっかけ サーバーがroots/listなどのリクエストを送信する サーバーがinput_requiredの途中結果を出力する
要求の運び方 リクエストそのもの 結果のinputRequests
クライアントの動き サーバーのリクエストに返信する 元のリクエストを再送しinputResponsesを添える
Multi Round-Trip Requests (MRTR) pattern introduced which replaces the previous approach of sending server-initiated requests, such as roots/list, sampling/createMessage, or elicitation/create. Servers return an InputRequiredResult (resultType: "input_required") whose inputRequests field carries the requests for the additional information needed to process the request. Clients respond with inputResponses on a retry of the original request providing the requested information. (SEP-2322). / All results now carry a required resultType field: "complete" for ordinary results and "input_required" for multi round-trip request interim results. Clients MUST treat results from earlier-protocol servers that omit the field as "complete" (SEP-2322). — MRTR パターンの導入と、resultType フィールドの必須化に関する記述より
公式情報を見る →

tasksの公式拡張への移動とポーリング中心のアップデート

コアのプロトコルにあったtasksは、公式拡張へ移動し、ポーリング中心の設計になりました。tasksはもともと実験的な機能で、移動先の拡張はio.modelcontextprotocol/tasksです。設計は次のように変わりました。

  • 結果が出るまで待ちが続くtasks/resultを廃止し、tasks/getによるポーリングに変更した
  • クライアントからサーバーへ入力を送信するtasks/updateを新設した
  • tasks/listを削除した
  • クライアントがリクエストごとに申し込まなくても、サーバーはタスクのハンドルを出力できる
Move experimental tasks out of the core protocol and into an official extension (io.modelcontextprotocol/tasks). The redesigned extension replaces the blocking tasks/result method with polling via tasks/get and a new tasks/update for client-to-server input, removes tasks/list, and allows servers to return task handles unsolicited without per-request opt-in (SEP-2663). — tasks の拡張への移動と再設計に関する記述より
公式情報を見る →

最新バージョンへの移行では、どの箇所を見直すか

移行時に確認する箇所は、セッションID依存・接続断からの復帰・ping・ログ水準の指定・リソース未発見のエラーコード・スキーマの制約の6つです。旧と新の対応は「移行時に確認する箇所と旧版から新版への変わり方」のとおりです。

既存のサーバーやクライアントを新しいバージョンへ移行するときは、ご自身の実装が旧版の方式に依存していないかを、「移行時に確認する箇所と旧版から新版への変わり方」の行ごとにチェックします。

移行時に確認する箇所と旧版から新版への変わり方

確認する箇所 旧 新
セッションID依存 セッションとMcp-Session-Idヘッダー ヘッダーは削除。ハンドルをツール引数に含める
接続断からの復帰 Last-Event-IDで途中から再開する 再開と再送は削除。新しいリクエストIDで出し直す
ping 呼び出せる 削除
ログ水準の指定 logging/setLevel リクエストごとに_metaで指定
リソース未発見のエラー -32002 -32602(Invalid Params)
スキーマの制約 inputSchemaとoutputSchemaに制約あり JSON Schema 2020-12の任意のキーワード。structuredContentは任意のJSON値

notifications/roots/list_changedもpingと同じく削除されています。ログ水準を_metaのio.modelcontextprotocol/logLevelで指定しないリクエストに対して、サーバーはnotifications/messageを出してはならないと定められています。

エラーコードの変更は、JSON-RPC(JSONで遠隔の処理を呼び出す規約)の仕様に合わせたものです。-32000から-32019は実装定義のままで、既存SDKが使うコードも認められ、-32020から-32099はMCP仕様用に予約された範囲です。inputSchemaやstructuredContentに入れるJSONは、整形して構造を見ると間違いを見つけやすくなります。

Remove ping, logging/setLevel, and notifications/roots/list_changed. Log level is now set per-request via io.modelcontextprotocol/logLevel in _meta; servers MUST NOT emit notifications/message for requests that did not include this field (SEP-2575). / Change resource not found error code from -32002 to -32602 (Invalid Params) to align with JSON-RPC specification. / Define an error code allocation policy partitioning the JSON-RPC server-error range: -32000 to -32019 remains implementation-defined (existing SDK usage is grandfathered), -32020 to -32099 is reserved for the MCP specification. / Loosen inputSchema and outputSchema to allow any JSON Schema 2020-12 keywords, and structuredContent to allow any JSON value. — 削除された呼び出しとログ水準、エラーコードの変更と割り当て方針、スキーマ制約の緩和に関する記述より
公式情報を見る →

ステートレス化のアップデートで実装側に残る作業

ステートレス化したMCP仕様の2026-07-28版で実装側に残る作業は、状態の引き継ぎ・リクエストの出し直し・バージョンと能力の申告という3つです。プロトコルがセッションとハンドシェイクを持たなくなったため、3つとも実装側のコードで処理します。

  • 呼び出しをまたぐ状態が必要な場合は、サーバーが発行したハンドルをツール引数に含める
  • 応答ストリームが切れた場合は新しいリクエストIDでリクエストを出し直す
  • バージョンと能力を各リクエストの_metaで毎回申告する

最初に確認する箇所はMcp-Session-Idへの依存と、Last-Event-IDによる接続断からの復帰です。続けて削除された呼び出しの有無を確認し、エラーコードとスキーマの変更も見直します。削除された呼び出しの一覧は公式チェンジログにまとまっています。

FAQ

MCPの2026-07-28版で何が変わったのですか?
プロトコルレベルのセッションが廃止され、MCPがステートレスになったことが最も大きな変更です。Streamable HTTP転送からMcp-Session-Idヘッダーが削除され、tools/listなどの一覧取得が接続ごとに異なる結果になることもなくなりました。呼び出しをまたいで状態を持ちたい場合は、サーバーが発行したハンドルを通常のツール引数に含めてやり取りする方式に変わります。
initializeのハンドシェイクはもう不要なのですか?
不要になりました。initializeとnotifications/initializedのやり取りが削除され、すべてのリクエストの_metaにプロトコルバージョンとクライアント能力を含める方式になっています。バージョンが合わない場合は、UnsupportedProtocolVersionErrorというエラーが出力されます。
サーバー側から追加の情報を求める仕組みはどうなりましたか?
MRTR(Multi Round-Trip Requests)という、新しい方式に置き換わりました。サーバー自身からリクエストを送信せず、resultTypeがinput_requiredの結果を出力して、必要な情報の要求をinputRequestsに含めます。クライアントは元のリクエストを再送する際に、inputResponsesで応答します。
接続が切れたときの再開はできますか?
できなくなりました。Streamable HTTP転送から、SSEストリームの再開機能とメッセージの再送信が削除されています。応答ストリームが切れると処理中のリクエストは失われるため、クライアントは新しいリクエストIDで発行し直す必要があります。