這個 Pull Request (#206) 提出了一個名為 "可流式 HTTP" (Streamable HTTP)的新傳輸協(xié)議,用于替代 MCP (Model Context Protocol) 當(dāng)前使用的 HTTP+SSE 傳輸方式。這是一個重要的技術(shù)改進(jìn),旨在解決現(xiàn)有傳輸方式的一些關(guān)鍵限制,同時保留其優(yōu)勢。
地址:https://github.com/modelcontextprotocol/specification/pull/206
主要變更點
與當(dāng)前的 HTTP+SSE 傳輸相比,新提案做出了以下改變:
1. 移除了?/sse
端點
2. 所有客戶端→服務(wù)器的消息都通過?/message
(或類似)端點傳輸
3. 所有客戶端→服務(wù)器的請求可以被服務(wù)器升級為 SSE,用于發(fā)送通知/請求
4. 服務(wù)器可以選擇建立會話 ID 來維持狀態(tài)
5. 客戶端可以通過向?/message
發(fā)送空 GET 請求來初始化 SSE 流這種方法可以向后兼容實現(xiàn),并允許服務(wù)器在需要時完全無狀態(tài)運行。
解決的問題
當(dāng)前的 HTTP+SSE 傳輸存在以下限制:
- ? 不支持可恢復(fù)性? 要求服務(wù)器維護(hù)高可用性的長連接? 服務(wù)器消息只能通過 SSE 傳遞
新方案的優(yōu)勢
支持無狀態(tài)服務(wù)器?- 不再需要高可用性的長連接
純 HTTP 實現(xiàn)?- MCP 可以在普通 HTTP 服務(wù)器上實現(xiàn),不一定需要 SSE
基礎(chǔ)設(shè)施兼容性?- 因為"只是 HTTP",確保與中間件和基礎(chǔ)設(shè)施兼容
向后兼容?- 這是對當(dāng)前傳輸方式的漸進(jìn)式演進(jìn)
靈活的升級路徑?- 服務(wù)器可以在需要時選擇使用 SSE 進(jìn)行流式響應(yīng)
使用場景示例
無狀態(tài)服務(wù)器
提案支持完全無狀態(tài)的服務(wù)器實現(xiàn),無需支持長連接:
1. 始終確認(rèn)初始化(但無需保留任何狀態(tài))
2. 對任何傳入的?ToolListRequest
用單個?JSON-RPC
響應(yīng)
3. 處理?CallToolRequest
時執(zhí)行工具,等待完成,然后發(fā)送單個?CallToolResponse
作為 HTTP 響應(yīng)體
帶流式處理的無狀態(tài)服務(wù)器
即使是完全無狀態(tài)且不支持長連接的服務(wù)器,在這個設(shè)計中仍然可以利用流式處理:
1. 當(dāng)收到?CallToolRequest
時,服務(wù)器指示響應(yīng)將是 SSE
2. 服務(wù)器開始執(zhí)行工具
3. 工具執(zhí)行過程中,服務(wù)器通過 SSE 發(fā)送任意數(shù)量的?ProgressNotification
4. 工具執(zhí)行完成后,服務(wù)器通過 SSE 發(fā)送?
CallToolResponse
5. 服務(wù)器關(guān)閉 SSE 流
有狀態(tài)服務(wù)器
有狀態(tài)服務(wù)器的實現(xiàn)與現(xiàn)在非常相似,主要區(qū)別是服務(wù)器需要生成會話 ID,客戶端需要在每個請求中傳回該 ID。服務(wù)器可以使用會話 ID 進(jìn)行粘性路由或在消息總線上路由消息。
為什么不使用 WebSocket
團(tuán)隊詳細(xì)討論了將 WebSocket 作為主要遠(yuǎn)程傳輸方式的可能性,但最終決定不采用,原因包括:
-
- 1. 對于"RPC 式"使用場景,WebSocket 會帶來不必要的運營和網(wǎng)絡(luò)開銷2. 在瀏覽器中,無法為 WebSocket 附加頭信息(如
Authorization
- ),且第三方庫無法在瀏覽器中從頭實現(xiàn) WebSocket3. 只有 GET 請求可以透明升級為 WebSocket,這意味著在 POST 端點上需要兩步升級過程,增加復(fù)雜性和延遲
團(tuán)隊也避免將 WebSocket 作為規(guī)范中的額外選項,以限制 MCP 官方指定的傳輸方式數(shù)量,避免客戶端和服務(wù)器之間的組合兼容性問題。
待辦事項
? 將會話 ID 責(zé)任轉(zhuǎn)移到服務(wù)器
? 定義可接受的會話 ID 空間
? 確保中間件/WAF 可以內(nèi)省會話 ID
? 使取消操作明確化
? 要求集中式 SSE GET 用于服務(wù)器→客戶端請求和通知
? 將可恢復(fù)性轉(zhuǎn)換為每個流的概念
? 設(shè)計主動"結(jié)束會話"的方式
? "如果客戶端有認(rèn)證令牌,應(yīng)在每個 MCP 請求中包含它"
后續(xù)工作
- ? 標(biāo)準(zhǔn)化對 JSON-RPC 批處理的支持? 支持流式請求體? 在規(guī)范中加入關(guān)于超時的建議,可能還會制定約定,如"發(fā)出進(jìn)度通知應(yīng)重置默認(rèn)超時"
這個提案是在廣泛社區(qū)討論和反饋的基礎(chǔ)上形成的,表明 MCP 正在積極發(fā)展以滿足更廣泛的使用場景需求。