工具 
使LLM能够通过您的服务器执行操作
工具是model context protocol(MCP)中的一个强大原语,使服务器能够向客户端公开可执行的功能。通过工具,LLM可以与外部系统交互、执行计算并在现实世界中采取行动。
提示
工具被设计为模型控制的,这意味着工具从服务器暴露给客户端时,AI模型能够自动调用它们(在人工参与授权的情况下)。
概述 
MCP中的工具允许服务器公开可执行的函数,这些函数可以被客户端调用并被LLM用来执行操作。工具的关键特性包括:
- 发现:客户端可以通过tools/list端点列出可用工具
- 调用:工具通过tools/call端点调用,服务器执行请求的操作并返回结果
- 灵活性:工具可以从简单的计算到复杂的API交互
与资源一样,工具由唯一的名称标识,并可以包含描述来指导其使用。但是,与资源不同,工具代表可以修改状态或与外部系统交互的动态操作。
工具定义结构 
每个工具都使用以下结构定义:
json
{
  name: string;          // Unique identifier for the tool
  description?: string;  // Human-readable description
  inputSchema: {         // JSON Schema for the tool's parameters
    type: "object",
    properties: { ... }  // Tool-specific parameters
  }
}实现工具 
以下是在MCP服务器中实现基本工具的示例:
typescript
const server = new Server({
  name: "example-server",
  version: "1.0.0"
}, {
  capabilities: {
    tools: {}
  }
});
// Define available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [{
      name: "calculate_sum",
      description: "Add two numbers together",
      inputSchema: {
        type: "object",
        properties: {
          a: { type: "number" },
          b: { type: "number" }
        },
        required: ["a", "b"]
      }
    }]
  };
});
// Handle tool execution
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("Tool not found");
});python
app = Server("example-server")
@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [
        types.Tool(
            name="calculate_sum",
            description="Add two numbers together",
            inputSchema={
                "type": "object",
                "properties": {
                    "a": {"type": "number"},
                    "b": {"type": "number"}
                },
                "required": ["a", "b"]
            }
        )
    ]
@app.call_tool()
async def call_tool(
    name: str,
    arguments: dict
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
    if name == "calculate_sum":
        a = arguments["a"]
        b = arguments["b"]
        result = a + b
        return [types.TextContent(type="text", text=str(result))]
    raise ValueError(f"Tool not found: {name}")工具示例模式 
以下是服务器可以提供的一些工具类型示例:
系统操作 
与本地系统交互的工具:
json
{
  name: "execute_command",
  description: "Run a shell command",
  inputSchema: {
    type: "object",
    properties: {
      command: { type: "string" },
      args: { type: "array", items: { type: "string" } }
    }
  }
}API集成 
封装外部API的工具:
json
{
  name: "github_create_issue",
  description: "Create a GitHub issue",
  inputSchema: {
    type: "object",
    properties: {
      title: { type: "string" },
      body: { type: "string" },
      labels: { type: "array", items: { type: "string" } }
    }
  }
}数据处理 
转换或分析数据的工具:
json
{
  name: "analyze_csv",
  description: "Analyze a CSV file",
  inputSchema: {
    type: "object",
    properties: {
      filepath: { type: "string" },
      operations: {
        type: "array",
        items: {
          enum: ["sum", "average", "count"]
        }
      }
    }
  }
}最佳实践 
在实现工具时:
- 提供清晰、描述性的工具名称和描述
- 使用详细的JSON Schema定义参数
- 在工具描述中包含示例,以演示模型应如何使用它们
- 实现适当的错误处理和验证
- 对长时间运行的操作使用进度报告
- 保持工具操作的重点和原子性
- 记录预期的返回值结构
- 实现适当的超时机制
- 考虑资源密集型操作的速率限制
- 记录工具使用情况以进行调试和监控
安全注意事项 
在公开工具时:
输入验证 
- 根据schema验证所有参数
- 清理文件路径和系统命令
- 验证URL和外部标识符
- 检查参数大小和范围
- 防止命令注入
访问控制 
- 在需要时实现身份验证
- 使用适当的授权检查
- 审计工具使用情况
- 限制请求速率
- 监控滥用行为 
错误处理 
- 不要向客户端暴露内部错误
- 记录与安全相关的错误
- 适当处理超时
- 错误后清理资源
- 验证返回值
工具发现和更新 
MCP支持动态工具发现:
- 客户端可以随时列出可用工具
- 服务器可以使用notifications/tools/list_changed通知客户端工具变更
- 工具可以在运行时添加或删除
- 工具定义可以更新(但应谨慎进行)
错误处理 
工具错误应在结果对象中报告,而不是作为MCP协议级别的错误。这允许LLM查看并可能处理错误。当工具遇到错误时:
- 在结果中将isError设置为true
- 在content数组中包含错误详细信息
以下是工具正确错误处理的示例:
typescript
try {
  // Tool operation
  const result = performOperation();
  return {
    content: [
      {
        type: "text",
        text: `Operation successful: ${result}`
      }
    ]
  };
} catch (error) {
  return {
    isError: true,
    content: [
      {
        type: "text",
        text: `Error: ${error.message}`
      }
    ]
  };
}python
try:
    # Tool operation
    result = perform_operation()
    return types.CallToolResult(
        content=[
            types.TextContent(
                type="text",
                text=f"Operation successful: {result}"
            )
        ]
    )
except Exception as error:
    return types.CallToolResult(
        isError=True,
        content=[
            types.TextContent(
                type="text",
                text=f"Error: {str(error)}"
            )
        ]
    )这种方法允许LLM看到发生了错误,并可能采取纠正措施或请求人工干预。
测试工具 
MCP工具的全面测试策略应涵盖:
- 功能测试:验证工具能够正确执行有效输入并适当处理无效输入
- 集成测试:使用真实和模拟的依赖项测试工具与外部系统的交互
- 安全测试:验证身份验证、授权、输入清理和速率限制
- 性能测试:检查负载下的行为、超时处理和资源清理
- 错误处理:确保工具通过MCP协议正确报告错误并清理资源