工具

协议版本:2025-03-26

模型上下文协议 (MCP) 允许服务器公开可由语言模型调用的工具。工具使模型能够与外部系统交互,例如查询数据库、调用 API 或执行计算。每个工具由名称唯一标识,并包括描述其架构的元数据。

用户交互模型

MCP 中的工具设计为模型控制,意味着语言模型可以根据其上下文理解和用户提示自动发现和调用工具。

然而,实现可以自由地通过适合其需求的任何接口模式公开工具——协议本身并不强制要求任何特定的用户交互模型。

警告

为了信任、安全和安全,应该始终有人类参与,并能够拒绝工具调用。

应用程序应该:

  • 提供清晰的 UI,显示哪些工具正在暴露给 AI 模型
  • 在调用工具时插入清晰的视觉指示器
  • 向用户展示确认提示以进行操作,以确保人类参与

功能

支持工具的服务器必须声明 tools 功能:

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

listChanged 指示当可用工具列表更改时服务器是否会发出通知。

协议消息

列出工具

要发现可用的工具,客户端发送 tools/list 请求。此操作支持分页。

请求:

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

响应:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get_weather",
        "description": "Get current weather information for a location",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "City name or zip code"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}

调用工具

要调用工具,客户端发送 tools/call 请求:

请求:

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

响应:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
      }
    ],
    "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 架构
  • annotations:描述工具行为的可选属性

警告

为了信任、安全和安全,除非工具注释来自受信任的服务器,否则客户端必须将工具注释视为不受信任。

工具结果

工具结果可以包含多个不同类型的内容项:

文本内容

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

图像内容

{
  "type": "image",
  "data": "base64-encoded-data",
  "mimeType": "image/png"
}

音频内容

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

嵌入资源

资源可以被嵌入,以提供额外的上下文或数据,位于客户端以后可以订阅或再次获取的 URI 后面:

{
  "type": "resource",
  "resource": {
    "uri": "resource://example",
    "mimeType": "text/plain",
    "text": "Resource content"
  }
}

错误处理

工具使用两种错误报告机制:

  1. 协议错误:用于以下问题的标准 JSON-RPC 错误:

    • 未知工具
    • 无效参数
    • 服务器错误
  2. 工具执行错误:在工具结果中报告,带有 isError: true:

    • API 失败
    • 无效的输入数据
    • 业务逻辑错误

示例协议错误:

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

示例工具执行错误:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Failed to fetch weather data: API rate limit exceeded"
      }
    ],
    "isError": true
  }
}

安全注意事项

  1. 服务器必须:

    • 验证所有工具输入
    • 实施适当的访问控制
    • 限制工具调用的速率
    • 清理工具输出
  2. 客户端应该:

    • 在敏感操作上提示用户确认
    • 在调用服务器之前向用户显示工具输入,以避免恶意或意外数据渗出
    • 在传递给 LLM 之前验证工具结果
    • 为工具调用实施超时
    • 记录工具使用情况以进行审计