【MCP协议】服务端特性:工具调用

163 阅读3分钟

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

用户交互模型

MCP中的工具采用模型驱动设计原则,即语言模型能够基于其上下文理解能力和用户提示,自动发现并调用相关工具。

不过具体实现时,开发者可自由选择最适合其应用场景的工具调用方式——该协议本身并不限定特定的交互模式。

出于信任与安全考量,系统应当始终保持"人在回路"(Human-in-the-loop)机制,保留否决工具调用的权限。

应用实现时应当:

  • 透明化工具暴露:在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": "获取指定地区的实时天气信息",
        "inputSchema": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "城市名或邮政编码"
            }
          },
          "required": ["location"]
        }
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}

工具调用

客户端通过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温度:22℃\n天气状况:多云"
      }
    ],
    "isError"false
  }
}

列表变更通知

当工具列表更新时,支持listChanged的服务器应推送通知:

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

消息交互流程

mcp_tools.png

数据类型

Tool

工具定义包含以下字段:

  • name: 工具的唯一标识符
  • description: 工具功能的可读描述
  • inputSchema: 定义预期参数的JSON Schema
  • annotations: 描述工具行为的可选属性

出于信任与安全考虑,客户端必须将工具注解视为不可信内容(除非来自可信服务器)。

Tool Result

工具结果可包含多种类型的内容项:

文本内容
{
  "type": "text",
  "text": "Tool result text"
}
图片内容
{
  "type": "image",
  "data": "Base64编码数据",
  "mimeType": "image/png"
}
音频内容
{
  "type": "audio",
  "data": "Base64编码音频数据",
  "mimeType": "audio/wav"
}
嵌入式资源 (Embedded Resources)

可通过URI嵌入可订阅或后续获取的附加资源:

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

错误处理

工具调用采用双重错误报告机制:

  1. 协议级错误:标准JSON-RPC错误码,包括:
  • 未知工具
  • 无效参数
  • 服务端错误

示例协议错误:

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

2. 工具执行错误:通过isError: true标识的业务错误:

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

示例执行错误:

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

安全规范

  1. 服务端必须:
  • 验证所有工具输入参数
  • 实施严格的访问控制
  • 对工具调用进行速率限制
  • 对输出内容进行安全过滤
  1. 客户端应当:
  • 敏感操作需用户二次确认
  • 调用前向用户展示输入参数(防止恶意数据外泄)
  • 工具返回结果需验证后再传递给LLM
  • 设置工具调用超时机制
  • 保留完整的操作审计日志