Skip to Content

工具是模型上下文协议(MCP)中强大的基础组件,它允许服务端向客户端暴露可执行功能。通过工具,LLM可以与外部系统交互、执行计算并在现实世界中采取行动。

工具被设计为模型控制的,这意味着服务端向客户端暴露工具的目的是让AI模型能够自动调用它们(需经人工审核批准)。

概述

MCP中的工具允许服务端暴露可执行函数,这些函数可以被客户端调用并被LLM用来执行操作。工具的关键特性包括:

  • 发现:客户端可以通过tools/list端点列出可用工具
  • 调用:使用tools/call端点调用工具,服务端执行请求的操作并返回结果
  • 灵活性:工具范围涵盖从简单计算到复杂API交互

资源类似,工具通过唯一名称标识,可以包含描述来指导使用。但与资源不同,工具代表可以修改状态或与外部系统交互的动态操作。

工具定义结构

每个工具的定义结构如下:

{ name: string; // 工具的唯一标识符 description?: string; // 人类可读的描述 inputSchema: { // 工具参数的JSON Schema type: "object", properties: { ... } // 工具特定参数 } }

实现工具

以下是在MCP服务端中实现基础工具的示例:

const server = new Server({ name: "example-server", version: "1.0.0" }, { capabilities: { tools: {} } }); // 定义可用工具 server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [{ name: "calculate_sum", description: "将两个数字相加", inputSchema: { type: "object", properties: { a: { type: "number" }, b: { type: "number" } }, required: ["a", "b"] } }] }; }); // 处理工具执行 server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === "calculate_sum") { const { a, b } = request.params.arguments; return { content: [ { type: "text", text: String(a + b) } ] }; } throw new Error("未找到工具"); });

工具模式示例

以下是服务端可以提供的一些工具类型示例:

系统操作

与本地系统交互的工具:

{ name: "execute_command", description: "运行shell命令", inputSchema: { type: "object", properties: { command: { type: "string" }, args: { type: "array", items: { type: "string" } } } } }

API集成

封装外部API的工具:

{ name: "github_create_issue", description: "创建GitHub issue", inputSchema: { type: "object", properties: { title: { type: "string" }, body: { type: "string" }, labels: { type: "array", items: { type: "string" } } } } }

数据处理

转换或分析数据的工具:

{ name: "analyze_csv", description: "分析CSV文件", inputSchema: { type: "object", properties: { filepath: { type: "string" }, operations: { type: "array", items: { enum: ["sum", "average", "count"] } } } } }

最佳实践

实现工具时:

  1. 提供清晰、描述性的名称和说明
  2. 为参数使用详细的JSON Schema定义
  3. 在工具描述中包含示例以演示模型应如何使用
  4. 实现适当的错误处理和验证
  5. 对长时间操作使用进度报告
  6. 保持工具操作专注和原子化
  7. 记录预期的返回值结构
  8. 实现适当的超时机制
  9. 对资源密集型操作进行速率限制
  10. 记录工具使用情况以便调试和监控

安全考虑

暴露工具时:

输入验证

  • 根据schema验证所有参数
  • 净化文件路径和系统命令
  • 验证URL和外部标识符
  • 检查参数大小和范围
  • 防止命令注入

访问控制

  • 在需要时实施身份验证
  • 使用适当的授权检查
  • 审计工具使用情况
  • 限制请求速率
  • 监控滥用行为

错误处理

  • 不要向客户端暴露内部错误
  • 记录与安全相关的错误
  • 适当处理超时
  • 错误后清理资源
  • 验证返回值

工具发现与更新

MCP支持动态工具发现:

  1. 客户端可以随时列出可用工具
  2. 服务端可以通过notifications/tools/list_changed通知客户端工具变更
  3. 工具可以在运行时添加或删除
  4. 工具定义可以更新(需谨慎操作)

错误处理

工具错误应在结果对象中报告,而不是作为MCP协议级错误。这允许LLM查看并可能处理错误。当工具遇到错误时:

  1. 在结果中设置isErrortrue
  2. content数组中包含错误详情

以下是工具错误处理的正确示例:

try { // 工具操作 const result = performOperation(); return { content: [ { type: "text", text: `操作成功: ${result}` } ] }; } catch (error) { return { isError: true, content: [ { type: "text", text: `错误: ${error.message}` } ] }; }

这种方法允许LLM看到发生了错误,并可能采取纠正措施或请求人工干预。

测试工具

全面的工具测试策略应涵盖:

  • 功能测试:验证工具在有效输入下正确执行,并正确处理无效输入
  • 集成测试:使用真实和模拟依赖项测试工具与外部系统的交互
  • 安全测试:验证身份验证、授权、输入净化和速率限制
  • 性能测试:检查高负载下的行为、超时处理和资源清理
  • 错误处理:确保工具通过MCP协议正确报告错误并清理资源
最后更新于: