Skip to content

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

欄位型別說明
toolsListChangedboolean工具清單變更時接收 notifications/tools/list_changed
promptsListChangedboolean提示詞清單變更時接收 notifications/prompts/list_changed
resourcesListChangedboolean資源清單變更時接收 notifications/resources/list_changed
resourceSubscriptionsstring[]指定資源 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/listen request ID 的 notifications/cancelled
  • 伺服器主動結束:例如關機時,伺服器 SHOULD(應該)先送出空的 subscriptions/listen response 表示正常結束,再關閉串流。
  • 底層傳輸中斷:例如 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 以恢復訂閱;伺服器不會跨重新連線保留訂閱狀態。