MCP Specification · 2026-07-28 · zh-TW
訂閱
Subscriptions
以 subscriptions/listen 建立長時間存活、可明確篩選通知種類的串流。
subscriptions/listen 會建立從伺服器到用戶端的長時間存活通知串流。不同於一次性的請求,這個串流會保持開啟並持續傳送通知,直到用戶端取消為止。它取代舊有的 resources/subscribe RPC 與 HTTP GET endpoint。
開啟串流
用戶端送出 subscriptions/listen,並以 notifications filter 指定希望接收的事件類型。伺服器 MUST NOT(不得)送出用戶端沒有明確要求的通知種類。
{
"jsonrpc": "2.0",
"id": 1,
"method": "subscriptions/listen",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "ExampleClient",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
},
"notifications": {
"toolsListChanged": true,
"resourceSubscriptions": ["file:///project/config.json"]
}
}
}
通知 filter
| 欄位 | 型別 | 說明 |
|---|---|---|
toolsListChanged | boolean | 工具清單變更時接收 notifications/tools/list_changed |
promptsListChanged | boolean | 提示詞清單變更時接收 notifications/prompts/list_changed |
resourcesListChanged | boolean | 資源清單變更時接收 notifications/resources/list_changed |
resourceSubscriptions | string[] | 指定資源 URI 更新時接收 notifications/resources/updated |
所有欄位都是選用。省略某個欄位,就等同於沒有訂閱該通知種類。
確認
伺服器 MUST(必須)把 notifications/subscriptions/acknowledged 當作這個訂閱的第一則訊息,並在 _meta.io.modelcontextprotocol/subscriptionId 放入訂閱 ID。在送出這個確認之前,伺服器 MUST NOT(不得)送出任何屬於該訂閱的通知。
在 stdio 中,所有訂閱共用同一條 channel,因此這個順序要求是以「每個 subscription ID」為範圍,而不是以整條 channel 為範圍;其他訂閱的訊息 MAY(可以)在這個確認之前交錯出現。
{
"jsonrpc": "2.0",
"method": "notifications/subscriptions/acknowledged",
"params": {
"_meta": {
"io.modelcontextprotocol/subscriptionId": 1
},
"notifications": {
"toolsListChanged": true,
"resourceSubscriptions": ["file:///project/config.json"]
}
}
}
確認訊息中的 notifications 代表伺服器實際同意支援的子集合;伺服器不支援的通知類型會被省略。用戶端 SHOULD(應該)把確認後的 filter 與原始要求比較,並妥善處理不支援的類型。
接收通知
串流上的每一則通知都在 _meta 中帶有 io.modelcontextprotocol/subscriptionId,用來指出是哪一個 subscriptions/listen 建立這個串流。其值就是原始 subscriptions/listen 請求的 JSON-RPC id。
{
"jsonrpc": "2.0",
"method": "notifications/resources/updated",
"params": {
"_meta": {
"io.modelcontextprotocol/subscriptionId": 1
},
"uri": "file:///project/config.json"
}
}
在 stdio 中,所有訊息共用同一條 channel,因此用戶端 MUST(必須)使用這個欄位,把通知分流回各自的原始訂閱。
多個並行訂閱
用戶端 MAY(可以)同時維持多個有效訂閱,例如一個監聽工具清單變更、另一個監聽資源更新。每個訂閱都以其 subscriptions/listen 的 JSON-RPC request ID 識別,串流上的每一則通知都帶有對應的 subscriptionId。
取消
訂閱會在下列情況結束:
- 用戶端取消:HTTP 時關閉 SSE stream;stdio 時送出指向該
subscriptions/listenrequest ID 的notifications/cancelled。 - 伺服器主動結束:例如關機時,伺服器 SHOULD(應該)先送出空的
subscriptions/listenresponse 表示正常結束,再關閉串流。 - 底層傳輸中斷:例如 HTTP timeout、TCP disconnect 或 stdio process exit。
正常關閉
當伺服器主動結束訂閱時,它 SHOULD(應該)先以原始 request id 回傳空結果,讓用戶端可以區分「正常結束」與沒有任何 response 的突發 transport 中斷:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"_meta": {
"io.modelcontextprotocol/subscriptionId": 1
}
}
}
和串流上的其他訊息相同,這個 response 也帶有 subscriptionId。收到它的用戶端知道訂閱已正常關閉;若 transport 在沒有這個 response 的情況下結束,則代表非預期斷線,用戶端 MAY(可以)把它視為重新連線的觸發條件。
在 stdio 中,若連線中斷後重新建立,用戶端 MUST(必須)重新送出 subscriptions/listen 以恢復訂閱;伺服器不會跨重新連線保留訂閱狀態。