1. 什么是工具? #
工具(Tools)是 MCP 服务器暴露的可执行函数,供语言模型根据对话内容自动发现并调用。模型通过工具与外部系统交互,如查天气、写文件、调 API。
协议版本:2025-11-25
| 通俗理解 | 说明 |
|---|---|
| 模型控制 | 由 LLM 根据上下文决定是否调用、调用哪些工具 |
| 函数调用 | 每个工具有名称、描述、参数模式(inputSchema) |
| 需人工参与 | 应用应当展示工具调用、提供确认或拒绝能力 |
用户交互建议:应用应当在 UI 中展示已暴露的工具、在调用时给出明显提示,并对敏感操作提供确认或拒绝。
2. 本章你将学到 #
- 工具的能力声明与协议消息
- 如何列出、调用工具
- 工具定义(inputSchema、outputSchema)
- 工具结果类型、错误处理与安全要点
3. 典型流程 #
用户问「巴黎天气怎么样?」→ 客户端将工具列表(含 get_weather)发给 LLM → LLM 决定调用 get_weather(location="Paris") → 客户端发 tools/call → 服务器执行并返回结果 → 客户端将结果交给 LLM → LLM 生成自然语言回复。
4. 能力 #
服务器必须声明 tools 能力:
{
"capabilities": {
"tools": {
"listChanged": true
}
}
}| 字段 | 说明 |
|---|---|
listChanged |
为 true 时,工具列表变化时应当发送 notifications/tools/list_changed |
5. 协议消息 #
5.1 列出工具(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",
"title": "Weather Information Provider",
"description": "Get current weather for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
],
"nextCursor": "next-page-cursor"
}
}5.2 调用工具(tools/call) #
请求:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "location": "Paris" }
}
}响应:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "Paris: 18°C, partly cloudy"
}
],
"isError": false
}
}5.3 列表变更通知 #
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed"
}6. 流程示意 #
sequenceDiagram
participant L as 大语言模型
participant C as 客户端
participant S as 服务器
C->>S: tools/list
S-->>C: 工具列表
L->>C: 选择工具 get_weather(location="Paris")
C->>S: tools/call
S-->>C: 工具结果
C-->>L: 结果
L-->>C: 自然语言回复
7. 工具定义 #
7.1 字段 #
| 字段 | 要求 | 说明 |
|---|---|---|
name |
必须 | 唯一标识符,1–128 字符,建议用 getUser、data_export_v2 等格式 |
description |
必须 | 功能描述 |
inputSchema |
必须 | 参数 JSON Schema,遵循 JSON Schema 用法 |
title |
可选 | 显示名称 |
outputSchema |
可选 | 输出 JSON Schema |
icons |
可选 | 图标数组 |
7.2 示例:有参数工具 #
{
"name": "calculate_sum",
"description": "Add two numbers",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
}7.3 示例:无参数工具 #
{
"name": "get_current_time",
"description": "Returns the current server time",
"inputSchema": {
"type": "object",
"additionalProperties": false
}
}8. 工具结果 #
8.1 内容类型 #
| 类型 | 说明 |
|---|---|
text |
纯文本 |
image |
图像(base64 + mimeType) |
audio |
音频(base64 + mimeType) |
resource_link |
指向 资源 的 URI |
resource |
嵌入资源(需服务器实现 resources 能力) |
示例:文本
{ "type": "text", "text": "Paris: 18°C, partly cloudy" }示例:资源链接
{
"type": "resource_link",
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"description": "Primary application entry point"
}8.2 结构化输出(outputSchema) #
工具可定义 outputSchema,结果同时放在 content(文本)和 structuredContent(JSON)中:
{
"content": [
{ "type": "text", "text": "{\"temperature\": 22.5, \"conditions\": \"Partly cloudy\"}" }
],
"structuredContent": {
"temperature": 22.5,
"conditions": "Partly cloudy",
"humidity": 65
}
}8.3 错误标记 #
工具执行失败时,在结果中设置 isError: true,错误信息仍放在 content 中,便于 LLM 自我纠正并重试:
{
"content": [
{
"type": "text",
"text": "Invalid departure date: must be in the future."
}
],
"isError": true
}9. 错误处理 #
| 类型 | 情况 | 示例 |
|---|---|---|
| 协议错误 | 未知工具、格式错误、服务端错误 | JSON-RPC error 对象 |
| 工具执行错误 | API 失败、输入验证、业务逻辑 | result.isError: true,内容在 content 中 |
协议错误示例:
{
"jsonrpc": "2.0",
"id": 3,
"error": {
"code": -32602,
"message": "Unknown tool: invalid_tool_name"
}
}工具执行错误示例:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"content": [
{
"type": "text",
"text": "Invalid departure date: must be in the future. Current date is 08/08/2025."
}
],
"isError": true
}
}10. 安全要点 #
| 角色 | 要点 |
|---|---|
| 服务器 | 必须验证输入;实施访问控制;速率限制;清理输出 |
| 客户端 | 应当对敏感操作提示确认;展示工具输入;验证结果;超时;记录审计 |