MCP Specification · 2026-07-28 · zh-TW
基礎協定
Base Protocol · Overview
MCP 的 JSON-RPC 訊息、無狀態模型、schema 與每次請求的協定 metadata。
Model Context Protocol(MCP)由多個彼此分工的元件組成:
- 基礎協定(Base Protocol):核心 JSON-RPC 訊息類型。
- 版本與相容性(Versioning and Compatibility):協定版本、擴充功能協商,以及與較早版本的互通方式。
- 訊息模式(Message Patterns):請求/回應、多回合請求(MRTR)、訂閱與通知等互動模式。
- 授權(Authorization):HTTP 傳輸所使用的認證與授權框架。
- 伺服器功能:Resources、Prompts 與 Tools。
- 用戶端功能:Elicitation,以及已標示為已棄用的 Sampling 與 Roots。
- 通用功能:例如 Logging 與參數補全。
所有實作 MUST(必須)支援基礎協定、版本處理與訊息模式;其他部分則 MAY(可以)依應用需求選擇實作。這種分層讓各元件保持清楚的責任邊界,同時允許實作者只支援真正需要的功能。
訊息
MCP 用戶端與伺服器之間的所有訊息都 MUST(必須)遵循 JSON-RPC 2.0。協定主要使用請求、回應與通知三類訊息。
請求(Requests)
請求由用戶端送往伺服器,用來啟動一項操作。
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
- 請求 MUST(必須)包含字串或整數形式的
id。 - 與基本 JSON-RPC 不同,
idMUST NOT(不得)為null。 - 在先前同一發送方送出的請求尚未收到回應前,新請求的
idMUST NOT(不得)與其重複。
回應(Responses)
回應對應到先前的請求,並包含成功結果或錯誤。
結果回應(Result Responses)
操作成功時使用結果回應。回應中的 id MUST(必須)與原請求相同,且 MUST(必須)包含 result。result MAY(可以)採用任意 JSON object 結構,但 MUST(必須)包含 resultType,讓用戶端知道如何解讀結果。
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete"
}
}
"complete":請求已完成,結果包含最終內容。"input_required":請求尚未完成,需要更多用戶端輸入;結果包含InputRequiredResult。- 擴充功能 MAY(可以)增加其他
ResultType;支援的集合 MUST(必須)由核心協定定義的值,加上已透過 capabilities 宣告支援之擴充功能所定義的值組成。 - 用戶端若收到無法識別的
resultType,MUST(必須)將它視為無效。 - 為相容於較早、不含
resultType的伺服器,用戶端在欄位缺失時 MUST(必須)將其視為"complete"。
錯誤回應(Error Responses)
操作失敗或發生錯誤時使用錯誤回應。
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32022,
"message": "Unsupported protocol version"
}
}
- 錯誤回應 MUST(必須)使用與原請求相同的
id;只有在 malformed request 使接收端根本無法讀出 ID 時例外。 - 錯誤回應 MUST(必須)包含
error,其中 MUST(必須)有code與message。 codeMUST(必須)是整數。- 錯誤回應 MAY(可以)透過
data帶入任意型別的額外資訊,例如巢狀錯誤。
錯誤代碼
MCP 沿用 JSON-RPC 2.0 的一般錯誤代碼,並將 JSON-RPC 的 -32000 至 -32099 server-error 範圍進一步分區:
-32000至-32019:舊有實作曾使用的區段。新代碼 MUST NOT(不得)配置在此區段,新實作也 SHOULD NOT(不應)使用其中的代碼。除下方列出的-32002相容規則外,接收端 MUST NOT(不得)假設這些代碼具有特定意義。-32020至-32099:保留給 MCP 規範。實作 MUST NOT(不得)發出規範未定義的代碼,且對已定義代碼 MUST(必須)只使用其規範指定的意義。
| 代碼 | 名稱 |
|---|---|
-32020 | HeaderMismatch |
-32021 | MissingRequiredClientCapability |
-32022 | UnsupportedProtocolVersion |
較早版本定義過的代碼仍保留且不會重新分配;2026-07-28 實作 MUST NOT(不得)發出 -32002(舊版 resource not found,已由 -32602 取代)或 -32042(2025-11-25 的 URL elicitation required)。但用戶端仍 SHOULD(應該)接受較舊伺服器送出的 -32002。
純粹由本機實作產生的錯誤,例如 SDK 自己的 timeout,目前沒有 MCP 標準代碼。若以類 JSON-RPC 結構呈現,應避免讓它看起來像從 peer 收到的協定錯誤。規範未定義的新錯誤代碼 SHOULD(應該)配置在 JSON-RPC 保留範圍 -32768 至 -32000 之外。
通知(Notifications)
通知是一種單向訊息,可由用戶端或伺服器送出;接收方 MUST NOT(不得)回傳 response。通知 MUST NOT(不得)包含 id。
訊息模式
MCP 核心協定定義數種互動模式:
- Request and Response:用戶端送出請求,伺服器回傳結果或錯誤。
- Multi Round-Trip Requests(MRTR):伺服器完成原始請求前,需要額外的用戶端輸入。
- Subscribe and Notify:用戶端訂閱通知串流,伺服器在事件發生時送出通知。
無狀態(Statelessness)
MCP 是無狀態協定:處理一個請求所需的協定資訊都包含在該請求本身。伺服器必須獨立處理每個請求,不應從之前的請求、底層連線或程序推測協定狀態。
- 伺服器 MUST NOT(不得)依賴同一連線上的先前請求來建立能力、協定版本或用戶端身分等上下文;每個請求都在
_meta中攜帶這些資訊。 - 伺服器 SHOULD(應該)能處理屬於不同 task、thread 或 conversation 的請求。
- 伺服器 SHOULD NOT(不應)要求相關操作一定要重複使用同一連線或程序。
- 用戶端 SHOULD NOT(不應)把單一 task、thread 或 conversation 當成 stdio 程序的生命週期邊界。
- 若狀態必須跨越多個請求保存,該狀態 MUST(必須)以明確識別碼表示,並由用戶端在每次請求中傳入。
因此,即使 stdio 程序或 HTTP 連線長時間保持開啟,它也不是 conversation 或 session。用戶端可以在同一 transport 上交錯不同工作,伺服器不能把 connection 或 process identity 當成 conversation/session continuity。像 subscriptions/listen 這類長時間請求仍屬於 request/response;其狀態範圍是該 request,而不是底層連線。
認證與授權(Auth)
MCP 為 HTTP 傳輸定義授權框架。使用 HTTP-based transport 的實作 SHOULD(應該)遵循該規範;使用 stdio 的實作 SHOULD NOT(不應)套用 HTTP 授權流程,而應從執行環境取得憑證。用戶端與伺服器也 MAY(可以)另外協商自訂的認證與授權方式。
結構描述(Schema)
MCP 的完整協定結構由官方 TypeScript schema 定義,並另有自 TypeScript 來源自動產生的 JSON Schema,供驗證與自動化工具使用;協定訊息與結構應以 TypeScript schema 的定義為準。
JSON Schema 使用方式
MCP 使用 JSON Schema 驗證協定中的多種資料結構。當 schema 沒有 $schema 欄位時,預設 dialect 為 JSON Schema 2020-12。
- schema MAY(可以)透過
$schema明確指定其他 dialect。 - 用戶端與伺服器 MUST(必須)至少支援 JSON Schema 2020-12,並 SHOULD(應該)記錄另外支援哪些 dialect。
- 實作者 RECOMMENDED(建議)優先使用 JSON Schema 2020-12。
- 用戶端與伺服器 MUST(必須)依 schema 宣告的 dialect,或缺省時的 2020-12 dialect 進行驗證。
- 不支援某個明確指定的 dialect 時,實作 MUST(必須)以適當錯誤指出不支援該 dialect,而不是默默放寬驗證。
- schema MUST(必須)符合其宣告或預設 dialect。
$ref 解析
實作 MUST NOT(不得)自動取得解析至網路 URI 的 $ref。若提供 opt-in 的遠端解析模式,預設 MUST(必須)關閉,且 SHOULD(應該)限制可連線的主機,或至少拒絕 loopback/link-local/private network,並設定 timeout、大小限制與存取紀錄。無法解析外部 $ref 而導致驗證失敗時,schema SHOULD(應該)被拒絕,而不是當成 permissive schema。
複合 schema 的資源使用
anyOf、oneOf、allOf、if/then/else 與 $defs 等功能可能造成高昂驗證成本。實作 SHOULD(應該)設定合理界線,例如 schema 最大深度、subschema 數量上限或每次驗證的時間預算,以降低惡意 schema 造成阻斷服務的風險。
通用欄位
_meta
_meta 讓用戶端與伺服器在 MCP 互動中附加中繼資料。MCP 保留部分 key namespace 供協定層使用;實作 MUST NOT(不得)對保留 key 的值作未經規範定義的假設。
Key 名稱格式
有效的 _meta key 由選用的 prefix 與 name 兩部分構成:
- 若有 prefix,它 MUST(必須)由以
.分隔的 labels 組成,最後接/;每個 label MUST(必須)以英文字母起始,並以英文字母或數字結尾,中間可使用英文字母、數字與-。實作 SHOULD(應該)使用 reverse-DNS notation。 - prefix 的第二個 label 若為
modelcontextprotocol或mcp,整個 prefix 即保留給 MCP 使用,例如io.modelcontextprotocol/、dev.mcp/。 - name 若非空,MUST(必須)以英數字元起始與結尾;中間 MAY(可以)使用
-、_、.與英數字元。
保留的 _meta keys
| Key | 用途 |
|---|---|
progressToken | 讓 request opt in 進度通知。 |
io.modelcontextprotocol/protocolVersion | 本次 request 的協定版本。 |
io.modelcontextprotocol/clientInfo | 用戶端名稱與版本。 |
io.modelcontextprotocol/clientCapabilities | 本次 request 相關的用戶端能力。 |
io.modelcontextprotocol/logLevel | 本次 request 希望伺服器輸出的最低 log level。 |
io.modelcontextprotocol/subscriptionId | 把通知對應到來源 subscription。 |
traceparent、tracestate、baggage | OpenTelemetry trace context。 |
官方 extension 可以在 io.modelcontextprotocol/ 下定義其他 keys;第三方 extension 使用自己的 vendor prefix,並由該 extension 文件定義其語意。
每次請求的協定欄位
| Key | 型別 | 必要性 | 用途 |
|---|---|---|---|
io.modelcontextprotocol/protocolVersion | string | 必須 | 本次請求使用的協定版本。 |
io.modelcontextprotocol/clientInfo | Implementation | 選用 | 用戶端名稱與版本。 |
io.modelcontextprotocol/clientCapabilities | ClientCapabilities | 必須 | 與本次請求相關的用戶端能力。 |
io.modelcontextprotocol/logLevel | LoggingLevel | 選用 | 本次請求希望伺服器輸出的最低 log level。 |
缺少必要欄位的請求屬於 malformed request;伺服器 MUST(必須)以 JSON-RPC -32602 拒絕。HTTP 傳輸時,HTTP status MUST(必須)為 400 Bad Request。
除非特別設定為不要提供,用戶端 SHOULD(應該)在每個 request 都包含 io.modelcontextprotocol/clientInfo。
伺服器 MUST NOT(不得)依賴用戶端未宣告的能力。若處理請求需要未宣告能力,伺服器 MUST(必須)回傳 MissingRequiredClientCapabilityError(-32021),其 data.requiredCapabilities 列出缺少的能力;HTTP response status MUST(必須)為 400 Bad Request。
每次回應的協定欄位
除非特別設定為不要提供,伺服器在每個 result 的 _meta 中 SHOULD(應該)包含 io.modelcontextprotocol/serverInfo,以描述自身名稱與版本。clientInfo 與 serverInfo 都是發送方自我宣告的資訊,只適合顯示、紀錄與除錯;實作 SHOULD NOT(不應)據此改變協定行為,也 SHOULD NOT(不應)把它們用於安全決策。
透過 subscriptions/listen 串流傳送的通知,伺服器 MUST(必須)在 _meta 中加入 io.modelcontextprotocol/subscriptionId,讓用戶端能對應來源訂閱。
OpenTelemetry trace context
traceparent、tracestate 與 baggage 是 prefix 規則的例外,保留給 OpenTelemetry trace context propagation。若出現,前兩者的值 MUST(必須)符合 W3C Trace Context,而 baggage MUST(必須)符合 W3C Baggage 格式。
{
"_meta": {
"traceparent": "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
}
}
icons
icons 提供一種標準方式,讓伺服器為 Implementation、Tool、Prompt 與 Resource 提供視覺識別。每個 icon 至少包含必要的 src,並可附帶 mimeType、sizes 與 theme。
支援顯示 icon 的用戶端 MUST(必須)至少支援 PNG 與 JPEG(包含 image/jpg),並 SHOULD(應該)考慮支援 SVG 與 WebP。
- icon metadata 與 bytes MUST(必須)視為不可信輸入,並防範網路、隱私與 parser 風險。
- icon URI 應是 HTTPS 或
data:URI;用戶端 MUST(必須)拒絕javascript:、file:、ftp:、ws:或 local-app scheme 等不安全 URI 與 redirect,並禁止 scheme 變更或跨 origin host redirect。 - 消費端 MAY(可以)設定 image/content size、尺寸與 frame 數量限制,以避免 resource exhaustion。
- 取得 icon 時不得帶 cookie、
Authorizationheader 或 client credentials,且應確認 icon URI 與 server 同 origin,避免把資料或追蹤訊號洩漏給第三方。 - icon payload MAY(可以)含可執行內容,例如 SVG script;消費端 MAY(可以)禁止特定格式或先進行 sanitize。
- 必須驗證 MIME type 與實際檔案內容;MIME metadata 只能當作提示,應以 magic bytes 等方式辨識內容,遇到 mismatch 或未知格式應拒絕,並維持嚴格的允許清單。
Icon 可以附加在 Implementation、Tool、Prompt 與 Resource;若提供多個 icon,用戶端可依顯示情境與解析度選擇合適項目。