Skip to content

MCP Specification · 2026-07-28 · zh-TW

Streamable HTTP

Streamable HTTP Transport

以單一 MCP POST endpoint、request-scoped SSE 與嚴格 header/body validation 傳遞 MCP message。

Streamable HTTP 最早在協定版本 2025-03-26 引入,用來取代 2024-11-05 的 HTTP+SSE transport。

2026-07-28 的重要變更

本版移除了 HTTP GET stream endpoint,也移除了 protocol-level sessions。需要同時支援舊版的實作必須依本頁的向後相容規則處理。

在 Streamable HTTP 中,伺服器是可服務多個用戶端連線的獨立程序:

  • 伺服器提供單一 HTTP path,稱為 MCP endpoint,並接受 POST。
  • 用戶端把每一個 JSON-RPC request 或 notification 各自包成新的 HTTP POST。
  • 伺服器對 request 回覆單一 JSON object,或回覆僅屬於該 request 的 Server-Sent Events(SSE)stream;stream 可以先傳 request-related notifications,再傳最終 response。
  • Sampling、Elicitation、Roots 等 server-to-client input 改由 MRTR 的 InputRequiredResult 內嵌。
  • 工具清單、資源等長時間 change notification 由 subscriptions/listen response stream 傳遞。

伺服器 MUST(必須)提供一個支援 POST 的單一 MCP endpoint,例如 https://example.com/mcp

安全性與 endpoint(Security & Endpoint)

實作 Streamable HTTP 時:

  1. 伺服器 MUST(必須)驗證所有 incoming connection 的 Origin header,以避免 DNS rebinding attack。若 Origin 存在但不合法,MUST(必須)回傳 HTTP 403 Forbidden;body MAY(可以)帶一個沒有 id 的 JSON-RPC error response。
  2. 在本機執行的 server SHOULD(應該)只 bind 到 localhost(127.0.0.1),而不是 0.0.0.0
  3. 伺服器 SHOULD(應該)對所有 connection 實作適當的 authentication。

送出訊息(Sending Messages)

用戶端送出的每個 JSON-RPC message MUST(必須)是對 MCP endpoint 的全新 HTTP POST。

  1. 用戶端 MUST(必須)使用 HTTP POST。
  2. Accept header MUST(必須)同時列出 application/jsontext/event-stream
  3. 每個 POST MUST(必須)包含本頁定義的 request metadata headers。
  4. POST body MUST(必須)是單一 JSON-RPC request 或 notification;用戶端 MUST NOT(不得)送出 JSON-RPC response。
  5. 若 body 是 notification,伺服器接受時 MUST(必須)202 Accepted 且沒有 body;無法接受則 MUST(必須)回 HTTP error status,body MAY(可以)是沒有 id 的 JSON-RPC error。
  6. 若 body 是 request,伺服器 MUST(必須)Content-Type: application/json 的單一 JSON object,或 Content-Type: text/event-stream 的 SSE response stream;用戶端 MUST(必須)支援兩種。
本版核心協定的 client-to-server notification

2026-07-28 核心協定本身沒有定義透過 Streamable HTTP 送出的 client-to-server notification。核心協定唯一由用戶端送出的 notifications/cancelled 只用在 stdio;Streamable HTTP 直接以關閉 SSE response stream 表示取消。上面的 notification POST 規則描述 transport mechanics;本版並未另外定義 notification POST 的 metadata header requirements。

接收訊息(Receiving Messages)

當伺服器回傳 Content-Type: text/event-stream 時:

  • 伺服器 MAY(可以)在最終 response 前送出 notifications,例如 notifications/progressnotifications/message;這些通知 MUST(必須)與原始 request 有關。
  • 伺服器 MUST NOT(不得)在 stream 上送出獨立 JSON-RPC request。Sampling、Elicitation、Roots 等互動必須放在 InputRequiredResult,並由 MRTR 處理。
  • 最終 JSON-RPC response SHOULD(應該)結束該 stream。

長時間 notification stream 由 subscriptions/listen 建立。該 request 的 response 本身就是保持開啟的 SSE stream,只傳用戶端明確訂閱的 change notifications。像 notifications/progress 這種 request-scoped notification 不會被放到 listen stream,而只會出現在其所屬 request 的 response stream。

開始 SSE stream 時,伺服器 SHOULD(應該)回傳 X-Accel-Buffering: no,以要求 nginx 等 reverse proxy 關閉 response buffering,避免即時事件被累積後才送出。

對長時間沒有事件的 stream,尤其是 subscriptions/listen,伺服器可定期送出 SSE comment line(例如 :\r\n)作為 keep-alive。用戶端必須忽略 SSE comment,不應把它視為 malformed input。

2026-07-28 不支援Last-Event-ID 恢復 SSE stream。

訊息流程(Message Flow)

請求與回應(Request / response)

  1. 用戶端 POST 一個 request,例如 tools/call
  2. 伺服器可以直接回 200 application/json 的 JSON-RPC response;或回 SSE stream。
  3. 若是 SSE,伺服器可先傳 progress 等 request-scoped notifications,再傳 JSON-RPC response,之後關閉 stream。

伺服器向用戶端取得輸入(Server-to-client input, MRTR)

伺服器需要使用者輸入、LLM completion 或 Roots 時,不會建立自己的 JSON-RPC request。它會回 InputRequiredResult,帶上 inputRequests;用戶端取得輸入後,以新的 JSON-RPC id 重送原始 request,並附上 inputResponses

變更通知(Change notifications)

用戶端 POST subscriptions/listen 與 notification filter;伺服器回 SSE stream,先傳 notifications/subscriptions/acknowledged,之後持續傳送獲准的 change notifications,直到任一方關閉 stream。

取消(Cancellation)

用戶端關閉某個 request 的 SSE response stream 時,伺服器 MUST(必須)把它視為取消該 request。因為每個 request 都有自己的 response stream,disconnect 的對應關係沒有歧義。

伺服器 SHOULD(應該)盡快停止工作,並 MUST NOT(不得)再為該 request 送出後續訊息。

請求中繼資料(Request metadata)

Streamable HTTP 會把 selected JSON-RPC body fields 鏡射成 HTTP headers,讓 load balancer、gateway 或 observability tooling 不必解析 body 即可 routing 或 inspection。Body 仍是 source of truth。

協定版本 header(Protocol version header)

每個送到 MCP endpoint 的 POST MUST(必須)包含 MCP-Protocol-Version

MCP-Protocol-Version: 2026-07-28

Header value MUST(必須)與 request body 中 _meta.io.modelcontextprotocol/protocolVersion 完全一致。若不一致,伺服器 MUST(必須)400 Bad RequestHeaderMismatch JSON-RPC error 拒絕。

若伺服器不支援要求的協定版本,MUST(必須)400 Bad RequestUnsupportedProtocolVersionError,並列出可支援版本。

若協定版本有效但 RPC method 不存在,伺服器 MUST(必須)404 Not Found,並在 JSON-RPC error 使用 -32601(Method not found)。這個 JSON-RPC body 可用來和 Legacy HTTP+SSE server 的普通 404 做區分。

若伺服器仍要相容於早於 2025-06-18、尚未定義 MCP-Protocol-Version header 的 client,MAY(可以)把缺少 header 的 request 視為 2025-03-26;不支援這類 client 的 server 則 MUST(必須)拒絕。

標準請求 headers(Standard request headers)

Header來源欄位需要的 request
Mcp-Methodmethod所有 request
Mcp-Nameparams.nameparams.uritools/callresources/readprompts/get

這些 headers 對符合 2026-07-28 的 Streamable HTTP 實作是 REQUIRED(必須)的。

如果 Mcp-Name 的來源值不能安全表示為 plain ASCII header value,用戶端 MUST(必須)使用下方定義的 Base64 sentinel encoding。

POST /mcp HTTP/1.1
Content-Type: application/json
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": "Taipei" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

由工具參數產生自訂 headers(Custom headers from tool parameters)

MCP server MAY(可以)在 tool 的 inputSchema 中,使用 x-mcp-header extension property 指定某些參數要鏡射成 HTTP header。伺服器是否使用這個功能是選用的,但 Streamable HTTP client MUST(必須)支援它;當 tool definition 含有 x-mcp-header annotation 時,符合規範的 client MUST(必須)把指定參數值鏡射到對應 HTTP header。

被指定的 header 形式為:

Mcp-Param-{Name}: {Value}

Schema extension 約束

x-mcp-header value:

  • MUST NOT(不得)為空字串。
  • MUST(必須)符合 HTTP field-name token syntax(RFC 9110 1*tchar)。
  • MUST NOT(不得)包含 control character,包括 CR 或 LF。
  • 在同一 inputSchema 中,以 case-insensitive 比較時 MUST(必須)唯一。
  • MUST(必須)只套用在 integer、string、boolean primitive;number 不允許。Integer 必須落在 JavaScript safe integer range(−253+1 到 253−1)。
  • MUST(必須)只出現在從 schema root 透過連續 properties 可靜態到達的 property;路徑不得穿越 items 或其他 array keyword、oneOfanyOfallOfnotif/then/else$ref。只要每一層都經由 properties,nested object property 可以使用。

取值時,client 會沿著被註記 property 的精確 properties path 從 call arguments 讀取 instance value;該 path 沒有 value 時就省略 header。

Streamable HTTP client MUST(必須)拒絕任何包含無效 x-mcp-header 的 tool definition,亦即從 tools/list 結果中排除該 tool;client SHOULD(應該)記錄包含 tool name 與原因的 warning。stdio 等其他 transport MAY(可以)完全忽略這些 annotation。

值編碼(Value encoding)

Client 在把參數放入 HTTP header 前 MUST(必須)先安全編碼:

  • string:使用原字串。
  • integer:轉為十進位字串。
  • boolean:轉為小寫 truefalse

依 RFC 9110,普通 HTTP header field value 可使用 visible ASCII(0x21–0x7E)、space(0x20)與 horizontal tab(0x09)。如果 value 不能安全表示為 plain ASCII header value,例如含非 ASCII、control character 或前後空白,client MUST(必須)把 UTF-8 bytes 做 Base64,使用固定 sentinel:

Mcp-Param-{Name}: =?base64?{Base64EncodedValue}?=

Mcp-Name 遵循完全相同的 encoding rule。=?base64??= 大小寫敏感,MUST(必須)精確使用這個形式。需要檢查這些值的伺服器與 intermediary MUST(必須)正確 decode;特別是伺服器在比較 header 與 body 前 MUST(必須)先 decode。

為避免歧義,即使是 plain ASCII,如果字串本身剛好以 =?base64? 開頭並以 ?= 結尾,client 也 MUST(必須)再次 Base64 encode。

原值原因Header value
us-west1Plain ASCIIus-west1
Hello, 世界非 ASCII=?base64?SGVsbG8sIOS4lueVjA==?=
padded 前後空白=?base64?IHBhZGRlZCA=?=

用戶端行為(Client behavior)

透過 HTTP 建立 tools/call 時,client MUST(必須)

  1. 從 body 取出標準 header 來源,例如 methodparams.nameparams.uri
  2. 加入 Mcp-Method,並在適用時加入 Mcp-Name
  3. 檢查該 tool 的 inputSchema,找出 x-mcp-header property,沿 exact property path 取值;該 path 沒有值時省略 header。
  4. 依 value encoding 規則編碼。
  5. 加入相對應的 Mcp-Param-{Name} header。

若 server 因缺少或不一致的 Mcp-Param-* 而回 HeaderMismatch,client SHOULD(應該)重新呼叫 tools/list,確認 tool schema 是否變更,再用正確 headers 重試。

伺服器與中介元件行為(Server and intermediary behavior)

不認得某個 Mcp-Param-{Name} 的 intermediary MUST(必須)轉送它並忽略其語意。Server MUST(必須)拒絕含無效字元的 recognized Mcp-Param-{Name}

任何有解析 body 的 server MUST(必須)驗證 header value(必要時 Base64 decode 後)與 body 中對應 value 相同;任何驗證失敗都 MUST(必須)以 HTTP 400 Bad Request 與 JSON-RPC -32020 HeaderMismatch 拒絕。

情境ClientServer
參數有值MUST 帶 headerMUST 驗證 header 與 body
參數為 nullMUST 省略 headerMUST NOT 要求 header
arguments 沒有參數MUST 省略 headerMUST NOT 要求 header
body 有值但 client 漏 header不符合規範MUST 拒絕

大小寫(Case Sensitivity)

HTTP header field names 不分大小寫;client 與 server MUST(必須)以 case-insensitive 方式比較 header names。Header values,例如 method name,則區分大小寫。

伺服器驗證(Server validation)

任何處理 request body 的 server MUST(必須)拒絕 header 與 body 對應值不一致的 request。這避免網路中不同元件依不同 source of truth 做 routing、policy 或 execution 所造成的安全問題。

Integer parameter 比較時,server SHOULD(應該)以數值比較,而非單純字串比較,例如 42.042 可視為相等。

Header validation failure 時:

  • HTTP status MUST(必須)400 Bad Request
  • JSON-RPC error code MUST(必須)-32020,名稱為 HeaderMismatch
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32020,
    "message": "Header mismatch"
  }
}

典型 failure 包括:缺少必需的 MCP-Protocol-VersionMcp-MethodMcp-Name;header value 與 body 不一致;對允許 Base64 sentinel encoding 的 Mcp-NameMcp-Param-{Name},server MUST(必須)先 decode 再比較;或 header 含不合法字元。

若 intermediary 自己執行 mirrored-header validation 而驗證失敗,MUST(必須)回傳適當的 HTTP error status(例如 400 Bad Request);intermediary 不必另外產生 JSON-RPC error response。

Intermediate component 若依 mirrored headers 實施 routing、rate limiting 等 policy,SHOULD(應該)先確認 MCP-Protocol-Version 指向一個要求 header/body validation 的版本;若版本較舊或 header 缺失,應拒絕,而不是信任未驗證的 header。

向後相容(Backward Compatibility)

同時支援 Modern 與 Legacy MCP 的 client MAY(可以)先嘗試 Modern POST。若收到 400 Bad RequestSHOULD(應該)先檢查 response body,而不是立刻 fallback:

  • 若 body 是已知 Modern JSON-RPC error,例如 unsupported version、missing capability 或 header validation error,表示 server 是 Modern;應修正 request 或改用 server 支援的 version。
  • 若 body 是空的,或不是已知 Modern JSON-RPC error,才 fallback 到 initialize 並改用 Legacy 行為。

較早的 Streamable HTTP revision

2025-03-262025-11-25 也使用 Streamable HTTP,但型態不同:server 可以用 Mcp-Session-Id 建 session、client 可以 HTTP GET 開獨立 SSE stream、server 可以在 SSE 上主動送 JSON-RPC request,而且可用 Last-Event-ID resume stream。這些機制都不屬於 2026-07-28。

只支援 2026-07-28 的 server 收到舊型態 traffic 時 SHOULD(應該)

  • 對 MCP endpoint 的 HTTP GET 或 DELETE 回 405 Method Not Allowed
  • 忽略 incoming Mcp-Session-Id,且不要建立或 echo session ID。
  • 忽略 Last-Event-ID,因為本版 stream 不可 resume。

若 server / client 需要和這些較早的 Streamable HTTP revision 互通,除了上述 version-negotiation fallback 外,還必須實作對應 revision 所定義的 transport 行為。

HTTP+SSE(2024-11-05)

Deprecated

HTTP+SSE 自 2025-03-26 起已 deprecated。新實作 SHOULD NOT(不應)採用;既有實作 SHOULD(應該)遷移到 Streamable HTTP。

需要相容 HTTP+SSE 的 server 可同時保留舊 SSE/POST endpoints 與新的 MCP endpoint。Client 則可先嘗試 Modern POST;只有在收到 400404405,而 response body 又不是已知 Modern JSON-RPC error 時,才改用 GET 嘗試舊 HTTP+SSE 的 endpoint event 流程。