Claude Media
MCP Streamable HTTPからGETストリームとセッションが消えた理由

MCP Streamable HTTPからGETストリームとセッションが消えた理由

MCP仕様2026-07-28で、Streamable HTTPのGETストリームとMcp-Session-Idによるセッションが廃止されました。何が変わり、旧クライアントとどう共存するかをまとめます。

Streamable HTTPは、サーバーが独立したプロセスとして複数クライアントを相手にする、MCPのリモート接続用トランスポートです。2026-07-28の仕様改訂で、このトランスポートから2つの要素が消えました。サーバー側が長時間の接続を張っておくためのGETエンドポイントと、Mcp-Session-Idヘッダーによるプロトコルレベルのセッションです。

どちらも2025-11-25版までは存在していた機能で、削除は単なる整理ではなく、MCPサーバーを「接続を覚えている常駐プロセス」から「リクエスト単位で完結するWeb API」に近づける設計変更です。

Streamable HTTPの基本形 — 1つのPOSTエンドポイントに全部乗せる

サーバーは単一のHTTPエンドポイント(MCPエンドポイント)を公開し、POSTだけを受け付けます。クライアントが送るJSON-RPCのリクエストや通知は、それぞれ独立したPOSTリクエストになります。サーバーはリクエストごとに、単一のJSONオブジェクト(Content-Type: application/json)か、そのリクエストに紐づくSSEストリーム(text/event-stream)のどちらかで応答し、クライアントは両方を扱えなければなりません。

セキュリティ面では、DNSリバインディング攻撃を防ぐためOriginヘッダーの検証が必須で、不正または想定外の値であれば403 Forbiddenを返す義務があります。ローカルで動かす場合は0.0.0.0ではなく127.0.0.1にのみバインドすることが推奨されています。

すべてのPOSTリクエストには、2025-06-18版で追加されたMCP-Protocol-Versionヘッダーに加えてMcp-MethodMcp-Nameという標準ヘッダーが必須になりました。この2つのヘッダーの検証条件とHeaderMismatchErrorの発生条件はMCPでMcp-MethodとMcp-Nameヘッダーが必須になった理由に詳しくまとめているので、ここでは深入りしません。

2026-07-28で何が削除されたか — GETエンドポイントとセッション

削除された2つの要素を、2025-11-25版までの姿と比べると次のようになります。

要素2025-11-25版まで2026-07-28版
サーバー通知の受信経路2025-11-25版までGETでSSEストリームを開いて待つ2026-07-28版subscriptions/listenへのPOSTで開く
接続の単位2025-11-25版までMcp-Session-Idでセッションを識別2026-07-28版セッションなし。tools/list等は接続に関わらず内容が同じ
ストリームの再開2025-11-25版までLast-Event-IDで再開可能2026-07-28版再開不可。切れたら新しいリクエストIDで送り直す
サーバーからの割り込みリクエスト2025-11-25版までSSEストリーム上でroots/list等を送信可2026-07-28版廃止。MRTRパターンのInputRequiredResultに一本化

Mcp-Session-Idが消えたことで、tools/listresources/listのような一覧系エンドポイントは「どの接続から呼んだか」に関わらず同じ内容を返すようになりました。呼び出しをまたいで状態を保ちたいサーバーは、セッションに頼るのではなく、サーバー自身が発行するハンドルを通常のツール引数として渡す設計に変える必要があります。

Last-Event-IDによるストリーム再開の廃止も実務上のインパクトがあります。応答用のSSEストリームが途中で切れた場合、以前は同じイベントIDから再開できましたが、2026-07-28版ではその仕組み自体がありません。クライアントは進行中のリクエストを失ったものとして扱い、新しいリクエストIDで送り直す必要があります。

subscriptions/listenが担う変更通知の仕組み

サーバー側の変更をクライアントに知らせる経路は、GETによる常時接続からsubscriptions/listenという1本のリクエストに置き換わりました。クライアントはtoolsListChangedpromptsListChangedresourcesListChangedresourceSubscriptionsのうち欲しい種類を指定してこのリクエストを送ります。サーバーはPOSTへの応答として開いたSSEストリームを開いたままにし、該当する通知だけを流し続けます。

notifications/progressnotifications/messageのようなリクエストに紐づく通知は、このsubscriptions/listenのストリームには乗りません。あくまでそのリクエスト自身の応答ストリーム上を流れます。長時間ストリームを開いたままにする都合上、仕様は中継プロキシによるタイムアウトを避けるため、コロンで始まるSSEコメント行を定期的なキープアライブとして送ることをサーバーに推奨しています。

後方互換 — 2025-11-25以前のクライアントとどう共存するか

2026-07-28版のみに対応したサーバーが、Mcp-Session-IdヘッダーやGET・DELETEリクエスト、Last-Event-IDヘッダーを含む古いトラフィックを受け取ったときの推奨対応は明確です。GETやDELETEには405 Method Not Allowedを返し、Mcp-Session-Idは無視してセッションIDを発行も反映もせず、Last-Event-IDも無視してストリームを再開不可のまま扱います。

クライアント側からサーバーの世代を見分ける手順も定義されています。まず通常どおりPOSTでリクエストを送り、成功すれば新しいStreamable HTTP対応サーバーです。400404405が返り、かつレスポンス本文が新しいプロトコルの既知のJSON-RPCエラーでなければ、GETリクエストを送ってendpointイベントが返るかを確認します。返ってくれば、相手は2024-11-05版のHTTP+SSEという非推奨のトランスポートで動いていると判断し、以降はその方式に切り替えます。

curl -i https://example.com/mcp \
  -X GET

このcurlで405 Method Not Allowedが返ってくれば、そのサーバーはすでにGETエンドポイントを廃止した2026-07-28版のStreamable HTTPで動いている、という簡単な切り分けに使えます。逆にendpointイベントを載せたSSEストリームが開けば、相手は2024-11-05版のHTTP+SSEのままだと判断できます。

Claude CodeのMCPクライアントもこの検出の恩恵を受けています。v2.1.232以降のv2ランタイムは、HTTPサーバーとclaude.aiコネクタサーバーに対して標準で2026-07-28対応可否を確認し、対応していればそちらを使います。自作のリモートサーバーをこの仕様に上げれば、Claude Code側の設定を変えなくても新しいトランスポートでの通信に切り替わります

古いクライアントとの共存を自分のサーバー側で維持したい場合は、旧SSEエンドポイントと旧POSTエンドポイントを、新しいMCPエンドポイントと並行してホストし続けるという選択肢もあります。両者を1つのエンドポイントに統合することも可能ですが、仕様は「不要な複雑さを持ち込む可能性がある」と釘を刺しています。段階的に移行したいサーバー運用者にとっては、いつ旧エンドポイントを畳むかの判断材料になります。

認証の枠組みはトランスポートで別物になる

Streamable HTTPを含むHTTPベースのトランスポートは、MCPが定義するAuthorization(認可)フレームワークに従うべきだとされています。OAuthを軸にしたこのフレームワークは、リモートのMCPエンドポイントに対する認証・認可の標準的なやり方を定めるものです。

対照的に、stdioトランスポートを使う実装はこのフレームワークに従うべきではないとされ、代わりに環境変数などその場の実行環境から認証情報を取得することが想定されています。同じMCPでも、トランスポートが変わればどこで認証情報を扱うべきかという設計方針そのものが変わるということです。クライアントとサーバーが独自の認証方式を合意することも仕様上は妨げられていません。

認可サーバーが返す認可レスポンスに発行者を示すissパラメータを含めるべきだという要件も、この改訂で加わりました。MCPクライアントは、認可コードを引き換える前に、返ってきたissの値が記録済みの発行者と一致するかを検証しなければなりません。Claude Code側もこの検証を実装しており、v2.1.221以降のv2ランタイムはMCP OAuthサーバーが返す発行者を確認し、一致しなければIssuer mismatch in authorization responseから始まるエラーでサインインを失敗させます。v1ランタイムはこの検証を行いません。リモートMCPサーバーのOAuth認証を自作していて、認可レスポンスにissを含めていない場合は、この検証で弾かれる可能性があるということです。

Streamable HTTPの版数タイムライン

Streamable HTTPという名前自体は2025-03-26版から使われていますが、中身は複数回にわたって手が入っています。

バージョンStreamable HTTPの姿
2024-11-05Streamable HTTPの姿HTTP+SSE(GETでSSEを開き、POSTでメッセージ送信。現在は非推奨)
2025-03-26Streamable HTTPの姿Streamable HTTPとして導入。単一のPOSTエンドポイントに統合し、Mcp-Session-IdによるセッションとLast-Event-IDによる再開を規定
2025-06-18Streamable HTTPの姿後続リクエストでMCP-Protocol-Versionヘッダーを送る要件を追加
2025-11-25Streamable HTTPの姿Origin不正時の403応答とGETストリームの再開挙動を明確化(形自体はセッション・再開を含め2025-03-26版のまま)
2026-07-28Streamable HTTPの姿セッション・GETエンドポイント・ストリーム再開をすべて廃止

2025-03-26版の導入時からあったセッション管理と再開機能が、2026-07-28版で丸ごと削除されているのが目を引きます。3世代(2025-03-26・2025-06-18・2025-11-25)にわたって維持されてきたステートフルな接続管理を撤回したという経緯は、この設計がうまくいかなかったというより、MCPサーバーの運用実態がステートレスなWeb APIの構成に寄っていったことの反映だと読めます。

GETエンドポイントの廃止でMCPサーバーはコネクション管理から解放される

セッションIDやストリームの再開ロジックを実装から取り除くと、サーバー側の設計はシンプルになります。どのリクエストも「届いたら処理して返す」だけで完結し、特定のクライアントとの接続状態をどこかに保持しておく必要がありません。

これは、一般的なWebバックエンドの設計がロードバランサーの背後で複数インスタンスを気軽にスケールできるステートレスな構成へ寄っていった流れと同じ方向です。MCPサーバーをコンテナで動かし、オートスケールやローリングデプロイの対象にしたい事業者にとって、特定のインスタンスに固定されるセッションは扱いにくい制約でした。2026-07-28版の変更は、MCPサーバーを普通のHTTPインフラの上でも運用しやすくするための整理だと見ることができます。

まとめ

MCP仕様2026-07-28版は、Streamable HTTPからGETエンドポイントによる常時接続とMcp-Session-Idによるセッションを削除し、変更通知はsubscriptions/listenへの単一のPOSTに一本化しました。旧世代のクライアント・サーバーとは、GET/DELETEへの405応答とヘッダーの無視という形で共存できるように設計されています。Claude Codeのv2ランタイムは対応サーバーを自動で検出するため、自作のリモートサーバーを2026-07-28対応に上げても接続側の設定変更は基本的に不要です。

MCP全体の仕組みと利用面別の違いはMCPとはに、リモートMCPのOAuth認証はリモートMCPのOAuth認証に、stdioとStreamable HTTPの使い分けはAgent SDK MCP接続ガイドにまとめています。

この記事を共有:XはてブLinkedIn
MCP をもっと見る →