Article · Writing

MCP 如何傳遞訊息?從 JSON-RPC 到目前的無狀態生命週期

MCP 使用 JSON-RPC 2.0 表達請求、回應與通知;但 2026-07-28 之後的生命週期已不再依賴初始化握手,而是讓每個請求自帶版本與能力資訊。

4 分鐘閱讀

Evidence trail

Provenance

這篇內容的 canonical URL 是 /writing/mcp-protocol/,發布日期為 2025年6月21日。

這篇內容也保留在其 Series 關係中;正文不需要依賴前一篇才能閱讀。

相容的歷史路徑:/posts/mcp-protocol/

MCP 如何傳遞訊息?從 JSON-RPC 到目前的無狀態生命週期
文章目錄

為什麼同一個工具呼叫需要一套訊息規則?

上一篇把 Host、Client 和 Server 的責任分開了,但角色分工只有在訊息能被雙方一致解析時才有用。MCP 使用 JSON-RPC 2.0 作為訊息格式:它把一次操作表示成方法名稱和參數,把結果和錯誤放回同一個 request ID,並用沒有 ID 的 notification 傳送不需要回覆的事件。

下面是刻意縮小的 JSON-RPC 例子。它展示訊息骨架,省略了目前 MCP 請求會攜帶的 _meta 協定版本與能力資訊,也省略了可用的身份 metadata(中繼資料),因此不是可以直接送出的完整可傳送訊息。

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "location": "Taipei" }
  }
}

Server 回覆時要使用相同的 ID,成功時放入 result,失敗時放入 error。如果它只是在通知列表變更,訊息不應帶 id,接收方也不會回覆。這些小規則讓 Client 可以把並行中的回應配回正確的請求,而不必靠猜測訊息抵達的順序。

result 不只是「一段文字」

目前規格的結果會帶有 resultType。通常完成的結果是 complete;如果 Server 在完成一次工具、提示或資源操作前還需要 Client 提供輸入,則可以回傳 input_required。Client 回應後再重送原本的操作,並帶上 inputResponses 以及 Server 提供的 requestState

這個多輪往返(Multi Round-Trip Requests,MRTR)模式很重要,因為它把「需要使用者或 Client 輸入」表達成原請求的一部分,而不是讓 Server 在對話之外任意發起一個沒有來源的互動。重送時必須使用新的 JSON-RPC ID;Server 也必須能依照明確的輸入重新處理請求。

目前的生命週期:每個請求自己帶上下文

2026-07-28 版本採用無狀態的核心協定。每個請求都應帶上它使用的協定版本與 Client 能力;Server 不能假設「之前同一條連線收到過什麼」就是這次請求的上下文。如果 Client 想先知道 Server 支援什麼,可以呼叫 server/discover,但它不是建立對話的必要握手。

因此,目前不應把 initialize → initialized 寫成所有 MCP 連線都必經的流程。2025-11-25 及更早的 legacy 版本仍然使用初始化握手,支援兩個世代的實作可以依 Server 的版本選擇對應行為;只是兩種生命週期不能混寫成同一個當代流程。

無狀態也不等於應用永遠沒有狀態。若工具要延續一個購物車或資料庫交易,可以回傳一個 opaque handle(不透露內部結構的識別碼),讓後續 tools/call 把它帶回來。狀態因此由應用資料和請求參數明確承擔,而不是偷偷附著在某個連線或程序上。

Client 會怎麼走過一次操作?

一個簡化的當代流程是:Client 發送帶有版本與能力 metadata 的 JSON-RPC 請求 → Server 回傳 completeinput_required 或錯誤 → 若需要額外輸入,Client 帶著回覆重送原操作 → Host 再決定如何把結果交給模型或使用者。能力清單、工具呼叫、資源讀取和提示取得,都共享這個訊息骨架。

這裡先不把 stdio、Streamable HTTP 或其他傳輸方式混進來。傳輸決定訊息如何抵達,JSON-RPC 和 MCP 規格決定訊息如何表達;下一篇會使用這套骨架比較 Tools、Resources、Prompts,以及一個需要特別標示版本邊界的 Sampling。

來源與版本邊界

訊息格式、resultType、stateless 原則與 JSON-RPC 角色來自 MCP 2026-07-28 Overview;版本相容與 legacy 初始化握手的界線見 Versioning and Compatibility。工具呼叫和 input_required 的具體形狀見 Tools。JSON 範例已明確標示為簡化骨架,不應被當成省略 metadata 後仍可直接傳送的完整請求。