1+ ---
2+ title: 工具
3+ type: docs
4+ weight: 40
5+ ---
6+
7+ <Info>**协议修订**:2024-11-05</Info>
8+
9+ 模型上下文协议(MCP)允许服务器暴露可以被语言模型调用的工具。这些工具使模型能够与外部系统交互,例如查询数据库、调用 API 或执行计算。每个工具由一个唯一名称标识,并包含描述其模式的元数据。
10+
11+ ## 用户交互模型
12+
13+ MCP 中的工具设计为由**模型控制**,这意味着语言模型可以根据其上下文理解和用户的提示自动发现并调用工具。
14+
15+ 然而,实现可以自由地通过任何适合其需求的接口模式暴露工具——协议本身不强制任何特定的用户交互模型。
16+
17+ <Warning>
18+
19+ 出于信任、安全和隐私的考虑,**始终**应该有一个人在调用工具的流程中,具备拒绝调用的能力。
20+
21+ 应用程序**应该**:
22+
23+ - 提供明确显示哪些工具暴露给 AI 模型的用户界面
24+ - 在调用工具时插入清晰的视觉指示
25+ - 在执行操作时向用户显示确认提示,以确保人在流程中
26+
27+ </Warning>
28+
29+ ## 功能
30+
31+ 支持工具的服务器**必须**声明 `tools` 能力:
32+
33+ ```json
34+ {
35+ "capabilities": {
36+ "tools": {
37+ "listChanged": true
38+ }
39+ }
40+ }
41+ ```
42+
43+ `listChanged` 表示当可用工具列表发生变化时,服务器是否会发送通知。
44+
45+ ## 协议消息
46+
47+ ### 列出工具
48+
49+ 要发现可用工具,客户端发送 `tools/list` 请求。该操作支持[分页](/specification/2024-11-05/server/utilities/pagination)。
50+
51+ **请求:**
52+
53+ ```json
54+ {
55+ "jsonrpc": "2.0",
56+ "id": 1,
57+ "method": "tools/list",
58+ "params": {
59+ "cursor": "可选的游标值"
60+ }
61+ }
62+ ```
63+
64+ **响应:**
65+
66+ ```json
67+ {
68+ "jsonrpc": "2.0",
69+ "id": 1,
70+ "result": {
71+ "tools": [
72+ {
73+ "name": "get_weather",
74+ "description": "获取某个地点的当前天气信息",
75+ "inputSchema": {
76+ "type": "object",
77+ "properties": {
78+ "location": {
79+ "type": "string",
80+ "description": "城市名称或邮编"
81+ }
82+ },
83+ "required": ["location"]
84+ }
85+ }
86+ ],
87+ "nextCursor": "下一页游标"
88+ }
89+ }
90+ ```
91+
92+ ### 调用工具
93+
94+ 要调用工具,客户端发送 `tools/call` 请求:
95+
96+ **请求:**
97+
98+ ```json
99+ {
100+ "jsonrpc": "2.0",
101+ "id": 2,
102+ "method": "tools/call",
103+ "params": {
104+ "name": "get_weather",
105+ "arguments": {
106+ "location": "纽约"
107+ }
108+ }
109+ }
110+ ```
111+
112+ **响应:**
113+
114+ ```json
115+ {
116+ "jsonrpc": "2.0",
117+ "id": 2,
118+ "result": {
119+ "content": [
120+ {
121+ "type": "text",
122+ "text": "纽约当前天气:\n温度:72°F\n天气状况:多云"
123+ }
124+ ],
125+ "isError": false
126+ }
127+ }
128+ ```
129+
130+ ### 工具列表变更通知
131+
132+ 当可用工具列表发生变化时,声明了 `listChanged` 能力的服务器**应该**发送通知:
133+
134+ ```json
135+ {
136+ "jsonrpc": "2.0",
137+ "method": "notifications/tools/list_changed"
138+ }
139+ ```
140+
141+ ## 消息流程
142+
143+ ```mermaid
144+ sequenceDiagram
145+ participant LLM
146+ participant Client
147+ participant Server
148+
149+ Note over Client,Server: 发现
150+ Client->>Server: tools/list
151+ Server-->>Client: 工具列表
152+
153+ Note over Client,LLM: 工具选择
154+ LLM->>Client: 选择要使用的工具
155+
156+ Note over Client,Server: 调用
157+ Client->>Server: tools/call
158+ Server-->>Client: 工具结果
159+ Client->>LLM: 处理结果
160+
161+ Note over Client,Server: 更新
162+ Server--)Client: tools/list_changed
163+ Client->>Server: tools/list
164+ Server-->>Client: 更新后的工具列表
165+ ```
166+
167+ ## 数据类型
168+
169+ ### 工具(Tool)
170+
171+ 一个工具定义包括:
172+
173+ - `name`:工具的唯一标识符
174+ - `description`:功能的可读性描述
175+ - `inputSchema`:定义预期参数的 JSON Schema
176+
177+ ### 工具结果(Tool Result)
178+
179+ 工具结果可以包含多个不同类型的内容项:
180+
181+ #### 文本内容
182+
183+ ```json
184+ {
185+ "type": "text",
186+ "text": "工具结果文本"
187+ }
188+ ```
189+
190+ #### 图像内容
191+
192+ ```json
193+ {
194+ "type": "image",
195+ "data": "base64编码的数据",
196+ "mimeType": "image/png"
197+ }
198+ ```
199+
200+ #### 嵌入式资源
201+
202+ [资源](/specification/2024-11-05/server/resources) **可以**嵌入,以提供额外的上下文或数据,通过客户端稍后可以订阅或再次获取的 URI:
203+
204+ ```json
205+ {
206+ "type": "resource",
207+ "resource": {
208+ "uri": "resource://example",
209+ "mimeType": "text/plain",
210+ "text": "资源内容"
211+ }
212+ }
213+ ```
214+
215+ ## 错误处理
216+
217+ 工具使用两种错误报告机制:
218+
219+ 1. **协议错误**:标准的 JSON-RPC 错误,用于以下问题:
220+ - 未知工具
221+ - 参数无效
222+ - 服务器错误
223+
224+ 2. **工具执行错误**:在工具结果中使用 `isError: true` 报告:
225+ - API 调用失败
226+ - 输入数据无效
227+ - 业务逻辑错误
228+
229+ 示例协议错误:
230+
231+ ```json
232+ {
233+ "jsonrpc": "2.0",
234+ "id": 3,
235+ "error": {
236+ "code": -32602,
237+ "message": "未知工具:invalid_tool_name"
238+ }
239+ }
240+ ```
241+
242+ 示例工具执行错误:
243+
244+ ```json
245+ {
246+ "jsonrpc": "2.0",
247+ "id": 4,
248+ "result": {
249+ "content": [
250+ {
251+ "type": "text",
252+ "text": "无法获取天气数据:API 调用频率超出限制"
253+ }
254+ ],
255+ "isError": true
256+ }
257+ }
258+ ```
259+
260+ ## 安全考虑
261+
262+ 1. 服务器**必须**:
263+ - 验证所有工具输入
264+ - 实现适当的访问控制
265+ - 对工具调用进行速率限制
266+ - 对工具输出进行清理
267+
268+ 2. 客户端**应该**:
269+ - 对敏感操作提示用户确认
270+ - 在调用服务器前向用户显示工具输入,以防止恶意或意外的数据泄露
271+ - 在传递给 LLM 前验证工具结果
272+ - 为工具调用实现超时机制
273+ - 记录工具使用情况以便审计
0 commit comments