Skip to content

MCP Specification · 2026-07-28 · zh-TW

多回合請求

Multi Round-Trip Requests (MRTR)

以 InputRequiredResult 與重試請求完成需要額外用戶端輸入的無狀態流程。

2026-07-28 的破壞性變更

多回合請求(Multi Round-Trip Requests, MRTR)是在本版 MCP 規範新增的模式,用來取代先前由伺服器主動送出請求的方式。伺服器若需要執行 roots/listsampling/createMessageelicitation/create 等「伺服器向用戶端取得輸入」的互動,MUST(必須)使用 MRTR;舊的 server-initiated request 模式已不再支援。

為了簡潔,本頁部分 JSON 範例省略每次請求的 _meta 協定欄位。依 Base Protocol,io.modelcontextprotocol/protocolVersionio.modelcontextprotocol/clientCapabilities MUST(必須)出現在每個請求;io.modelcontextprotocol/clientInfo 為選用欄位,但用戶端 SHOULD(應該)在未特別停用時提供。

多回合請求

MCP 中有些操作在處理過程中需要向使用者或用戶端取得額外資訊。MRTR 提供標準化的無狀態流程,不要求不同伺服器實例共用儲存,也不要求使用 stateful load balancing。

  1. 用戶端以執行操作所需的參數送出初始請求。
  2. 伺服器判斷資訊不足,回傳需要額外輸入的結果。
  3. 用戶端從使用者或其他來源取得所需資料,再重送原始請求,並附上額外輸入。
  4. 伺服器確認資訊足夠後,回傳最終結果。

每一回合都是彼此獨立的 JSON-RPC 請求。處理重試的伺服器不需要知道前一次請求的記憶體狀態;必要的狀態應由請求本身攜帶。

核心型別

InputRequests

InputRequests 是伺服器希望用戶端完成之請求的 map。key 是伺服器自行指定的字串識別碼;value 是請求物件,例如 ElicitRequestCreateMessageRequestListRootsRequest

{
  "github_login": {
    "method": "elicitation/create",
    "params": {
      "mode": "form",
      "message": "Please provide your GitHub username",
      "requestedSchema": {
        "type": "object",
        "properties": { "name": { "type": "string" } },
        "required": ["name"]
      }
    }
  }
}

InputResponses

InputResponses 是用戶端對前述伺服器請求的回覆 map。key 對應 InputRequests 中的 key,value 則是各請求的結果,例如 ElicitResultCreateMessageResultListRootsResult

{
  "github_login": {
    "action": "accept",
    "content": { "name": "octocat" }
  }
}

InputRequiredResult

InputRequiredResult 是一種 Result,表示目前尚不能完成請求,仍需要額外輸入:

  • inputRequests(選用):伺服器希望用戶端完成的 InputRequests map。
  • requestState(選用):只有伺服器能理解的不透明字串。用戶端 MUST NOT(不得)檢查、解析、修改它,也不得對其內容作任何假設。
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "input_required",
    "inputRequests": {
      "github_login": {
        "method": "elicitation/create",
        "params": { "mode": "form", "message": "Please provide your GitHub username" }
      }
    },
    "requestState": "AEAD-protected blob"
  }
}

支援的請求

伺服器 MAY(可以)在下列用戶端請求回傳 InputRequiredResult

用戶端請求可回傳 InputRequiredResult
prompts/get
resources/read
tools/call

伺服器 MUST NOT(不得)在其他用戶端請求中回傳 InputRequiredResult

基本流程

以下以 tools/call 為例;相同模式也適用於前述其他支援的請求。

  1. 用戶端送出 tools/call
  2. 伺服器需要更多資料,回傳包含 inputRequests 與/或 requestStateInputRequiredResult;初始請求到此即結束。
  3. 用戶端完成需要的 Elicitation/Sampling/Roots 輸入。
  4. 用戶端以新的 JSON-RPC id 重送原始 tools/call,並附上 inputResponses 與原樣回傳的 requestState
  5. 伺服器只依新請求中的資料重建所需狀態並完成操作。

伺服器要求

  1. 伺服器 MAY(可以)對任何支援 MRTR 的用戶端請求回傳 InputRequiredResult
  2. inputRequests 為選用;若存在,其 key 由伺服器指定,且在該請求範圍內 MUST(必須)唯一;value MUST(必須)ElicitRequestCreateMessageRequestListRootsRequest 之一。
  3. requestState 為選用,格式完全由伺服器決定,例如 base64 JSON、加密 JWT 或序列化二進位資料。
  4. 當重試請求帶有 requestState 時,伺服器 MUST(必須)把它視為攻擊者可控制的輸入。如果它會影響授權、資源存取或商業邏輯,伺服器 MUST(必須)保護其完整性(例如 HMAC 或 AEAD),並拒絕驗證失敗的狀態。只有在竄改最多只會導致請求失敗時,才 MAY(可以)省略完整性保護。
  5. 為限制 replay,伺服器 SHOULD(應該)把已驗證 principal、短效 TTL,以及原始請求識別資訊(例如 method 與重要參數摘要)放入受到完整性保護的 requestState,並在接收時逐一驗證。若業務要求狀態只能被消耗一次,則仍 MUST(必須)由伺服器端額外維護 single-use invariant。
  6. 每一個 InputRequiredResult MUST(必須)至少包含 inputRequestsrequestState 其中之一。
  7. 伺服器 MUST NOT(不得)要求用戶端沒有在 capabilities 宣告支援的輸入。例如用戶端沒有宣告 elicitation 時,不得在 inputRequests 放入 elicitation/create
  8. 伺服器 MUST NOT(不得)假設用戶端一定會完成 inputRequests 或重試原請求。若應用希望持續向使用者詢問直到資訊足夠,伺服器 MAY(可以)在多次嘗試中重複回傳 InputRequiredResult

用戶端要求

  1. InputRequiredResult 含有 inputRequests,用戶端在重試原始請求前 MUST(必須)建立所要求的輸入;若沒有 inputRequests,則用戶端 MAY(可以)立刻重試。
  2. 若結果含有 requestState,用戶端重試時 MUST(必須)原封不動回傳相同值,並 MUST NOT(不得)檢查、解析、修改或猜測內容。若原結果沒有 requestState,重試時也 MUST NOT(不得)自行加入。
  3. 初始請求與重試請求是兩個獨立 JSON-RPC 請求,因此 id MUST(必須)不同。
  4. inputRequestsrequestState 只影響對原始請求的這次重試,MUST NOT(不得)套用到用戶端並行送出的其他請求。

錯誤處理

伺服器 SHOULD(應該)驗證用戶端提供的資料是否為合法的 InputResponses,且內容可以正確解析。格式不正確的 JSON、schema 錯誤或伺服器內部錯誤,SHOULD(應該)以適當的 JSON-RPC error code 與 message 回覆。

InputResponses 含有額外且未預期的欄位,伺服器 SHOULD(應該)忽略自己不認得或不需要的資料。若用戶端漏掉先前要求、而且完成請求確實需要的資訊,伺服器 SHOULD(應該)再次回傳新的 InputRequiredResult 要求缺少的資訊,而不是直接回傳錯誤。

安全考量

requestState 會經過用戶端,因此惡意或遭入侵的用戶端可能嘗試修改它,藉此改變伺服器行為、繞過授權檢查或破壞商業邏輯。伺服器 MUST(必須)依前述伺服器要求驗證並保護 requestState