aire.
·13 分鐘

MCP 2026-07-28 新規格解析:session 沒了之後,你的 MCP server 要改哪些地方

7 月 28 日發布的 MCP 2026-07-28 是這個協定的第五版規格,改的不是功能而是形狀:initialize 握手與 Mcp-Session-Id 一起退場,每個 request 自己帶齊版本與能力,server 因此能放上 serverless 和 edge。同時有四個既有功能被標記棄用。這篇把官方兩篇公告與規格站的變更清單逐條核對,整理成新舊對照表、棄用時間表,以及一份給現有 server 維護者的遷移檢查清單。

收進
本文涉及工具

Model Context Protocol(MCP)在 2026 年 7 月 28 日發布了新版規格,版本號 2026-07-28。這是這個協定的第五版。

這次改的不是功能清單,而是協定的形狀。原本 client 和 server 要先握手、建立一條帶 session 的雙向連線;現在每一個 request 自己帶齊所有必要資訊,送到哪一台機器都能被處理。官方部落格把這件事描述為協定型態的轉變:從雙向而有狀態,走向 request/response 而無狀態。

會動到程式碼的是維護 MCP server 的人。initialize 握手沒了,Mcp-Session-Id 沒了,server 反過來向 client 要東西的那條路換了設計,另外有四個既有功能在同一天被標記為棄用。

這篇把官方兩篇公告和規格站的變更清單逐條核對過,整理成三樣官方文件沒有並排放在一起的東西:新舊規格對照表、棄用時間表,以及一份給現有 server 維護者的遷移檢查清單。如果只想帶走一件事,我會選最後那份清單——規格條文讀完不一定知道自己該動哪裡,那份清單就是為了回答這個問題。

先把版本號的意思講清楚

2026-07-28 看起來像日期,實際上是版本識別碼。

規格站對這個格式的定義寫得很明確:版本識別碼採 YYYY-MM-DD 字串格式,用來標示最後一次做出不向後相容變更的日期。只要改動維持向後相容,版本號就不會前進。所以版本號的數量少於實際更新次數,這是設計上刻意的。

至今共有五個修訂版本:2024-11-052025-03-262025-06-182025-11-252026-07-28。五份文件在規格站上都還開得起來,各自的頁面也自報對應的版本,目前只有最後一個標示為 latest。這一版恰好在同一天發布,所以版本號和發布日期看起來重疊,但它們是兩件事。寫文件或錯誤訊息時值得留意這個差別。

新版的版本協商方式也跟著改了。以前是握手時談好一個版本,之後整條連線都用它;現在每一個 request 都在 _meta 裡自己宣告版本(HTTP 上同時放在 MCP-Protocol-Version header),server 逐一決定接受或拒絕。版本不合時 server 必須回 UnsupportedProtocolVersionError,錯誤內容會列出它支援哪些版本;client 則應該從中挑一個共同支援的版本重送,若雙方沒有相容版本,就把錯誤呈現給使用者。

這次真正動的是什麼:session 沒了

核心改動可以濃縮成一句:協定層的 session 被移除了。

具體來說,initializenotifications/initialized 這組握手退場,Mcp-Session-Id header 一起退場。每個 request 改在 _meta 裡帶 io.modelcontextprotocol/protocolVersionclientCapabilities;client 應該在每個 request 帶上 clientInfo,server 應該在每個回應的 _meta 帶上 serverInfo

取代握手的是一個新的 RPC:server/discover。這裡有個容易讀反的地方:server 必須實作它,但 client 不一定要呼叫它。client 可以直接送出任何請求,遇到版本錯誤再處理;想事先知道對方支援什麼的 client 才需要先問一次。

這麼改的直接後果是官方一直在強調的那句:任何一個 request 都可以落在負載平衡器後面的任何一台 server 實例上,不需要共享儲存。這也是 MCP server 能放上 serverless 和 edge 的原因。

連帶被拿掉的還有幾個小東西:pinglogging/setLevelnotifications/roots/list_changed。log 等級改成每個 request 各自在 _metaio.modelcontextprotocol/logLevel 指定,而且規格明訂 server 不得對沒帶這個欄位的 request 發出 notifications/message

狀態沒有消失,只是換人拿

「無狀態」這三個字很容易被讀成「你的 server 不能有狀態了」,但官方講得很清楚:拿掉協定層的 session,不會強迫你的應用程式變成無狀態。

規格給的替代做法是:如果 server 需要跨呼叫保留狀態,就自己鑄一個明確的 handle,當成普通的 tool 參數回給模型,讓模型下次呼叫時帶回來。官方還補了一句為什麼偏好這樣:這個 handle 是模型看得見的,模型可以自己在不同 tool 之間串接它,而藏在傳輸層裡的 session 狀態做不到。

實作上這代表一件事:原本靠 session id 當作使用者上下文容器的 server,需要重新設計那個容器要放在哪裡。官方在談 SDK 的段落裡自己承認了會有一定的遷移成本,並且點名依賴 session 識別碼的開發者受影響最深——這個評估出自規格作者本人,而非外界的批評。

反向請求也改了:MRTR

有一類需求在無狀態架構下特別彆扭:tool 執行到一半需要回頭問使用者一件事,例如要一個確認、或補一個缺漏的參數。舊做法是 server 主動發請求給 client(elicitation/createsampling/createMessageroots/list),而這需要一條一直開著的雙向串流。

新規格用 Multi Round-Trip Requests(MRTR)取代這一整類互動。流程變成:server 回一個 resultType: "input_required" 的結果,裡面的 inputRequests 說明它還需要什麼;client 把答案放進 inputResponses,重送同一個原始請求。

為了配合這件事,所有回應都新增了一個必填的 resultType 欄位,值是 "complete""input_required"。規格特別交代:如果收到的是舊版 server 送來、沒有這個欄位的結果,client 必須當成 "complete" 處理。

新舊規格逐項對照

把主要差異並排放在一起會清楚很多:

項目 2025-11-25 及之前 2026-07-28
連線建立 initialize / initialized 握手 無握手;每個 request 自帶版本與能力
session Mcp-Session-Id header 移除;跨呼叫狀態改用 server 鑄造的 handle
能力探詢 握手時交換 server/discover;server 必須實作,client 可選呼叫
server 反向請求 server 主動發起,需長連線 MRTR:回 input_required,client 帶答案重送
變更通知 HTTP GET 端點、resources/subscribe subscriptions/listen 單一長連線串流,逐類型加入
HTTP 路由資訊 需解析 JSON body Mcp-MethodMcp-Name header 必填
可快取結果 無快取語意 tools/listprompts/listresources/listresources/readresources/templates/list 必帶 ttlMscacheScope
串流中斷 Last-Event-ID 可續傳重送 移除;client 須以新的 request id 重送
錯誤碼分配 未明文劃分 −32000 至 −32019 實作自訂,−32020 至 −32099 保留給規格

「五個 method」這件事值得展開,因為它的範圍比直覺大:規格點名的是 tools/listprompts/listresources/listresources/readresources/templates/list。其中 resources/read 並不是 list 類方法,只把「清單類回應」補上快取欄位的話會漏掉它。cacheScope 的值是 publicprivate,決定共用的中介層可不可以快取這個回應。

還有一項對維運的人特別有感:tools/list 現在建議回傳確定性的順序。理由不只是好看,而是讓 client 能快取工具清單,並讓上游的 LLM prompt cache 在重新連線後保持穩定。

授權:DCR 要交棒給 CIMD

官方說授權是實作者花最多整合時間的地方,這一版在這條線上做了四件事。

第一,authorization server 應該依 RFC 9207 在授權回應裡帶上 iss,而 client 在兌換 code 之前必須驗證它。官方說明這是為了堵住 authorization server 混淆的漏洞。

第二,client 在動態註冊時必須指定 application_type,避免 OIDC 的 redirect URI 衝突。官方順手回答了一個很多人踩過的坑:如果你的 CLI client 走 OAuth 時拿到 redirect_uri 錯誤,很可能就是因為授權伺服器拒絕了 localhost 導向。

第三,client 憑證綁定發出它的 issuer。憑證必須以 issuer 識別碼為索引儲存,不得換一個 authorization server 繼續用,換了就必須重新註冊。

第四是方向性最強的一項:Dynamic Client Registration(DCR,RFC 7591)正式被棄用,改推 Client ID Metadata Documents(CIMD)。DCR 仍然可用,供尚未支援 CIMD 的授權伺服器向後相容,但官方明講未來版本會移除它。

Apps 和 Tasks 不是新功能,是換了位置

這一點值得單獨拉出來講,因為它很容易被轉述錯。

Tasks 並不是這次新增的能力。它原本以 experimental 的身分放在核心協定裡,這一版把它移出核心、變成官方擴充 io.modelcontextprotocol/tasks,同時重新設計:原本阻塞式的 tasks/result 換成輪詢的 tasks/get,新增 tasks/update 供 client 回送輸入,拿掉 tasks/list,並允許 server 未經逐次請求同意就回傳 task handle。Tasks 由 AWS 貢獻,這一點在兩篇官方公告裡都有具名說明。

MCP Apps 也不是新的,它本來就是既有擴充,識別碼是 io.modelcontextprotocol/ui。真正新的是那個容器:這一版正式確立了版本化的擴充框架,讓 Tasks 和 MCP Apps、Enterprise Managed Authorization(EMA)並列在同一套機制底下。

擴充的協商方式是在 capabilities 的 extensions map 裡宣告。如果一方支援某個擴充而另一方不支援,支援的那一方必須退回核心行為,或以適當的錯誤拒絕該請求。

棄用時間表:十二個月,和一個九十天的例外

這一版同時採用了正式的功能生命週期政策,定義 Active、Deprecated、Removed 三種狀態,並訂出最短十二個月的棄用視窗。政策另外留了一個加速移除的例外,最短九十天。

無狀態核心搶走了大部分版面,但如果要我挑這次對維護者影響最久的一項,我會挑這個政策。它管的不是這一版改了什麼,而是往後要拿掉任何東西時,得先給多久的預告。

目前登記在棄用狀態的功能如下:

功能 棄用於 遷移路徑 最早移除
Roots 2026-07-28 改用 tool 參數、resource URI 或 server 設定傳遞目錄與檔案 2027-07-28 當日或之後的第一個修訂版
Sampling 2026-07-28 直接串接 LLM 供應商的 API 同上
Logging 2026-07-28 stdio 傳輸寫 stderr;可觀測性改用 OpenTelemetry 同上
Dynamic Client Registration 2026-07-28 Client ID Metadata Documents 同上
includeContextthisServerallServers 2025-11-25 省略該欄位或改用 none 跟隨 Sampling
HTTP+SSE transport 2025-03-26 Streamable HTTP SEP-2596 進入 Final 後三個月

最後一列的三個月和十二個月的政策看起來對不上,這裡要說清楚官方文件實際講了什麼、又沒講什麼。登記表說明 HTTP+SSE 與 includeContext 那兩項在生命週期政策存在之前就已被描述為棄用,這次是依 SEP-2596 的過渡條款重新歸類;政策本身另外訂有一個最短九十天的加速移除例外。而官方部落格提到這個傳輸方式有長達一年的緩衝期。

這兩個數字各自從哪一天起算、彼此是什麼關係,官方文件沒有交代,本文也不替它們調和。實務上比較安全的讀法是:兩個數字都當成官方講過的話記著,真的要排時程時去看該功能的棄用通知與 changelog,因為登記表自己就說明它是衍生視圖,規範性的紀錄是那兩者。

另外兩件事值得記住。「最早移除」只表示從那時起具備被移除的資格,實際何時移除是核心維護者在準備發行時的決定,可能更晚。以及:Removed 區目前是空的,還沒有任何功能依這套政策被真正移除。

你的 server 現在是哪一代

規格用三個詞描述互通性,翻譯時建議直接沿用原詞,因為它們在文件裡是有定義的術語:

  • Modern:以每個 request 攜帶版本、身分與能力的方式運作,也就是 2026-07-28 及之後。
  • Legacy:以 initialize 握手建立 session,也就是 2025-11-25 及之前。
  • Dual-era:同時支援上述兩者。

官方給了一張完整的相容性矩陣,結論可以壓成三句話。兩邊同代就通。跨代直接對上就不通:Modern client 對 Legacy server 會失敗,Legacy client 對 Modern server 也會失敗,而且舊 client 沒有向前相容的機制,它連錯在哪都不一定講得出來。Dual-era 那一側則吃得下兩種:Dual-era client 對上兩種 server 都能通,而規格允許 Dual-era server 在同一個端點同時服務兩個世代。

實務上這代表:如果你的 server 面對的既有 client 之中仍有 Legacy,直接跳到純 Modern 會切斷它們。若你希望在不要求那些 client 升級的前提下、由同一個端點同時服務兩個世代,Dual-era 就是規格為此定義的做法。要用別的方式安排遷移當然也可以,只是規格文件本身沒有寫。

給現有 MCP server 維護者的遷移檢查清單

以下把上面所有變更翻成待辦事項。這份清單由本站依規格內容整理,官方文件裡沒有對應的東西:

  1. 盤點你的程式碼有沒有依賴 Mcp-Session-Id 或握手階段建立的狀態。有的話,先決定那些狀態要改放進 handle、還是移到自己的儲存層。
  2. 實作 server/discover。這在 server 端是必要項。
  3. 在所有回應加上 resultType。需要中途向使用者要資訊的流程,改寫成 MRTR。
  4. 檢查有沒有用到 roots/listsampling/createMessageelicitation/create 這三個 server 主動發起的請求,它們的舊路徑已經被 MRTR 取代。
  5. 如果走 Streamable HTTP,補上 Mcp-MethodMcp-Name header 的處理。
  6. 為五個 method 的回應補 ttlMscacheScopetools/listprompts/listresources/listresources/readresources/templates/list。順手讓 tools/list 的順序穩定下來。
  7. 把變更通知從 HTTP GET 端點搬到 subscriptions/listen。這不只是換個名字:它是一條長時間存活的 POST 回應串流,client 要逐一表明想收哪些類型,server 會確認並在通知上標 io.modelcontextprotocol/subscriptionId。要注意 notifications/progressnotifications/message 不走這條,它們仍留在各自所屬請求的回應串流上。
  8. 檢查是否依賴 SSE 的續傳與重送(Last-Event-ID)。這個機制沒有了,斷線就是重送一個新請求。
  9. 授權那一側:驗證 iss、註冊時帶 application_type、憑證改以 issuer 為索引儲存,並開始評估從 DCR 移到 CIMD。
  10. 盤點 Roots、Sampling、Logging 的使用。不急著今天改,但新功能不要再往上面加。
  11. 決定要不要做 Dual-era。這取決於既有 client 的實際世代分布,以及你能不能安排它們一起遷移。
  12. 升級 SDK。TypeScript、Python、Go、C# 這四個 Tier 1 SDK 在發布當天就支援新版規格,Rust SDK 則是 beta 支援。

Claude 這邊支援到哪

Anthropic 在同一天發了一篇對應的公告,標題是〈Bringing MCP 2026-07-28 to Claude〉。這裡有個用詞值得精確轉述:公告在正文說支援正陸續開放到各個 Claude 產品,文末說支援即將開放,連網頁標題用的動詞都還是「即將帶進 Claude」。撰稿當下它仍在推進中,尚未全面上線。

同一篇提到幾個可查證的數字:MCP 近期突破每月 4 億次 SDK 下載,今年成長 4 倍;Claude 的連接器目錄目前列出超過 950 個 MCP server。公告也整理了 Claude 這一年陸續推出的相關能力,包括讓 server 在對話中直接渲染互動介面的 MCP Apps、讓管理員透過身分供應商為整個組織佈建連接器的企業託管授權、連接器開發者的可觀測性儀表板,以及仍在 research preview 階段的 MCP tunnels。要注意這些是 Claude 產品自己的功能進展,跟這次規格改了什麼是兩回事。

至於這次改版的份量,官方公告的定性是「至今最重要的規格發布之一」。另外有一句更強的說法,出自具名個人:MCP 共同發明人、Anthropic 技術幕僚 David Soria Parra 形容它是 remote MCP 推出一年多以來最重要的一次發布。這句話有明確的主詞,也有明確的時間起點,轉述時兩者都不宜省略——把它縮寫成「官方稱這是 MCP 史上最大改版」,主詞和範圍就同時消失了。

給非工程師的一句話

如果你不寫 MCP server,規格本身推斷不出你會不會直接有感。規格能確認的相容性條件是:當一邊已經走新版、另一邊還停在舊版,而且沒有任何一邊做雙世代支援時,這個組合在規格上就是連不起來的。至於實際會不會發生在你用的某個連接器身上、什麼時候發生,官方文件沒有講,本文也無從預測。真的遇到連不上,版本世代是值得列入的一種可能,但它不是唯一的可能,也不必然排在最前面。

想先補一下 MCP 到底是什麼,可以看〈不懂技術的行銷人,也能把 Meta 廣告接進 AI〉。那篇是站內最早介紹 MCP 的文章,把它比喻成「AI 的萬用轉接頭」,比喻在今天仍然成立,只是轉接頭內部的接線方式從這一版起換掉了。如果你想知道終端機那一側的 agent 現在長什麼樣,可以看〈Claude Code vs Codex:兩個終端機 AI 助手,你該選哪一個〉,裡面對非同步任務的討論,正好對得上這次 Tasks 換位置的脈絡;而 ClaudeClaude Code 都是目前接得上 MCP 連接器的入口。

事實分級說明

以下內容取自官方一手文件,並於 2026 年 7 月 29 日重新查證:規格版本號與格式定義、五個歷代版本、所有協定變更條目、授權相關的四項改動、擴充框架與 Tasks 的位置變動、棄用功能清單與最早移除時間、相容性矩陣與 Modern/Legacy/Dual-era 的定義、Tier 1 SDK 名單,以及 Anthropic 公告中的推進狀態、下載量、連接器數量與具名發言。來源為 modelcontextprotocol.io 的規格站與官方部落格,以及 claude.com 的產品公告。

以下屬本站自行整理:新舊規格逐項對照表的編排方式、遷移檢查清單的十二個項目與排序,以及五個歷代版本頁的存續實測(於查證日逐一開啟,每一頁自報的版本與網址相符,其中只有 2026-07-28 標示為 latest)。官方文件裡沒有這樣一份對照表或檢查清單。

有一件事本文刻意不下結論:官方部落格提到 HTTP+SSE 有長達一年的緩衝期,棄用登記表寫的則是「SEP-2596 進入 Final 後三個月」。這兩個數字的起算點與相互關係,在本文查得到的官方文件裡都沒有交代,因此本文並列兩者而不調和。

規格文件在發布後仍可能修訂,實際行為請以 modelcontextprotocol.io 上的規格頁面與各 SDK 的遷移說明為準。

常見問題

MCP 2026-07-28 是版本號還是發布日期?

是版本號。MCP 的版本識別碼採 YYYY-MM-DD 格式,官方對這個格式的定義是「用來標示最後一次做出不向後相容變更的日期」,而不是每次更新就換一個號碼;只要改動維持向後相容,版本號就不會前進。2026-07-28 這一版剛好在同一天發布,所以版本號和發布日期看起來一樣,但兩者是不同的東西。前一版是 2025-11-25。

MCP 改成無狀態之後,我的 server 還能記住東西嗎?

可以,只是記的方式換了。官方明講「拿掉協定層的 session 不會強迫你的應用程式變成無狀態」。做法是由 server 自己發一個明確的 handle,當成一般的 tool 參數回給模型,模型下次呼叫時把它帶回來。官方也說明了為什麼偏好這個做法:handle 是模型看得見的,可以在不同 tool 之間自己串接,而藏在傳輸層裡的 session 狀態做不到這件事。

舊版的 MCP server 和新版的 client 還能互通嗎?

不一定,要看兩邊各自是哪一代。規格用 Modern(2026-07-28 及之後)、Legacy(2025-11-25 及之前)、Dual-era(兩者都支援)三個詞描述。新 client 對舊 server 會失敗,舊 client 對新 server 也會失敗,而且舊 client 沒有向前相容的機制。只有 Dual-era 那一側能同時吃兩種:Dual-era client 對上兩種 server 都能通,而規格允許 Dual-era server 同時服務兩個世代。

Roots、Sampling、Logging 被棄用了,我現在就得改嗎?

不用馬上改,但新的實作不該再採用。這三個功能在棄用視窗內仍完全可用,規格的棄用政策訂了最短十二個月的視窗,登記表把它們的最早移除時間寫成「2027-07-28 當日或之後發布的第一個修訂版」。要注意「最早移除」只代表從那時起具備被移除的資格,實際移除是核心維護者在準備發行時的決定,可能更晚。

MCP Apps 和 Tasks 是這次新增的功能嗎?

不是。這次動的是它們的位置,不是有無。Tasks 原本以 experimental 的身分放在核心協定裡,這一版把它移出核心、改成官方擴充 io.modelcontextprotocol/tasks,同時重新設計成輪詢式;MCP Apps 則是本來就存在的擴充。真正新的東西是「版本化擴充框架」這個機制本身,讓這類能力有一條正式的路可以加進來,而不必更動核心協定。

📚 收進你的工具

For AI Reading Era

把這篇文章交給你日常用的工具——做研究、整理筆記,或當 AI 的 context。

 
延伸閱讀