Skip to content

工具(Tools)

协议版本: 2025-06-18

在 Model Context Protocol (MCP) 中,工具是强大的功能,允许语言模型与外部系统进行交互,如数据库、API 调用或执行计算。每个工具都有唯一的名称标识,并包含描述其模式的元数据。

1. 用户交互模型

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

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

WARNING

出于信任、安全和保障考虑,工具调用过程中应该始终有人工参与,能够拒绝工具调用。

应用程序应该:

  • 提供 UI 清楚地显示哪些工具被暴露给 AI 模型
  • 在工具被调用时插入清晰的视觉指示器
  • 向用户呈现操作确认提示,确保有人工参与

2. 能力声明

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

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

listChanged 表示当可用工具列表发生变化时,服务器是否会发出通知。

3. 协议消息

3.1 列出工具

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

请求:

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

响应:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "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"]
        }
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}

3.2 调用工具

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

请求:

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

响应:

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

3.3 列表变更通知

当可用工具列表发生变化时,声明了 listChanged 能力的服务器应该发送通知:

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

4. 消息流程

5. 数据类型

5.1 工具定义

工具定义包括:

  • name: 工具的唯一标识符
  • title: 可选的工具人类可读名称,用于显示目的
  • description: 功能的人类可读描述
  • inputSchema: 定义预期参数的 JSON Schema
  • outputSchema: 可选的定义预期输出结构的 JSON Schema
  • annotations: 描述工具行为的可选属性

WARNING

出于信任、安全和保障考虑,客户端必须将工具注解视为不可信的,除非它们来自可信的服务器。

5.2 工具结果

工具结果可能包含结构化非结构化内容。

非结构化内容在结果的 content 字段中返回,可以包含不同类型的多个内容项:

NOTE

所有内容类型(文本、图像、音频、资源链接和嵌入式资源)都支持可选的 注解,提供关于受众、优先级和修改时间的元数据。这与资源和提示使用的注解格式相同。

5.2.1 文本内容

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

5.2.2 图像内容

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

}

此示例演示了可选注解的使用。

5.2.3 音频内容

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

5.2.4 资源链接

工具可以返回到 资源 的链接,以提供额外的上下文或数据。在这种情况下,工具将返回一个可以被客户端订阅或获取的 URI:

json
{
  "type": "resource_link",
  "uri": "file:///project/src/main.rs",
  "name": "main.rs",
  "description": "Primary application entry point",
  "mimeType": "text/x-rust",
  "annotations": {
    "audience": ["assistant"],
    "priority": 0.9
  }
}

资源链接支持与常规资源相同的 资源注解,以帮助客户端了解如何使用它们。

NOTE

工具返回的资源链接不保证会出现在 resources/list 请求的

5.2.5 嵌入式资源

资源 可以使用合适的 URI 方案 嵌入以提供额外的上下文或数据。使用嵌入式资源的服务器应该实现 resources 能力:

json
{
  "type": "resource",
  "resource": {
    "uri": "file:///project/src/main.rs",
    "title": "Project Rust Main File",
    "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"
    }
  }
}

嵌入式资源支持与常规资源相同的 资源注解,以帮助客户端了解如何使用它们。

5.2.6 结构化内容

结构化内容作为 JSON 对象在结果的 structuredContent 字段中返回。

为了向后兼容,返回结构化内容的工具应该也在 TextContent 块中返回序列化的 JSON。

5.2.7 输出模式

工具还可以提供输出模式用于验证结构化结果。如果提供了输出模式:

  • 服务器必须提供符合此模式的结构化结果
  • 客户端应该对照此模式验证结构化结果

带有输出模式的工具示例:

json
{
  "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"]
  }
}

此工具的有效响应示例:

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

提供输出模式通过以下方式帮助客户端和 LLM 理解并正确处理结构化工具输出:

  • 启用对响应的严格模式验证
  • 为与编程语言的更好集成提供类型信息
  • 指导客户端和 LLM 正确解析和利用返回的数据
  • 支持更好的文档和开发者体验

6. 错误处理

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

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

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

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

协议错误示例:

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

工具执行错误示例:

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

7. 安全考虑

  1. 服务器必须

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

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