跳至主要內容

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

工具

Tools

伺服器向模型提供可執行的工具,涵蓋 JSON Schema、結構化結果、多輪往返請求、狀態控制與安全要求。

Model Context Protocol(MCP)允許伺服器提供可由語言模型呼叫的工具。工具讓模型與外部系統互動,例如查詢資料庫、呼叫 API 或執行計算。每個工具都有唯一名稱,以及描述其結構描述(schema)的中繼資料。

請求中繼資料(Request metadata)

為保持簡潔,本頁請求範例省略 _meta 中的 io.modelcontextprotocol/protocolVersion、io.modelcontextprotocol/clientInfo 與 io.modelcontextprotocol/clientCapabilities。每個請求仍 MUST(必須)包含必要的 _meta 欄位,詳見基礎協定的中繼資料說明。

使用者互動模型(User Interaction Model)

MCP 工具是由模型控制的基本功能:語言模型可以依據上下文與使用者提示,自動探索並呼叫工具。不過,實作可以透過任何適合需求的介面提供工具;協定本身不強制特定的使用者互動模型。

人工介入(Human in the loop)

基於信任與安全考量,SHOULD(應該)始終保留可拒絕工具呼叫的人工介入機制。應用程式 SHOULD(應該)清楚顯示提供給 AI 模型的工具、在呼叫工具時提供明確的視覺提示,並透過操作確認提示讓使用者參與決定。

能力宣告(Capabilities)

支援工具的伺服器 MUST(必須)宣告 tools 能力:

{
  "capabilities": {
    "tools": {
      "listChanged": true
    }
  }
}

listChanged 表示伺服器是否會在可用工具清單變更時發出通知。

宣告 tools 能力的伺服器 MUST(必須)回應 tools/list,提供目前可供該用戶端使用的工具集合。集合 MAY(可以)為空,也 MAY(可以)隨時間改變,但 MUST NOT(不得)因連線不同或同一連線中其他請求的副作用而變化。集合 MAY(可以)依請求攜帶的授權而異,例如只回傳呼叫者獲准範圍內的工具,因為憑證是每次請求的輸入,而非連線狀態。

伺服器 SHOULD(應該)以確定的順序回傳工具:只要工具集合未變,不同請求取得的順序就相同。這能讓用戶端可靠地快取清單,並在工具納入模型上下文時提高 LLM 提示詞快取命中率。

列出工具(Listing Tools)

用戶端以 tools/list 探索可用工具。此操作支援分頁與快取。

請求:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}

回應:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "complete",
    "tools": [
      {
        "name": "get_weather",
        "title": "Weather Information Provider",
        "description": "Get current weather information for a location",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name or zip code"
            }
          },
          "required": ["location"]
        },
        "icons": [
          {
            "src": "https://example.com/weather-icon.png",
            "mimeType": "image/png",
            "sizes": ["48x48"]
          }
        ]
      }
    ],
    "nextCursor": "next-page-cursor",
    "ttlMs": 300000,
    "cacheScope": "public"
  }
}

呼叫工具(Calling Tools)

用戶端以 tools/call 呼叫工具。請求:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "New York"
    }
  }
}

回應:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
      }
    ],
    "isError": false
  }
}

需要額外輸入(Input Required Tool Results)

伺服器 MAY(可以)以 InputRequiredResult 回應 tools/call,表示完成呼叫前需要額外輸入。這遵循多回合請求(MRTR)機制。用戶端帶回輸入結果重試時,會在參數中加入 inputResponses,以及伺服器先前提供的 requestState(若有)。

要求輸入的回應:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "resultType": "input_required",
    "inputRequests": {
      "github_login": {
        "method": "elicitation/create",
        "params": {
          "mode": "form",
          "message": "Please provide your GitHub username",
          "requestedSchema": {
            "type": "object",
            "properties": {
              "name": { "type": "string" }
            },
            "required": ["name"]
          }
        }
      }
    },
    "requestState": "eyJsb2NhdGlvbiI6Ik5ldyBZb3JrIn0..."
  }
}

攜帶輸入結果重試:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "New York"
    },
    "inputResponses": {
      "github_login": {
        "action": "accept",
        "content": {
          "name": "octocat"
        }
      }
    },
    "requestState": "eyJsb2NhdGlvbiI6Ik5ldyBZb3JrIn0..."
  }
}

重試時的 JSON-RPC id MUST(必須)與初始請求不同。

清單變更通知(List Changed Notification)

可用工具清單變更時,宣告 listChanged 的伺服器 SHOULD(應該)通知已開啟 subscriptions/listen 串流、且設定 toolsListChanged: true 的用戶端:

{
  "jsonrpc": "2.0",
  "method": "notifications/tools/list_changed"
}

訊息流程(Message Flow)

工具探索、選擇、呼叫與清單更新流程 用戶端向伺服器列出工具,模型選擇工具後,由用戶端呼叫並將結果交給模型。若支援清單變更通知,用戶端訂閱通知,收到變更時重新取得工具清單。 語言模型用戶端伺服器 探索:tools/list可用工具清單選擇要使用的工具呼叫:tools/call工具結果處理結果subscriptions/listen(toolsListChanged: true)notifications/subscriptions/acknowledgednotifications/tools/list_changed重新取得:tools/list更新後的工具清單 選用:listChanged 通知
依英文原文的循序圖重製。下半部只適用於支援清單變更通知的情況。

工具定義(Tool Definition)

  • name:工具的唯一識別碼。
  • title:選用、適合人類閱讀的顯示名稱。
  • description:適合人類閱讀的功能說明。
  • icons:選用的介面圖示陣列。
  • inputSchema:定義預期參數的 JSON Schema,遵循JSON Schema 使用指引。未指定 $schema 時預設為 2020-12,且 MUST(必須)是有效的 JSON Schema 物件,不得為 null。無參數工具可用 {"type":"object","additionalProperties":false}(建議,明確只接受空物件),或 {"type":"object"}(接受任何物件,包括含屬性的物件)。屬性 MAY(可以)加入 x-mcp-header 註記,將參數值暴露為 HTTP 標頭。
  • outputSchema:選用的輸出結構 JSON Schema,遵循相同使用指引;未指定 $schema 時預設為 2020-12。
  • annotations:描述工具行為的選用屬性。
工具註記的信任邊界

基於信任與安全考量,除非工具註記來自受信任的伺服器,用戶端 MUST(必須)將其視為不受信任。

工具名稱(Tool Names)

  • 名稱長度 SHOULD(應該)介於 1–128 個字元,包含兩端。
  • 名稱 SHOULD(應該)區分大小寫。
  • 名稱 SHOULD(應該)只使用 ASCII 大小寫字母、數字、底線、連字號與句點。
  • 名稱 SHOULD NOT(不應)包含空格、逗號或其他特殊字元。
  • 名稱在單一伺服器內 SHOULD(應該)唯一。
  • 有效名稱範例:getUser、DATA_EXPORT_v2、admin.tools.list。

唯一性只限於單一伺服器。彙整多個伺服器的用戶端或代理 MAY(可以)遇到同名工具,例如兩個伺服器都提供 search,並 SHOULD(應該)採用消除歧義的策略,例如加上伺服器識別碼前綴。serverInfo 中的 name 不保證跨伺服器唯一,SHOULD NOT(不應)單獨依賴它區分工具。

x-mcp-header

x-mcp-header 擴充屬性允許伺服器在使用 Streamable HTTP 傳輸時,把指定工具參數鏡射至 HTTP 標頭,讓負載平衡器、代理與 WAF 等網路中介設備不必解析請求本文,就能依參數路由及處理請求。

此屬性直接放在待鏡射屬性的 JSON Schema 內,其值指定產生的 Mcp-Param-{name} HTTP 標頭中的名稱部分。限制如下:

  • 值 MUST NOT(不得)為空。
  • 值 MUST(必須)符合 RFC 9110 §5.1 的 HTTP 欄位名稱語法 1*tchar。
  • MUST NOT(不得)包含控制字元,包括歸位字元(CR,\r)與換行字元(LF,\n)。
  • 同一 inputSchema 中的所有值 MUST(必須)在不區分大小寫時仍保持唯一。
  • MUST(必須)只套用於整數、字串或布林等基本型別。number 不允許;整數 MUST(必須)位於 IEEE754 雙精度浮點數可安全表示的整數範圍(−253+1 至 253−1)。
  • MUST(必須)只套用於從 schema 根部可靜態到達的屬性;完整路徑規則及從呼叫參數擷取標頭值的方式,見 工具參數自訂標頭。

Streamable HTTP 用戶端 MUST(必須)拒絕任何 x-mcp-header 值違反限制的工具定義,也就是 MUST(必須)將該工具排除於 tools/list 結果之外,並 SHOULD(應該)記錄含工具名稱與拒絕原因的警告。如此可避免單一格式錯誤的工具影響其他有效工具。使用 stdio 等其他傳輸方式的用戶端 MAY(可以)完全忽略此註記。

包含 x-mcp-header 的工具定義:

{
  "name": "execute_sql",
  "description": "Execute SQL on Google Cloud Spanner",
  "inputSchema": {
    "type": "object",
    "properties": {
      "region": {
        "type": "string",
        "description": "The region to execute the query in",
        "x-mcp-header": "Region"
      },
      "query": {
        "type": "string",
        "description": "The SQL query to execute"
      }
    },
    "required": ["region", "query"]
  }
}

以上範例以 "region": "us-west1" 呼叫時,用戶端會在 HTTP 請求加入 Mcp-Param-Region: us-west1。

不要將敏感參數鏡射到 HTTP 標頭

伺服器開發者 SHOULD NOT(不應)對密碼、API 金鑰、權杖或個人識別資訊使用 x-mcp-header,因為網路中介設備可以看見標頭值。

工具結果(Tool Result)

工具結果可包含結構化或非結構化內容。非結構化內容放在結果的 content 欄位,可同時包含不同型別的內容項目。

文字、圖片、音訊、資源連結及內嵌資源皆支援選用的註記,描述目標對象、優先順序及修改時間。格式與資源、提示詞使用的註記相同。

文字內容(Text Content)

{
  "type": "text",
  "text": "Tool result text"
}

圖片內容(Image Content)

{
  "type": "image",
  "data": "base64-encoded-data",
  "mimeType": "image/png",
  "annotations": {
    "audience": ["user"],
    "priority": 0.9
  }
}

音訊內容(Audio Content)

{
  "type": "audio",
  "data": "base64-encoded-audio-data",
  "mimeType": "audio/wav"
}

工具 MAY(可以)回傳資源連結以提供額外上下文或資料。此時回傳的是可供用戶端訂閱或擷取的 URI:

{
  "type": "resource_link",
  "uri": "file:///project/src/main.rs",
  "name": "main.rs",
  "description": "Primary application entry point",
  "mimeType": "text/x-rust"
}

資源連結支援與一般資源相同的註記,協助用戶端判斷如何使用。工具回傳的資源連結不保證出現在 resources/list 結果中。

內嵌資源(Embedded Resources)

資源 MAY(可以)透過適當的 URI 配置內嵌於結果,提供額外上下文或資料。使用內嵌資源的伺服器 SHOULD(應該)實作 resources 能力:

{
  "type": "resource",
  "resource": {
    "uri": "file:///project/src/main.rs",
    "mimeType": "text/x-rust",
    "text": "fn main() {\n    println!(\"Hello world!\");\n}",
    "annotations": {
      "audience": ["user", "assistant"],
      "priority": 0.7,
      "lastModified": "2025-05-03T14:30:00Z"
    }
  }
}

內嵌資源也支援與一般資源相同的註記。

結構化內容(Structured Content)

結構化內容是結果中 structuredContent 欄位的 JSON 值,可以是物件、陣列、字串、數字、布林或 null;若工具定義了 outputSchema,內容須符合該 schema。為保持向後相容,工具回傳結構化內容時 SHOULD(應該)也在 TextContent 區塊提供序列化的 JSON。

結構化結果與模型輸出

structuredContent 是伺服器產生的結果資料,與 LLM 的「結構化輸出」(受 schema 約束的模型生成)無關。

輸出結構描述(Output Schema)

工具可提供輸出 schema 以驗證結構化結果。若有提供,伺服器 MUST(必須)產生符合該 schema 的結果,用戶端 SHOULD(應該)依 schema 驗證結果。

包含輸出 schema 的工具:

{
  "name": "get_weather_data",
  "title": "Weather Data Retriever",
  "description": "Get current weather data for a location",
  "inputSchema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "City name or zip code"
      }
    },
    "required": ["location"]
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "temperature": {
        "type": "number",
        "description": "Temperature in celsius"
      },
      "conditions": {
        "type": "string",
        "description": "Weather conditions description"
      },
      "humidity": {
        "type": "number",
        "description": "Humidity percentage"
      }
    },
    "required": ["temperature", "conditions", "humidity"]
  }
}

此工具的有效回應:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "{\"temperature\": 22.5, \"conditions\": \"Partly cloudy\", \"humidity\": 65}"
      }
    ],
    "structuredContent": {
      "temperature": 22.5,
      "conditions": "Partly cloudy",
      "humidity": 65
    }
  }
}

輸出為陣列的工具:

{
  "name": "list_users",
  "title": "User List",
  "description": "Returns a list of all users",
  "inputSchema": {
    "type": "object",
    "properties": {}
  },
  "outputSchema": {
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "name": { "type": "string" },
        "email": { "type": "string" }
      },
      "required": ["id", "name", "email"]
    }
  }
}

陣列輸出的有效回應:

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "Found 2 users: Alice (alice@example.com) and Bob (bob@example.com)."
      }
    ],
    "structuredContent": [
      { "id": "1", "name": "Alice", "email": "alice@example.com" },
      { "id": "2", "name": "Bob", "email": "bob@example.com" }
    ]
  }
}

輸出 schema 可提供嚴格的回應驗證、方便與程式語言整合的型別資訊,以及解析和使用回傳資料的指引,幫助用戶端與 LLM 正確處理結果,並改善文件與開發體驗。

Schema 範例(Schema Examples)

使用預設 2020-12 schema

{
  "name": "calculate_sum",
  "description": "Add two numbers",
  "inputSchema": {
    "type": "object",
    "properties": {
      "a": { "type": "number" },
      "b": { "type": "number" }
    },
    "required": ["a", "b"]
  }
}

明確指定 draft-07 schema

{
  "name": "calculate_sum",
  "description": "Add two numbers",
  "inputSchema": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
      "a": { "type": "number" },
      "b": { "type": "number" }
    },
    "required": ["a", "b"]
  }
}

沒有參數的工具

{
  "name": "get_current_time",
  "description": "Returns the current server time",
  "inputSchema": {
    "type": "object",
    "additionalProperties": false
  }
}

具狀態工具(Stateful Tools)

非規範性設計指引

本節是工具設計指引。協定沒有狀態控制代碼(state handle)的概念;在傳輸層看來,控制代碼只是工具結果中的一般字串,以及後續工具呼叫的一般參數。

MCP 沒有協定層級的會話,伺服器不能依賴隱含的每連線狀態串起不同工具呼叫。若要跨呼叫維持購物車、開啟的瀏覽器上下文或資料庫交易等狀態,伺服器應由建立工具明確回傳控制代碼,後續呼叫再將它當成參數傳入。例如購物車伺服器可提供:

// → tools/call
{ "name": "create_basket", "arguments": {} }

// ← result
{
  "content": [{ "type": "text", "text": "Created basket bsk_a1b2c3" }],
  "structuredContent": { "basket_id": "bsk_a1b2c3" }
}

// → tools/call
{
  "name": "add_item",
  "arguments": { "basket_id": "bsk_a1b2c3", "sku": "..." }
}

模型負責在後續呼叫帶入 basket_id;伺服器以它為索引儲存購物車內容,並在每次呼叫時查詢。

設計控制代碼時應考慮:

  • 授權:對需要身分驗證的伺服器,控制代碼是名稱,不是授權能力;每次呼叫都應驗證呼叫者對該代碼的權限。對不驗證身分的伺服器,控制代碼實質上是持有者權杖,應有足夠的熵(例如 UUIDv4),並限制有效期限。
  • 不透明性:包含內部結構的代碼容易讓人解析或猜測;不透明的識別碼則不會。
  • 存活時間:控制代碼的存續時間超過單一連線,因此建立工具的說明應交代保留政策,例如「購物車閒置 24 小時後過期」,讓模型在建立狀態前得知。
  • 過期錯誤:使用過期或未知代碼的呼叫,應回傳明確指出原因的工具執行錯誤,讓模型透過重新建立狀態復原。

錯誤處理(Error Handling)

工具使用兩種錯誤回報機制:

協定錯誤

這類錯誤涉及請求本身,模型較難自行修正,包括未知工具、不符合 CallToolRequest schema 的格式錯誤請求,以及伺服器錯誤。它們以標準 JSON-RPC 錯誤回傳:

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32602,
    "message": "Unknown tool: invalid_tool_name"
  }
}

工具執行錯誤

這類錯誤提供可採取行動的回饋,讓模型調整參數後重試,例如 API 失敗、日期格式或數值範圍等輸入驗證錯誤,以及商業邏輯錯誤。它們以工具結果回傳,並設定 isError: true:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "Invalid departure date: must be in the future. Current date is 08/08/2025."
      }
    ],
    "isError": true
  }
}

用戶端 MAY(可以)將協定錯誤提供給模型,但較不容易成功復原;用戶端 SHOULD(應該)將工具執行錯誤提供給模型,以便自行修正。

安全考量(Security Considerations)

伺服器 MUST(必須)驗證所有工具輸入、實作適當的存取控制、限制工具呼叫速率,並清理工具輸出。

用戶端 SHOULD(應該):

  • 敏感操作要求使用者確認。
  • 呼叫伺服器前顯示工具輸入,避免惡意或意外的資料外洩。
  • 將工具結果提供給 LLM 前先驗證。
  • 依 inputSchema 與 outputSchema 驗證輸入及輸出時,遵循$ref 解析要求。
  • 為工具呼叫設定逾時。
  • 記錄工具使用情形以供稽核。