Streamable HTTPとは? MCPが選んだ「AI時代の通信」
最近、LLM(大規模言語モデル)とアプリケーションをつなぐ、標準プロトコルとして期待されているのが Model Context Protocol (MCP) です。
エンジニアの方なら一度は耳にしたことがあるかもしれません。その仕様を深掘りしていくと、通信レイヤーにおいて気になる技術がありました。
それが 「Streamable HTTP」 です。
MCPの最新仕様(2025-11-25版)に基づき、なぜAI時代の通信にこの方式が採用されたのか、そのアーキテクチャの面白さを解説していきます!
Streamable HTTPとは
MCPの仕様書(Transports - Streamable HTTP) では、JSON-RPCメッセージを配送するための 「トランスポート規格(Transport Binding)「として、以下の方式を 「Streamable HTTP」 と定義しています。
A transport for JSON-RPC messages over HTTP, using a combination of Request/Response and Server-Sent Events (SSE).
つまり、「HTTPのリクエスト/レスポンス(主にPOST)」と「SSE」を組み合わせたハイブリッド方式のことです。一般的に「HTTP+SSE」と呼ばれる技術構成ですが、MCPではこれに双方向通信のためのルール(後述)を加え、独自のトランスポート層として標準化しています。
SSE(Server-Sent Events)とは、一度確立したHTTP接続を維持したまま、サーバーからクライアントへ一方向にテキストデータを継続的にプッシュ送信するWeb標準技術です。WebSocketのような複雑なプロトコル切り替えを必要とせず、「普通のHTTP通信の延長」として実装できるシンプルさが特徴です。
最大の特徴:「POST-SSEパターン」による双方向通信
Streamable HTTPの最大の発明は、「上り(Client→Server)はPOST、下り(Server→Client)はSSE」 という役割分担を行い、それをセッションIDで紐付けるアーキテクチャにあります。
通常、双方向通信にはWebSocket(常時接続)が使われますが、MCPではあえてこれを使わず、標準的なHTTP技術の組み合わせだけで「擬似的な双方向通信」を実現しています。
これにより、AWS LambdaやCloud Runのような「ステートレス(常時接続できない)な環境」でも、WebSocket用の特別なゲートウェイや複雑な構成を必要とせず、標準的なHTTP機能だけで双方向通信を実現できる という大きなメリットが生まれています。
技術的詳細:ここが「普通のHTTP」と違う!
では、具体的にどのような仕組みで動いているのか、技術的な「推しポイント」を3つ紹介します。
1. 動的なレスポンス形式の選択(Content Negotiation)
これが一番面白い部分です。クライアントはリクエストを送る際、Content Negotiation(コンテンツネゴシエーション)の仕組みを利用して、Accept ヘッダで「私はJSONもいけるし、ストリームもいけるよ」と宣言します。
POST /mcp HTTP/1.1
Host: api.example.com
Accept: application/json, text/event-stream
Content-Type: application/json
{ "jsonrpc": "2.0", "method": "...", "id": 1 }
これを受け取ったサーバーは、処理の重さに応じて返し方を動的に変えることができます。
-
処理がすぐ終わる場合:
通常のREST APIのようにContent-Type: application/jsonでレスポンスを返します。コネクションはその場で閉じられます。 -
処理が長い(または通知が必要な)場合:
Content-Type: text/event-streamに切り替え、Server-Sent Events (SSE)として接続を維持したままデータを流し始めます。
この挙動をシーケンス図にすると以下のようになります。
この仕組みこそが、Streamable HTTPの革新的な点です。
従来のSSEでは「常に接続し続ける」ことが前提でしたが、MCPではツール実行などの短い処理であれば、常時接続を維持せず、JSONを返して即座に切断する(ステートレス) という選択肢が生まれました。これにより、サーバーレス環境でのリソース消費を劇的に抑えることができます。
2. HTTPなのに「ステートフル」なセッション管理
HTTPは本来ステートレス(状態を持たない)プロトコルです。しかし、対話型AIには「文脈(Context)」が必要です。
そこでMCPでは、MCP-Session-Id というカスタムヘッダを使用します。
- 初期化リクエスト時に、サーバーが一意なセッションIDを発行して返す。
- クライアントはそれを受け取り、以降の全てのリクエスト(POST/GET)のヘッダにそのIDを含める。
- サーバーはそのIDを見て、「ああ、さっきの続きね」と認識する。
WebSocketのようにTCPコネクションレベルで繋ぎっぱなしにするのではなく、論理的なIDでセッションを紐付けることで、HTTPの気楽さを保ったまま文脈を維持しています。
3. 双方向通信の実現(JSON-RPC + SSE)
双方向通信は以下のように役割分担されています。
-
Client → Server:
POSTリクエストで JSON-RPC 2.0 メッセージを送る。 - Server → Client: SSEを用いて、サーバーからクライアントへ能動的にメッセージをプッシュする。
サーバーから何か言いたいときは、クライアントが待ち受けしているSSEのパイプラインに流し込めば良い、というシンプルな構造です。
なぜWebSocketではなくStreamable HTTPなのか?
「WebSocketの方が速いし、双方向だし、最強では?」と思うかもしれません。しかし、MCPの仕様において、WebSocketではなくStreamable HTTPが標準として採用されているのには、明確な 「インフラ・運用上の理由」 があります。
[Image of HTTP versus WebSocket architecture comparison]
ステートレスなサーバー運用との相性
WebSocketはサーバーとの常時接続を前提とするため、サーバー側でコネクション管理のコストが発生します。オートスケーリングでサーバーが増減する際や、サーバーレス環境(AWS LambdaやCloud Run)では、この「常時接続」が足かせになることがあります。
HTTPベースであれば、リクエスト単位で処理が完結しやすいため、モダンなサーバーレスアーキテクチャに非常にフィットします。MCPの仕様が、JSONレスポンス(即時切断)を選択できるようにしているのも、このサーバーレス適性を最大化するためと考えられます。
インフラ・プロキシへの親和性(Firewall Friendly)
企業内ネットワークや厳しいファイアウォール環境では、WebSocketのプロトコルアップグレードが遮断されることが多々あります。また、L7ロードバランサーの設定によっては、WebSocketの長いコネクションがタイムアウトで切られることもあります。
一方、Streamable HTTPはあくまで「普通のHTTP通信(テキストデータのダウンロード)」として振る舞います。そのため、既存のWAF、ロードバランサー、認証プロキシ(OAuthなど)をそのまま通過しやすいという強力なメリットがあります。
標準機能による再接続(Resumability)
地味ですが重要なのが「再接続」です。
モバイル回線などで瞬断した際、WebSocketでは「どこまでデータを受け取ったか」を管理し、再送要求するロジックをアプリ層で実装する必要があります。
対してSSE(Streamable HTTP)には、Last-Event-ID という標準仕様があります。
接続が切れても、ブラウザやクライアントが「ID: 100までは受け取りました」と自動的にヘッダをつけて再接続してくれるため、データの欠損なくスムーズに復帰できます。
もちろん、全てのケースでStreamable HTTPが優れているわけではありません。
MCPは「AIへの指示と回答(比較的頻度は低く、1回のデータ量は多い)」という特性に最適化されているため、あえてHTTPベースの設計を選んでいるのです。
まとめ
Streamable HTTPは、AIとの通信においてWebSocketとは異なるアプローチを提供する技術です。
特に以下の3点が大きなメリットとして挙げられます。
- サーバーレス環境との高い親和性
- HTTP標準の仕組みを活かした柔軟な制御
- 既存インフラへの適応しやすさ
AIエージェントやツールを開発する際は、Streamable HTTPも選択肢として検討してみてください。
MCPの仕様書は、プロトコル設計の教科書としても非常に面白いので、ぜひ一度原文も読んでみるてください!
Discussion