症狀 → 多實例下工具列表變更沒有抵達持續連線的 Client;最快解法是先確認事件是否跨程序送達,再決定是否加入通知總線。
選擇 → 同一執行環境先用記憶體通知;發布者與訂閱流分離時,才使用跨進程分發,並把斷線恢復交給 Client 重新訂閱與重讀資料。
這篇適合正在實作動態 tools、resources 或 prompts 列表的 Server 開發者,也適合讓多個實例共同承載長連線通知流的平台工程師。若你負責 Agent 的斷線恢復、快取失效和相容性測試,下面的部署矩陣可以直接用來定位責任邊界。
最後更新於 2026 年 9 月 5 日;資料核實自 MCP 2026-07-28 正式規範、官方 Python/Ruby SDK 文件及 Streamable HTTP 傳輸說明。
先釐清 subscriptions/listen 的責任邊界
截至 2026 年 9 月 5 日,subscriptions/listen 屬於 MCP 2026-07-28 已確認的通知流機制;正式變更說明可見 MCP 2026-07-28 變更紀錄。但這不代表所有 SDK 的輔助 API、事件保存方式或重放行為都完全一致。Python SDK 的 Client 訂閱文件與 Server 端訂閱文件,應分開閱讀,不能只用其中一套實作推論整個協議。
你要把三件事拆開:
- 變化信號:告知 Client「工具、資源或提示詞可能變了」。
- 事實資料讀取:Client 收到信號後,重新取得工具列表、資源狀態或提示詞內容。
- 持久事件日誌:保存事件,讓稍後重新連線的 Client 依序補回遺漏事件。
subscriptions/listen 解決的是前兩者之間的通知通道,不應被當成持久事件日誌。換句話說,通知抵達不等於資料已自動同步;通知遺失時,也不能假設協議會補發所有中間事件。
MCP 通知流是否一定需要訊息佇列?
不一定。只要事件發布者和持有訂閱連線的程式位於同一個執行環境,記憶體中的訂閱集合與事件分派就足以完成最小鏈路。訊息佇列或其他通知總線只有在事件需要跨程序、跨容器或跨節點抵達時才成為必要的架構元件。
單進程開發者的最小通知鏈路
單進程不是「功能不完整」,而是把故障範圍限制在一個執行環境內。你可以先建立一個事件發佈器、訂閱連線集合,以及按事件類型過濾的分派函式:
- Server 啟動時建立記憶體內的訂閱註冊表。
- Client 完成
subscriptions/listen後,記錄連線與訂閱的資源或列表類型。 - 工具、資源或提示詞變更時,只發出對應類型的變化信號。
- Server 清理取消、逾時或已關閉的連線,避免註冊表持續累積。
- Client 收到信號後,重新讀取依賴資料,再更新本地快取。
在這個階段,驗收重點不是先安裝外部訊息系統,而是確認訂閱確認、事件過濾、取消連線和重新讀取都有效。Python SDK 的 Server 端訂閱處理文件可作為實作對照,但仍要按你使用的 SDK 版本測試。
單進程最常見的隱性成本,是開發者把「通知已送出」誤當成「Client 狀態已一致」。如果事件只是提示列表變化,Client 仍須主動重新取得完整列表;若你的產品需要逐事件追蹤、稽核或嚴格順序,就已經進入事件日誌問題,而不是單純的 subscriptions/listen 問題。
多 Worker 團隊的跨程序驗證
Web Worker、程序池或請求型執行環境會引入一個關鍵分離:發布變更的 Worker,未必是持有 Streamable HTTP 長連線的 Worker。此時,發布者在 A 程序內呼叫通知函式,並不代表 B 程序的訂閱流能看見它。
subscriptions/listen 多實例為什麼收不到通知?
通常不是單一原因。可能是事件只進入 A 程序的記憶體總線,也可能被反向代理導向不同程序,還可能是 Client 收到流中斷後沒有重新建立訂閱。你應用一個帶有實例識別碼的測試事件,沿途記錄:
- 事件在哪個程序產生;
- 哪個程序持有訂閱流;
- 跨程序通知總線是否收到與轉發;
- 反向代理是否保持原本的長連線;
- Client 是否收到信號並重新讀取資料。
只有完成這條追蹤鏈,你才知道遺失點在應用總線、代理伺服器,還是 Client。不要一看到多 Worker 就直接引入功能很重的訊息平台;先用可觀測的測試事件證明「發布者與流持有者確實分離」。
多實例平台的共享通知路徑
在負載平衡環境中,任一實例都可能接收工具變更,而訂閱流則由另一個實例持有。這時需要共享通知路徑,讓變更信號可以從發布實例抵達所有相關的流持有者。這個共享元件可以是團隊現有的內部通知總線,但其責任是跨實例分發,不是自動替你保存完整事件歷史。
部署時應明確分層:
- 應用資料層保存目前有效的工具、資源或提示詞狀態。
- 通知總線只負責把「狀態可能變更」送到其他實例。
- Client收到信號後重新讀取,並以讀回的狀態更新快取。
- 事件日誌只有在業務需要追蹤每個事件、稽核或精確補償時才另外設計。
因此,即使通知總線成功轉發,仍不能向 Client 承諾「一定補回斷線期間的每一個事件」。這是可靠性邊界,也是多實例設計中最容易被寫錯的地方。
Client 團隊的斷線恢復與舊版相容
subscriptions/listen 斷線後會不會補發事件?
不能作為通用保證。連線遺失後,Client 應建立新的訂閱,再重新讀取工具列表、資源狀態或提示詞資料;如果只重連通知流而不重讀依賴資料,快取可能永遠停留在舊狀態。Python SDK 的 Client 訂閱文件可協助確認目前 API 行為,但仍需以實際 SDK 版本和你的傳輸設定驗收。
舊版 MCP Client 如何接收列表變化?
先做能力探測,不要假設舊 Client 會理解新通知。若 Client 不支援相應訂閱流程,兼容路徑可以是重新讀取完整列表、按需輪詢,或在功能介面中停用即時更新。這會增加讀取成本,但比讓 Client 收到無法處理的通知、卻沒有一致性修復機制更安全。官方 Python SDK 的 版本遷移說明也提醒你,SDK 行為可能隨版本調整,測試矩陣不能只覆蓋 Server。
反向代理與長流運維邊界
反向代理會不會中斷 MCP 通知流?
會,尤其是代理緩衝、閒置逾時、連線上限或滾動更新處理不一致時。Streamable HTTP 使用長時間保持的 HTTP 流;若代理等待足夠資料才轉發,通知可能已在 Server 產生,卻遲遲不到 Client。SSE 的事件格式與連線行為,可參考 MDN 的 Server-Sent Events 說明。
運維驗收至少要涵蓋以下步驟:
- 建立一條真實的 Streamable HTTP 訂閱連線,確認初始回應和後續事件都能抵達。
- 在不同程序發布測試變更,對照發布程序與流持有程序的識別碼。
- 暫停事件一段時間,再發送變更,檢查代理是否因緩衝而延遲傳送。
- 主動關閉連線、重啟 Worker,確認 Client 是否重新訂閱並重讀狀態。
- 執行滾動更新,觀察優雅關閉是否先通知 Client,或直接切斷長流。
- 對照多個 SDK 的行為;Ruby SDK 的 Streamable HTTP 傳輸實作可用來檢查不同語言實作的差異。
若你使用 Uvicorn,應把長連線的程序管理、優雅關閉與逾時設定納入測試,而不是只驗證普通短請求;相關執行參數可參考 Uvicorn 官方設定文件。代理層、執行環境和 Client 三者任何一層不接受長流,通知架構都會表現成「偶爾漏事件」。
按團隊規模選擇部署方案
下面的矩陣將運行形態、通知路徑和故障恢復責任放在一起;評分以部署複雜度、跨程序能力和恢復清晰度綜合判斷,五分代表較適合該場景,不是協議官方評分。
| 運行形態 | 通知路徑 | 適合情境 | 兼容與恢復責任 | 綜合評分 |
|---|---|---|---|---|
| 本地原型、單進程 | 記憶體通知 | 開發工具列表和訂閱流程 | Client 重新讀取;不承諾事件重放 | ★★★★★ |
| 單機生產、單執行環境 | 記憶體通知,搭配長流驗收 | 流量和部署拓撲仍在同一程序 | 驗證取消、重啟與代理逾時 | ★★★★☆ |
| 多 Worker、單節點 | 跨程序通知總線 | 發布者與流持有者可能不同 | 用實例識別碼定位遺失點 | ★★★☆☆ |
| 多節點、負載平衡 | 共享通知總線 | 任一節點都可能產生變更 | Client 重訂閱、重讀;總線不等於事件日誌 | ★★★★☆ |
本地原型不必為了「將來可能多節點」先引入外部元件;單機生產則應把代理與優雅關閉納入驗收。多 Worker 團隊先證明跨程序事件能抵達,再決定總線是否要升級。多節點平台則要把通知、資料讀取和事件保存拆成不同責任,否則故障時很難判斷是哪一層失效。
如果你正準備建立遠端測試節點,可以先查看 SSHMac 的支援中心,再按單進程、多 Worker 或多節點拓撲安排驗收。需要臨時切換測試環境時,也可從 SSHMac 的遠端 Mac 方案入口確認適合你的執行方式;重點是測試真實的長流、代理和重連路徑,而不是只在本機模擬成功。
對大多數團隊而言,最穩妥的次序是先完成單進程最小鏈路,再用實例識別碼驗證跨程序問題,最後才把共享通知總線放進多節點部署。相較於在單機環境維護外部訊息系統,這條路徑更容易定位故障;相較於讓多實例各自使用記憶體通知,也能避免變更只停留在某一個節點。
如果你目前依賴的是單機開發環境,真正的限制通常是無法重現跨節點分發、代理緩衝和滾動更新;若直接使用一般雲端執行環境,還可能遇到 macOS 工具鏈、長連線保活與多節點狀態難以同步等問題。需要臨時算力或隔離測試環境時,租用 SSHMac 的 Mac 環境可以讓你在實際的遠端拓撲中驗證 MCP 通知流;但若你需要長期穩定的重負載、固定硬體介面或永久運行,先自建合適的 Mac 基礎設施通常更合理。