深入解讀 MCP 協議最新版本的 4 大升級【上】:傳輸機制與安全授權
MCP 協議的最新修訂版本(2025-03-26)已經在路上,儘管 SDK 尚未發佈,但規範內容已經基本定型,前期的各種解讀也在網絡上陸續出現。我們將結合官方文檔、Github 上的 PR 與社區討論等,爲大家深入解讀該版本中的四個較大的升級。
-
Streamable HTTP 傳輸模式
-
OAuth2.1 的授權框架
-
JSON-RPC 批處理
-
增強工具註解
我們將分成兩篇進行介紹。
01
Streamable HTTP 傳輸模式
在新版本中,MCP 引入了新的 Streamable HTTP 遠程傳輸機制來代替之前的 HTTP+SSE 的遠程傳輸模式(stdio 的本地模式不變)。
- 背景與動機
當前 MCP 採用的 HTTP+SSE 的遠程傳輸模式總結爲(圖中未涵蓋服務端發送請求如 Sampling 的場景):
-
客戶端首先發送 HTTP Get 請求到服務端 / sse 端點
-
服務端進行響應,建立 SSE 長連接,並返回後續請求的 URI(默認 / messages)
-
客戶端使用此 URI 與服務端交互,發送請求
-
服務端則通過 SSE 連接發送響應消息或通知信息給客戶端
這種方式存在問題有:
-
需要維護兩個獨立的連接端點
-
有較高的連接可靠性要求。一旦 SSE 連接斷開,客戶端無法自動恢復,需要重新建立新連接,導致上下文丟失
-
服務端必須爲每個客戶端維持一個高可用長連接,對可用性和伸縮性提出挑戰
-
強制所有服務端向客戶端的消息都經由 SSE 單向推送,缺乏靈活性。
- 變更說明
最新規範的 Streamable HTTP 傳輸機制總結爲(圖中未涵蓋服務端發送請求如 Sampling 的場景):
這裏的主要變化包括:
-
服務端只需一個統一的 HTTP 端點(如 / messages)用於通信
-
客戶端可以完全無狀態的方式與服務端進行交互,即 Restful HTTP Post 方式
-
必要時客戶端也可以在單次請求中獲得 SSE 方式響應,比如:一個需要進度通知的長時間運行的任務,可以藉助 SSE 不斷推送進度
-
客戶端也可以通過 HTTP Get 請求來打開一個長連接的 SSE 流,這種方式與當前的 HTTP+SSE 模式類似;但這個 SSE 長連接主要用於後續的服務端向客戶端推送通知或發起服務端的請求(比如 Sampling 請求)
-
增強的 Session 管理。服務端會在初始化時返回 Mcp-Session-Id,後續客戶端在每次請求中需要攜帶該 MCP-Session-Id。這個 Mcp-Session-Id 作用是:
-
用來關聯一次會話的多次交互。
-
服務端可以用 Session-Id 來終止會話,要求客戶端開啓新會話
-
客戶端也可以用 HTTP Delete 請求來終止會話
StreamableHTTP 在舊方案的基礎上,提升了傳輸層的靈活性與健壯性:
-
允許無狀態的服務端存在,不依賴長連接。有更好的部署靈活性與擴展能力
-
對服務端中間件的兼容性更好,只需要支持 HTTP 即可,無需做 SSE 處理
-
允許根據自身需要開啓 SSE 響應或長連接,保留了現有規範 SSE 模式的優勢
- 影響與應用
新的應用客戶端必須設置 Accept 頭支持兩種返回類型(application/json 和 text/event-stream),以同時支持服務器返回 JSON 或 SSE 流。如:
POST /mcp HTTP/1.1
Host: mcp.example.com
Accept: application/json, text/event-stream
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
如果不要求流式輸出,則服務端返回一個 JSON 響應;如果要求流式模式,則響應頭爲 Content-Type: text/event-stream,並以 SSE 事件方式發送一個或多個 JSON-RPC 消息。
客戶端通過以下方式開啓 SSE 的長連接,用來接收服務端的異步的消息推送:
GET /mcp HTTP/1.1
Host: mcp.example.com
Accept: text/event-stream
此外,爲了實現兼容性,你需要小心的控制客戶端與服務端應用對連接方式的支持,以兼容舊版本的對端。具體我們將在 SDK 升級後進行解析。
02
引入基於 OAuth 2.1 的授權框架
MCP 2025-03-26 規範引入了基於 OAuth 2.1 的授權框架,爲基於 HTTP 交互的客戶端與服務端提供了標準化的安全機制。當然,這種機制僅適用於遠程模式,對於通過標準輸入輸出(stdio)傳輸的交互則無需考慮此規範。
如果你對 OAuth 流程毫無概念,參考文後方法獲得一個極簡的例子代碼。
- 背景與動機
目前的大多數 MCP 應用採用基於 stdio 的本地傳輸模式,部署幾乎是一對一的,安全邊界清晰。但在基於 SSE 傳輸模式的遠程 MCP 服務端場景中,尤其是隨着第三方 MCP 共享服務的迅速增長,缺少統一的授權機制導致無法安全地管理對服務端功能的訪問權限。引入 OAuth 2.1 可以使資源所有者通過標準的授權流程安全地控制訪問權限。
例如, 在企業環境中,一個 MCP 服務端可能連接內部數據庫或敏感 API,通過 OAuth2.1 授權,可以確保只有經過用戶同意的 MCP 客戶端才能訪問這些資源。這使構建安全的 AI 智能體成爲可能:用戶可隨時撤銷授權令牌,終止其對數據的訪問。此外,由於使用標準 OAuth 流程,企業開發者可以方便地將現有企業的身份認證與授權服務整合到 MCP 服務器中。
- 變更說明
若選擇遵循 MCP 新規範中的 OAuth2.1 授權流程,MCP 客戶端在向服務端的受限資源發起請求之前,必須先通過瀏覽器引導用戶授權訪問 MCP 服務端,完成 OAuth 授權流程以獲取訪問的安全令牌(Access Token)。隨後,客戶端需攜帶此令牌訪問 MCP 服務端;若服務器返回未授權響應,並提示客戶端啓動授權流程。
此外,規範建議 MCP 服務端支持 OAuth 動態客戶端註冊和授權服務器元數據發現,以便客戶端能夠自動獲取服務器的授權端點信息。
整體授權流程描述如下圖:
【角色定義】
-
瀏覽器:用戶所使用的網絡瀏覽器,用於實現交互式授權。
-
MCP 客戶端(例如智能體、ChatBot):需要調用 MCP 服務端功能的應用程序。
-
MCP 服務端(同時擔任 OAuth 授權服務器的角色):既是受保護資源的服務器端,也是 OAuth 認證授權的服務器。
【流程描述】
(1) 客戶端發現授權服務器的元數據
客戶端訪問標準路徑(一般爲. well-known/oauth-authorization-server),希望自動發現服務器的授權端點、令牌端點等元數據。這不是一種必須實現的服務端機制,所以有兩種可能的返回結果:
-
[Server Supports Discovery]:服務器返回標準的元數據信息(通常是一個 JSON,裏面有 authorization_endpoint、token_endpoint 等地址)。
-
[No Discovery]:如果服務器返回 404,客戶端按默認配置繼續,相當於 MCP 服務端直接告訴客戶端:“我沒有實現發現機制,請自己配置好端點地址”。
(2) 動態客戶端註冊(可選)
在調用授權服務的過程中,需提供一個 client_id(比如調用 Google 的 OAuth 授權服務,需要在後臺創建獲得 client_id)。若 MCP 服務端支持動態客戶端註冊,客戶端無需預先註冊,即可在運行時直接向 MCP 服務端進行註冊,從而獲得一組新的 client_id、client_secret 以及其他授權配置信息。
如果您的 MCP 服務可能擁有衆多客戶端應用,建議實現動態客戶端註冊機制。
(3) 客戶端準備授權請求(包含 PKCE 參數)
PKCE(Proof Key for Code Exchange)是 OAuth 2.1 強制要求的保護機制,旨在防範 “授權碼被攔截盜用” 的攻擊。它涉及一組 PKCE 參數,包括:
-
code_verifier(一串隨機字符串)
-
code_challenge(基於 code_verifier 進行編碼生成)
在授權過程中,客戶端會攜帶 code_challenge 以獲取授權碼;在使用授權碼交換安全令牌時,客戶端再提供 code_verifier。授權服務器將驗證 code_verifier 與先前的 code_challenge 是否匹配,只有在匹配的情況下,纔會發放令牌,從而有效防止授權碼被劫持。
(4) 啓動瀏覽器,進行用戶授權
客戶端打開系統瀏覽器,跳轉到 MCP 服務端的授權地址。並帶上這些信息:client_id、redirect_uri、response_type=code、scope、code_challenge 等。此時瀏覽器界面顯示讓用戶確認授權,比如 “授權 MCP xxx 訪問你的 MCP 服務資源”。
(5) 用戶同意授權
用戶在瀏覽器上點擊 “允許授權”(也可能需要額外的輸入驗證信息)。
(6) 服務端驗證並生成授權碼
此時服務端驗證用戶身份與授權請求是否合法,如果用戶同意授權,就生成一個臨時的授權碼(code)。
(7) 授權碼回調到客戶端
MCP 服務端通過瀏覽器重定向到 MCP 客戶端前面提供的重定向 URI(redirect_uri),並在參數中附帶授權碼 code=xxx。
(8) 客戶端接收回調
客戶端捕獲這個回調請求,拿到授權碼;並使用授權碼訪問 MCP 服務端的令牌頒發的端點,換取訪問令牌(Access Token),一般需要帶上 code,code_verifier,client_id 等信息。MCP 服務端驗證授權碼合法,且 code_verifier 驗證通過,就會下發安全令牌。
(9) 客戶端使用安全令牌調用 MCP 服務端功能
客戶端拿到安全令牌後,正式調用 MCP 服務端的受保護功能。令牌在 HTTP 的請求頭中攜帶即可:
POST /mcp
Authorization: Bearer {access_token}
Content-Type: application/json
接着就可以發起 MCP 調用,比如 tool/call、resource/fetch 等。
- 影響和應用
-
老版本 MCP 客戶端 / 服務器如果不實現授權,默認仍可在不需要認證的環境下正常通信,因爲授權是可選的。
-
規範明確僅在 HTTP 傳輸下推薦 OAuth 授權,本地 stdio 模式下的行爲不被影響。
-
不支持 OAuth 的舊客戶端仍可連接不要求認證的新版服務器。然而,如果新版服務器開啓了授權要求,此時需要客戶端升級以實現 OAuth 流程。
總體而言,OAuth 授權框架的加入對原有功能不造成破壞,但要求在需要安全接入的場景下,客戶端和服務器都進行相應升級來配合這一流程。
我們將在下篇接着介紹另外兩項 MCP 協議升級:批處理與工具註解。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/ip2d62wFzQj51uaRORvflw