MCP Streamable HTTPとは?仕様・ヘッダー・実装・移行を完全解説【2026-07-28版対応】
MCPのStreamable HTTPを最新仕様(2026-07-28)で解説。stdio・HTTP+SSEとの違い、必須ヘッダー(MCP-Protocol-Version / Mcp-Method / Mcp-Name)、セッション廃止とステートレス化、SSEストリーム、最小実装コード、2025年版からの移行チェックリスト、よくあるハマりどころまで1本でまとめました。
最終更新:2026年10月13日 / 対象仕様:MCP 2026-07-28(最新リビジョン) この記事は、MCP(Model Context Protocol)の Streamable HTTP トランスポートについて、仕様・実装・運用・移行の観点から網羅的にまとめたものです。
結論(30秒で読める要約)
- MCP Streamable HTTPとは、MCPサーバーをURL(例:
https://example.com/mcp)で公開するための標準のリモート用トランスポートです。ローカル用のstdioと並ぶ、MCPの2つの標準トランスポートの1つです。 - 2025-03-26版で、旧方式のHTTP+SSE(2024-11-05版)の後継として導入されました。
- 最新の2026-07-28版で大きく変わりました。 セッション(
Mcp-Session-Id)、initializeハンドシェイク、GETによる常設SSEストリーム、Last-Event-IDによる再開がすべて削除され、MCPはステートレスなプロトコルになりました。 - 現在のStreamable HTTPは「1メッセージ = 1回のPOST。レスポンスは
application/jsonか、そのリクエスト専用のtext/event-stream(SSE)」というシンプルな形です。 - POSTには
MCP-Protocol-Version・Mcp-Method・Mcp-Nameなどのヘッダーが必須になり、ロードバランサーやゲートウェイがボディを読まずにルーティングできるようになりました。 - 2025年にStreamable HTTPへ移行済みのサーバーこそ、2026-07-28対応のための改修が必要です。
目次
- MCPのトランスポートとは
- Streamable HTTPの定義と歴史
- stdio・HTTP+SSE・Streamable HTTPの比較
- 2026-07-28版で何が変わったか
- Streamable HTTPの通信の仕組み
- 必須ヘッダーとヘッダー検証
- SSEストリームとキャンセル・通知
- セキュリティ要件
- 最小実装(Node.js)とcurlでの動作確認
- 2025年版サーバーからの移行チェックリスト
- よくあるハマりどころ
- stdioのMCPサーバーをStreamable HTTPで公開する方法
- よくある質問(FAQ)
1. MCPのトランスポートとは
MCP(Model Context Protocol)は、ClaudeなどのAIアプリケーション(ホスト/クライアント)と、ツールやデータを提供するMCPサーバーをつなぐためのオープンなプロトコルです。メッセージ形式にはJSON-RPC 2.0(UTF-8)が使われます。
トランスポートは、そのJSON-RPCメッセージを「どうやって運ぶか」を定める層です。公式仕様では、トランスポートは「メッセージのフレーミング・配送・メタデータの運び方・キャンセルの伝え方」だけを定義するバインディングであり、メッセージの意味(プロトコルのセマンティクス)はどのトランスポートでも同じとされています。
標準のトランスポートは次の2つです。
| トランスポート | 用途 | 仕組み |
|---|---|---|
| stdio | ローカル | クライアントがサーバーをサブプロセスとして起動し、標準入出力で改行区切りのJSON-RPCをやり取りする |
| Streamable HTTP | リモート | 単一のMCPエンドポイントにHTTP POSTでメッセージを送り、JSONまたはSSEで応答を受け取る |
つまり、「MCPサーバーをインターネット越しに共有・ホスティングしたい」「Webベースのクライアントから使いたい」ならStreamable HTTP一択です。
2. Streamable HTTPの定義と歴史
定義
Streamable HTTPは、MCPサーバーが単一のHTTPエンドポイント(MCPエンドポイント)を公開し、クライアントがJSON-RPCメッセージを1件ずつHTTP POSTで送信するトランスポートです。サーバーは各リクエストに対して、単一のJSONオブジェクトか、そのリクエストに紐づくSSE(Server-Sent Events)ストリームで応答します。
「Streamable(ストリーム可能)」という名前は、必要なときだけ通常のHTTPレスポンスをストリームに格上げできることに由来します。
バージョンごとの変遷
MCPの仕様は日付でバージョン管理されています。Streamable HTTPに関係する主な変遷は次のとおりです。
| 仕様リビジョン | Streamable HTTPまわりの主な出来事 |
|---|---|
| 2024-11-05 | 初期のリモート方式 HTTP+SSE(SSE用エンドポイント+POST用エンドポイントの2本立て) |
| 2025-03-26 | Streamable HTTPが導入され、HTTP+SSEは非推奨に。セッション(Mcp-Session-Id)、GETによる常設SSEストリーム、Last-Event-IDによる再開をサポート |
| 2025-06-18 | MCP-Protocol-Versionヘッダーが定義される |
| 2025-11-25 | 2025年系の最終リビジョン(セッションありのStreamable HTTP) |
| 2026-07-28(最新) | ステートレス化。 セッション・initialize・GETストリーム・ストリーム再開を削除。Mcp-Method/Mcp-Nameヘッダー必須化、server/discover、subscriptions/listen、MRTRを追加。HTTP+SSEは正式に「Deprecated」へ再分類 |
ネット上のStreamable HTTPの解説記事の多くは2025年版(セッションあり)を前提に書かれています。読む前に「どのリビジョン向けの記事か」を必ず確認してください。
3. stdio・HTTP+SSE・Streamable HTTPの比較
| 項目 | stdio | HTTP+SSE(旧・非推奨) | Streamable HTTP(2026-07-28) |
|---|---|---|---|
| 想定 | ローカル | リモート | リモート |
| エンドポイント数 | なし(プロセス) | 2本(SSE+POST) | 1本(POSTのみ) |
| 接続の持続 | プロセスの寿命 | 常時SSE接続が必要 | リクエスト単位(常時接続不要) |
| セッション | プロセス単位 | 接続単位 | なし(ステートレス) |
| スケールアウト | 不可 | 難しい(接続の張り付きが必要) | 容易(任意のインスタンスで処理可能) |
| 認証 | 環境変数で資格情報を渡す | 実装依存 | OAuth 2.1ベースの認可フレームワーク |
| 新規採用 | ローカル用途ならOK | 非推奨 | 推奨 |
ポイントは、HTTP+SSEは「常に開いたSSE接続」に依存していたため、サーバーレスやロードバランサー配下での運用が難しかったことです。Streamable HTTPはこれを1本のエンドポイントに集約し、2026-07-28版ではセッションまで捨てたことで、普通のWeb APIと同じ感覚で水平スケールできるようになりました。
4. 2026-07-28版で何が変わったか
公式のchangelogに記載された主要な変更のうち、Streamable HTTPに直接影響するものをまとめます。
4-1. セッションの廃止(SEP-2567)
Mcp-Session-Idヘッダーとプロトコルレベルのセッションが削除されました。tools/listなどの一覧系エンドポイントは接続ごとに変わらなくなります。呼び出しをまたいだ状態が必要な場合は、サーバーが発行したハンドル(ID)を通常のツール引数として受け渡す設計にします。
4-2. initializeハンドシェイクの廃止(SEP-2575)
initialize/notifications/initializedがなくなり、すべてのリクエストが_metaにプロトコルバージョンとクライアント能力(capabilities)を持つようになりました。
io.modelcontextprotocol/protocolVersionio.modelcontextprotocol/clientCapabilitiesio.modelcontextprotocol/clientInfo(SHOULD)
バージョンが合わない場合はUnsupportedProtocolVersionErrorが返ります。
4-3. server/discoverの追加
サーバーはserver/discoverを実装しなければなりません(MUST)。対応バージョン・能力・サーバー情報を返すRPCで、クライアントは最初に呼んでバージョンを選ぶことができます。
4-4. GETストリームの廃止とsubscriptions/listen
従来の「GETで常設SSEストリームを開いてサーバー起点のメッセージを受け取る」方式と、resources/subscribe/resources/unsubscribeが削除されました。代わりに、subscriptions/listenをPOSTし、そのレスポンスのSSEストリームを開いたままにすることで、notifications/tools/list_changedなどの変更通知を受け取ります。
4-5. MRTR(Multi Round-Trip Requests)
サーバーがクライアントにリクエストを送る(sampling・elicitation・roots)方式が廃止され、サーバーはInputRequiredResult(resultType: "input_required")を返し、クライアントがinputResponsesを付けて元のリクエストを再送する方式になりました。すべての結果にresultTypeが必須です。
4-6. ストリーム再開の廃止
Last-Event-IDとSSEイベントIDによる再開・再送がなくなりました。ストリームが切れたらそのリクエストは失われ、クライアントは新しいIDで再送します。
4-7. その他の変更
ping、logging/setLevel、notifications/roots/list_changedを削除(ログレベルはリクエストごとに_metaのio.modelcontextprotocol/logLevelで指定)tools/listなどにttlMsとcacheScopeが必須(キャッシュ用ヒント)tools/listは決定的な順序で返すことを推奨(プロンプトキャッシュのヒット率向上)- エラーコードを再採番:
HeaderMismatchは-32020、MissingRequiredClientCapabilityは-32021、UnsupportedProtocolVersionは-32022 - Roots・Sampling・Logging、Dynamic Client Registration(RFC 7591)が非推奨に
MCPのメンテナー自身も、このリビジョンをこれまでで最も大きな仕様変更と位置づけています。単なるバージョン番号の更新ではないと考えて工数を見積もってください。
5. Streamable HTTPの通信の仕組み
2026-07-28版のStreamable HTTPは、次の4パターンを覚えれば全体像がつかめます。
パターンA:通常のリクエスト(JSONで即応答)
Client → POST /mcp (tools/call)
Server → 200 OK, Content-Type: application/json
{ "jsonrpc": "2.0", "id": 1, "result": { ... } }
パターンB:ストリーミング応答(SSE)
時間のかかる処理では、サーバーはそのリクエスト専用のSSEストリームを開き、進捗通知を流してから最終レスポンスを送ります。
Client → POST /mcp (tools/call)
Server → 200 OK, Content-Type: text/event-stream
event: notifications/progress
event: notifications/progress
event: 最終のJSON-RPCレスポンス → ストリーム終了
パターンC:通知(notification)
Client → POST /mcp (JSON-RPC notification)
Server → 202 Accepted(ボディなし)
パターンD:変更通知の購読(subscriptions/listen)
Client → POST /mcp (subscriptions/listen)
Server → SSE: notifications/subscriptions/acknowledged
(ストリームを開いたまま)
SSE: notifications/tools/list_changed
SSE: notifications/resources/updated
サーバーがユーザー入力やLLMの生成結果を必要とする場合(elicitation・sampling)は、MRTRによりInputRequiredResultを返し、クライアントが入力を集めて元のリクエストを再送します。サーバーが自分からJSON-RPCリクエストを送ることはありません。
6. 必須ヘッダーとヘッダー検証
2026-07-28版の大きな特徴が、ボディの一部をHTTPヘッダーにミラーする仕組みです。これにより、ロードバランサー・APIゲートウェイ・監視ツールがJSONを解析せずにルーティングや計測をできます。
クライアントが付けるヘッダー
| ヘッダー | 内容 | 必要なリクエスト |
|---|---|---|
Accept |
application/jsonとtext/event-streamの両方 |
すべてのPOST |
MCP-Protocol-Version |
例:2026-07-28(ボディの_metaと一致必須) |
すべてのPOST |
Mcp-Method |
JSON-RPCのmethod |
すべてのリクエスト |
Mcp-Name |
params.nameまたはparams.uri |
tools/call、resources/read、prompts/get |
Mcp-Param-{Name} |
x-mcp-headerで指定されたツール引数 |
サーバーが指定した場合 |
リクエスト例
POST /mcp HTTP/1.1
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: get_weather
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "location": "Tokyo" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "ExampleClient", "version": "1.0.0" },
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
サーバー側の検証ルールとステータスコード
| 状況 | サーバーの応答 |
|---|---|
| ヘッダーとボディの値が不一致・必須ヘッダー欠落 | 400 Bad Request + JSON-RPCエラー -32020(HeaderMismatch) |
| 要求されたプロトコルバージョンに非対応 | 400 Bad Request + UnsupportedProtocolVersionError(対応バージョン一覧付き) |
| 未実装のメソッド | 404 Not Found + JSON-RPCエラー -32601 |
| 通知を受理 | 202 Accepted(ボディなし) |
| GET / DELETE が来た | 405 Method Not Allowed |
不正なOrigin |
403 Forbidden |
ヘッダーとボディの不一致を拒否するのはセキュリティのためです。ロードバランサーがヘッダーを、MCPサーバーがボディを信じる構成だと、両者の食い違いを悪用される恐れがあるからです。
日本語のツール名・引数は要注意(Base64エンコード)
HTTPヘッダーには基本的にASCIIしか入れられません。ツール名やリソースURI、Mcp-Param-*の値に日本語などの非ASCII文字・改行・前後の空白が含まれる場合、クライアントは次の形式でBase64エンコードしなければなりません。
Mcp-Name: =?base64?{UTF-8をBase64したもの}?=
サーバーは比較前に必ずデコードします。日本語のツール名を付けているMCPサーバーは、ここでHeaderMismatchを起こしやすいので、ツール名は英数字・_・-にしておくのが無難です。
7. SSEストリームとキャンセル・通知
SSEで送ってよいもの
- そのリクエストに関係する通知(
notifications/progress、notifications/messageなど) - 最終のJSON-RPCレスポンス(これでストリームを閉じるのが推奨)
独立したJSON-RPCリクエストを流してはいけません(2025年版との大きな違い)。
キャンセルは「ストリームを閉じる」だけ
Streamable HTTPでは、クライアントがSSEレスポンスストリームを閉じること自体がキャンセルです。notifications/cancelledは使いません(これはstdio専用)。サーバーはストリームが閉じられたら処理をできるだけ早く止め、そのリクエストについてそれ以上メッセージを送ってはいけません。
プロキシのバッファリング対策
SSEを開始するときは、レスポンスに X-Accel-Buffering: no を付けることが推奨されています。nginxなどのリバースプロキシがSSEをバッファしてしまい、進捗通知がまとめて遅れて届く問題を防げます。
キープアライブ
subscriptions/listenのような長時間ストリームでは、定期的にSSEコメント行(:で始まる行)を送り、中間装置やクライアントのアイドルタイムアウトで切られないようにします。
8. セキュリティ要件
仕様が定めるStreamable HTTPのセキュリティ要件は次の3つです。
Originヘッダーを必ず検証する(MUST)。 不正なOriginには403 Forbiddenを返す。DNSリバインディング攻撃の対策です。- ローカルで動かすときは
127.0.0.1にのみバインドする(SHOULD)。0.0.0.0で待ち受けると、悪意あるWebサイトからローカルのMCPサーバーを操作される恐れがあります。 - すべての接続に適切な認証を実装する(SHOULD)。 リモート公開するならOAuth 2.1ベースの認可フレームワークに従うのが標準です。
2026-07-28版では認可まわりにも変更があり、クライアント登録はClient ID Metadata Documentsが推奨となり、Dynamic Client Registrationは非推奨になりました。また、認可レスポンスのissパラメーター(RFC 9207)を、クライアントが検証する必要があります。
9. 最小実装(Node.js)とcurlでの動作確認
実運用では公式SDKを使うべきですが、仕様の理解のために、SDKなしで2026-07-28版の要点だけを実装した最小サーバーを示します(学習用。server/discoverや各エラーの詳細なスキーマは公式schemaで確認してください)。
// minimal-mcp.mjs — 学習用の最小Streamable HTTPサーバー(2026-07-28想定)
import http from "node:http";
const SUPPORTED = ["2026-07-28"];
const ALLOWED_ORIGINS = new Set(["https://claude.ai"]); // 自分の環境に合わせる
const TOOLS = [{
name: "echo",
description: "Echo back the given text",
inputSchema: { type: "object", properties: { text: { type: "string" } }, required: ["text"] },
}];
const json = (res, status, obj) => {
res.writeHead(status, { "Content-Type": "application/json" });
res.end(JSON.stringify(obj));
};
const err = (id, code, message, data) => ({ jsonrpc: "2.0", id, error: { code, message, data } });
http.createServer(async (req, res) => {
if (req.url !== "/mcp") return json(res, 404, {});
if (req.method !== "POST") { res.writeHead(405, { Allow: "POST" }); return res.end(); }
const origin = req.headers.origin;
if (origin && !ALLOWED_ORIGINS.has(origin)) { res.writeHead(403); return res.end(); }
let raw = "";
for await (const chunk of req) raw += chunk;
const msg = JSON.parse(raw);
// 通知(idなし)は202
if (msg.id === undefined) { res.writeHead(202); return res.end(); }
const meta = msg.params?._meta ?? {};
const version = meta["io.modelcontextprotocol/protocolVersion"];
// ヘッダーとボディの一致検証(HeaderMismatch = -32020)
const needsName = ["tools/call", "resources/read", "prompts/get"].includes(msg.method);
const bodyName = msg.params?.name ?? msg.params?.uri;
if (
req.headers["mcp-protocol-version"] !== version ||
req.headers["mcp-method"] !== msg.method ||
(needsName && req.headers["mcp-name"] !== bodyName) // 本番ではBase64表記のデコードも必要
) {
return json(res, 400, err(msg.id, -32020, "Header mismatch"));
}
if (!SUPPORTED.includes(version)) {
return json(res, 400, err(msg.id, -32022, "Unsupported protocol version", { supported: SUPPORTED }));
}
switch (msg.method) {
case "server/discover":
return json(res, 200, { jsonrpc: "2.0", id: msg.id, result: {
resultType: "complete",
supportedVersions: SUPPORTED, // 正確なフィールド名は公式schemaを参照
capabilities: { tools: {} },
serverInfo: { name: "minimal-mcp", version: "0.1.0" },
}});
case "tools/list":
return json(res, 200, { jsonrpc: "2.0", id: msg.id, result: {
resultType: "complete", tools: TOOLS, ttlMs: 60000, cacheScope: "public",
}});
case "tools/call": {
// SSEで進捗→最終結果を返す例
res.writeHead(200, { "Content-Type": "text/event-stream", "X-Accel-Buffering": "no" });
res.write(`data: ${JSON.stringify({ jsonrpc: "2.0", method: "notifications/progress",
params: { progressToken: meta.progressToken ?? "p1", progress: 50, total: 100 } })}\n\n`);
res.write(`data: ${JSON.stringify({ jsonrpc: "2.0", id: msg.id, result: {
resultType: "complete",
content: [{ type: "text", text: msg.params.arguments.text }],
}})}\n\n`);
return res.end();
}
default:
return json(res, 404, err(msg.id, -32601, "Method not found"));
}
}).listen(3000, "127.0.0.1"); // ローカルは127.0.0.1にバインド
curlで動作確認
curl -N http://127.0.0.1:3000/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: tools/call' \
-H 'Mcp-Name: echo' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","arguments":{"text":"hello"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'
Mcp-Nameをわざとecho2に変えると、400と-32020が返ることを確認できます。
10. 2025年版サーバーからの移行チェックリスト
2025-03-26〜2025-11-25のStreamable HTTPで動いているサーバーを2026-07-28に対応させるときの作業リストです。
トランスポート層
- [ ] GET/DELETEを
405 Method Not Allowedにする - [ ]
Mcp-Session-Idを発行・返却しない(受け取っても無視) - [ ]
Last-Event-IDを無視し、SSEイベントIDによる再開処理を削除 - [ ]
MCP-Protocol-Version・Mcp-Method・Mcp-Nameの検証を追加(不一致は400+-32020) - [ ] Base64表記(
=?base64?...?=)のデコードに対応 - [ ] SSEで独立したリクエストを送っている箇所を削除
- [ ] ストリーム切断をキャンセルとして扱う
プロトコル層
- [ ]
initialize依存のロジックを削除し、各リクエストの_metaからバージョン・能力を読む - [ ]
server/discoverを実装 - [ ] すべての結果に
resultTypeを付与 - [ ]
tools/listなどにttlMs・cacheScopeを付与し、順序を固定 - [ ] sampling/elicitation/rootsをMRTR(
InputRequiredResult)に置き換え - [ ]
resources/subscribeをsubscriptions/listenに置き換え - [ ]
ping・logging/setLevelへの依存を削除 - [ ] エラーコードの再採番(-32001→-32020 など)に追従
状態管理
- [ ] セッションに保存していた状態を洗い出し、「サーバー発行のハンドルをツール引数で受け渡す」設計に変更
- [ ] 外部ストア(Redis・DBなど)に状態を移す
互換性
- [ ] 旧クライアントも受けるなら、
MCP-Protocol-Versionなしのリクエストを2025-03-26として扱うか判断 - [ ] 旧版の挙動も残す場合は、旧リビジョンの仕様に沿った分岐を用意
公式SDKのベータ版はリリース前から提供されており、SDKで作ったサーバーならトランスポート層の変更の多くはSDK側が吸収してくれます。まずSDKを最新に上げ、残ったプロトコル層と状態管理を手で直すのが最短ルートです。
11. よくあるハマりどころ
「SSEの進捗が最後にまとめて届く」
リバースプロキシのバッファリングが原因です。X-Accel-Buffering: noを付ける、nginxならproxy_buffering off;を設定します。CDNやAPIゲートウェイ側でもストリーミングを許可してください。
「長いツール実行が途中で切れる」
ロードバランサーのアイドルタイムアウトです。SSEのコメント行でキープアライブを送るか、タイムアウトを延ばします。2026-07-28版ではストリームが切れるとリクエストごと失われるので、重い処理はio.modelcontextprotocol/tasks拡張のような非同期パターンも検討します。
「406や400が返ってクライアントがつながらない」
Acceptヘッダーにapplication/jsonとtext/event-streamの両方が入っていないケースが多いです。自作クライアントやテスト用のcurlで忘れがちです。
「スケールアウトしたら壊れた」
2025年版では、セッションがインスタンスのメモリにあるため、Mcp-Session-Idによるスティッキールーティングが必要でした。2026-07-28版ではセッション自体がないため、状態を外部化すればどのインスタンスでも処理できます。逆に言えば、旧版のサーバーを複数台で動かすならセッションアフィニティが必須です。
「ローカルで動かしたら外部から叩かれた」
0.0.0.0でリッスンしているのが原因です。ローカル用途は127.0.0.1にバインドし、Origin検証を必ず入れます。
「日本語名のツールだけ呼べない」
6章のBase64エンコードの問題です。ツール名は英数字にするのが安全です。
12. stdioのMCPサーバーをStreamable HTTPで公開する方法
GitHubで公開されているMCPサーバーの多くは、いまだにstdioのみ対応です。これをClaudeのカスタムコネクタやWebベースのエージェントから使うには、Streamable HTTPのエンドポイントとして公開する必要があります。
主な方法は3つです。
| 方法 | 向いている人 | 注意点 |
|---|---|---|
| SDKでHTTPトランスポートを追加し、自前でデプロイ | サーバーのコードを書き換えられる人 | 認証・TLS・スケーリング・2026-07-28対応を自分で面倒を見る |
| stdio→HTTPのプロキシ/ラッパーを自前で運用 | コードを触らずに公開したい人 | プロセス管理・マルチテナントの分離・ヘッダー検証を自分で作る必要がある |
| MCPホスティングサービスを使う | すぐ使いたい人・運用したくない人 | 対応している仕様リビジョンやリージョンを確認する |
NodeFlareは、stdioベースの既存MCPサーバーをコードを変更せずにリモートのStreamable HTTPエンドポイントに変換してホスティングするPaaSです。Fly.ioのFirecracker microVM上でサーバーごとに分離して動かすため、安全性とコールドスタートの速さを両立できます。GitHubのURLを指定するだけで、ClaudeなどのクライアントにそのままつなげるURLが手に入ります。
13. よくある質問(FAQ)
Q. MCPのStreamable HTTPとは何ですか?
A. MCPサーバーをURLで公開するための標準のリモート用トランスポートです。クライアントは単一のエンドポイントにJSON-RPCメッセージをHTTP POSTで送り、サーバーはJSONまたはそのリクエスト専用のSSEストリームで応答します。
Q. Streamable HTTPとSSE(HTTP+SSE)の違いは?
A. HTTP+SSEは2024-11-05版の旧方式で、SSE用とPOST用の2つのエンドポイントと、常時開いたSSE接続が必要でした。Streamable HTTPはエンドポイントを1つに統合し、必要なときだけレスポンスをSSEに格上げします。HTTP+SSEは2025-03-26版から非推奨で、2026-07-28版で正式に「Deprecated」に分類されました。
Q. HTTP+SSEのサーバーはもう使えないのですか?
A. 2026年10月時点では、すぐに使えなくなるわけではありません。仕様上はまだ削除されておらず、ClaudeやOpenAIのAPIも旧方式を受け付けています。ただし将来のリビジョンで削除対象になり得るため、新規実装では採用せず、既存のものは移行を計画すべきです。
Q. Streamable HTTPとstdioはどちらを使うべき?
A. 自分のPCだけで使うローカルツールならstdio、チームで共有する・ホスティングする・Webベースのクライアントから使うならStreamable HTTPです。
Q. Mcp-Session-Idはまだ使えますか?
A. 2026-07-28版では削除されました。最新版のみをサポートするサーバーは、このヘッダーを受け取っても無視し、発行も返却もしません。2025年版のクライアントと互換性を保つ場合のみ、旧仕様の挙動を残します。
Q. Streamable HTTPでサーバーからクライアントに通知を送るには?
A. リクエストに関係する進捗やログは、そのリクエストのSSEレスポンスで送ります。ツール一覧の変更などの通知は、クライアントがsubscriptions/listenで開いた長時間ストリームで送ります。GETによる常設ストリームは廃止されました。
Q. Streamable HTTPはサーバーレス(Lambda・Cloud Run・Workersなど)で動きますか?
A. 2026-07-28版はステートレスで1リクエスト=1POSTなので、サーバーレスとの相性は大きく改善しました。ただし、SSEで長時間ストリームを返す場合は、プラットフォームのレスポンスストリーミング対応と最大実行時間を確認してください。
Q. 必須のHTTPヘッダーは何ですか?
A. すべてのPOSTにMCP-Protocol-Version、すべてのリクエストにMcp-Method、tools/call・resources/read・prompts/getにはMcp-Nameが必要です。加えてAccept: application/json, text/event-streamを付けます。
Q. HeaderMismatch(-32020)エラーが出るのはなぜ?
A. HTTPヘッダーの値とJSONボディの値が一致していないか、必須ヘッダーが欠けています。非ASCIIのツール名をBase64エンコードせずに送っている場合や、古いSDKがヘッダーを付けていない場合によく起きます。
Q. Streamable HTTPのMCPサーバーをClaudeにつなぐには?
A. ClaudeのカスタムコネクタにMCPエンドポイントのURL(例:https://example.com/mcp)を登録します。stdioのみのサーバーは、そのままではURLで登録できないため、Streamable HTTPで公開する必要があります。
まとめ
- Streamable HTTPは、MCPサーバーをリモートで公開するための標準トランスポート。
- 2026-07-28版でステートレス化し、セッション・
initialize・GETストリーム・再開が消えた。 - 代わりにヘッダーのミラーリング、
server/discover、subscriptions/listen、MRTRが入り、普通のWeb APIのように水平スケールしやすくなった。 - 2025年版で実装済みのサーバーは、10章のチェックリストで移行する。
- stdioのみのMCPサーバーを手早くURL化したいなら、NodeFlareのようなホスティングを使うのが最短。
