工具

協議版本: 2024-11-05

模型上下文協議(MCP)允許服務器公開可由語言模型調用的工具。工具使模型能夠與外部系統交互,如查詢數據庫、調用 API 或執行計算。每個工具由名稱唯一標識,幷包含描述其架構的元數據。

用戶交互模型

MCP 中的工具被設計為模型控制,這意味著語言模型可以根據其上下文理解和用戶的提示自動發現和調用工具。

然而,實現可以通過任何適合其需求的接口模式公開工具—協議本身不強制任何特定的用戶交互模型。

出於信任、安全和安全考慮,應該始終有一個人類參與,能夠拒絕工具調用。

應用程序應該

  • 提供 UI,明確向 AI 模型公開哪些工具
  • 在調用工具時插入清晰的視覺指示器
  • 向用戶呈現操作確認提示,以確保有人類參與

能力

支持工具的服務器必須聲明 tools 能力:

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

listChanged 表示服務器是否會在可用工具列表更改時發出通知。

協議消息

列出工具

要發現可用工具,客戶端發送 tools/list 請求。此操作支持分頁

請求:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list",
  "params": {
    "cursor": "可選的遊標值"
  }
}

響應:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get_weather",
        "description": "獲取位置的當前天氣信息",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "城市名稱或郵政編碼"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "nextCursor": "下一頁遊標"
  }
}

調用工具

要調用工具,客戶端發送 tools/call 請求:

請求:

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

響應:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "紐約的當前天氣:\n溫度:72°F\n天氣狀況:部分多雲"
      }
    ],
    "isError": false
  }
}

列表更改通知

當可用工具列表更改時,聲明瞭 listChanged 能力的服務器應該發送通知:

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

消息流程

  sequenceDiagram
    participant LLM
    participant Client
    participant Server

    Note over Client,Server: 發現
    Client->>Server: tools/list
    Server-->>Client: 工具列表

    Note over Client,LLM: 工具選擇
    LLM->>Client: 選擇要使用的工具

    Note over Client,Server: 調用
    Client->>Server: tools/call
    Server-->>Client: 工具結果
    Client->>LLM: 處理結果

    Note over Client,Server: 更新
    Server--)Client: tools/list_changed
    Client->>Server: tools/list
    Server-->>Client: 更新的工具

數據類型

工具

工具定義包括:

  • name:工具的唯一標識符
  • description:功能的人類可讀描述
  • inputSchema:定義預期參數的 JSON Schema

工具結果

工具結果可以包含不同類型的多個內容項:

文本內容

{
  "type": "text",
  "text": "工具結果文本"
}

圖像內容

{
  "type": "image",
  "data": "base64編碼數據",
  "mimeType": "image/png"
}

嵌入資源

資源可以被嵌入,以提供額外的上下文或數據,通過 URI 可以被客戶端稍後訂閱或再次獲取:

{
  "type": "resource",
  "resource": {
    "uri": "resource://example",
    "mimeType": "text/plain",
    "text": "資源內容"
  }
}

錯誤處理

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

  1. 協議錯誤:用於以下問題的標準 JSON-RPC 錯誤:

    • 未知工具
    • 無效參數
    • 服務器錯誤
  2. 工具執行錯誤:在工具結果中報告,帶有 isError: true

    • API 失敗
    • 無效輸入數據
    • 業務邏輯錯誤

協議錯誤示例:

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32602,
    "message": "未知工具:invalid_tool_name"
  }
}

工具執行錯誤示例:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "無法獲取天氣數據:API 速率限制已超出"
      }
    ],
    "isError": true
  }
}

安全考慮

  1. 服務器必須

    • 驗證所有工具輸入
    • 實現適當的訪問控制
    • 限制工具調用的速率
    • 淨化工具輸出
  2. 客戶端應該

    • 在敏感操作上提示用戶確認
    • 在調用服務器之前向用戶顯示工具輸入,以避免惡意或意外的數據洩露
    • 在傳遞給 LLM 之前驗證工具結果
    • 為工具調用實現超時
    • 記錄工具使用情況以供審計