目录

  1. 简介
  2. 核心数据结构与语义
  3. 工具注册与装饰器机制
  4. 客户端调用流程
  5. 数据结构可视化对比
  6. 错误处理机制
  7. 性能优化建议
  8. 开发者集成指南

简介

MCP(Model Context Protocol)中的工具(Tool)是服务器向客户端暴露的功能接口,允许客户端通过结构化方式调用后端服务。本文档深入解析工具在MCP协议中的定义、实现机制及交互流程,涵盖从服务器端注册到客户端调用的完整生命周期。

核心数据结构与语义

协议模型:src.mcp.types.Tool

该类定义了MCP协议中工具的对外暴露模型,继承自BaseMetadata,包含以下核心字段:

  • name: 工具的程序化名称,用于唯一标识。
  • description: 工具功能的描述性说明。
  • inputSchema: 使用JSON Schema定义工具参数的输入结构。
  • outputSchema: 可选字段,定义工具输出的结构化格式。
  • title: 人类可读的标题,优先级高于name用于UI展示。
  • icons: 可选图标列表,用于前端界面展示。
  • annotations: 附加元信息,如ToolAnnotations.title在显示时优先于name

内部实现:src.mcp.server.fastmcp.tools.base.Tool

此为服务器内部使用的工具注册模型,封装了函数执行所需的所有元数据:

  • fn: 实际执行的可调用对象(函数或协程)。
  • parameters: 由func_metadata生成的参数JSON Schema。
  • fn_metadata: 包含参数验证和结果转换逻辑的元数据对象。
  • is_async: 标记工具是否为异步函数。
  • context_kwarg: 指定接收上下文对象的参数名。
  • output_schema: 通过@cached_property动态获取输出模式。
  • run(): 异步执行方法,负责参数验证、上下文注入和异常封装。

本节来源

工具注册与装饰器机制

工具通过装饰器@app.call_tool()@app.list_tools()注册到FastMCP服务器。from_function类方法将普通函数转换为Tool实例:

  1. 自动提取函数名、文档字符串作为namedescription
  2. 使用func_metadata分析函数签名,生成输入Schema。
  3. 判断函数是否为异步(_is_async_callable)。
  4. 支持structured_output参数控制输出模式。
  5. 注册时关联上下文注入参数(context_kwarg)。

示例中fetch_tool通过装饰器注册,其参数urlinputSchema严格定义。

本节来源

客户端调用流程

simple-chatbot为例,客户端调用工具的完整流程如下:

  1. 初始化连接:通过ClientSession建立与服务器的通信。
  2. 获取工具列表:调用list_tools()获取所有可用工具的元数据。
  3. 格式化工具信息:使用Tool.format_for_llm()将工具描述转换为LLM可理解的文本。
  4. LLM决策:LLM根据用户输入和工具描述决定是否调用工具及参数。
  5. 执行调用:通过call_tool(tool_name, arguments)发送调用请求。
  6. 结果处理:接收并解析工具返回结果,生成自然语言响应。

本节来源

数据结构可视化对比

映射
BaseMetadata
+name : str
+title : str | None
ToolProtocol
+description : str | None
+inputSchema : dict[str, Any]
+outputSchema : dict[str, Any] | None
+icons : list[Icon] | None
+annotations : ToolAnnotations | None
+meta : dict[str, Any] | None
ToolInternal
-fn : Callable
+name : str
+title : str | None
+description : str
+parameters : dict[str, Any]
+fn_metadata : FuncMetadata
+is_async : bool
+context_kwarg : str | None
+annotations : ToolAnnotations | None
+icons : list[Icon] | None
+meta : dict[str, Any] | None
+output_schema()
+from_function()
+run()

图源

错误处理机制

系统在多个层面实现了完善的错误处理:

  • 参数验证失败call_fn_with_arg_validation在执行前验证输入参数,不符合inputSchema将抛出异常。
  • 执行异常run()方法捕获所有异常并封装为ToolError,包含工具名和原始错误信息。
  • 客户端重试execute_tool()实现指数退避重试机制,增强系统鲁棒性。
  • 类型安全:Pydantic模型确保数据结构的完整性和类型一致性。

本节来源

性能优化建议

  1. 输出模式选择:对结构化数据使用structuredContent而非text,减少LLM解析开销。
  2. 异步执行:I/O密集型操作应实现为异步函数,提升并发处理能力。
  3. Schema精简:合理设计inputSchemaoutputSchema,避免过度复杂化。
  4. 缓存机制:对于幂等性操作,可结合idempotentHint实现结果缓存。
  5. 批量调用:支持批量工具调用以减少网络往返延迟。

开发者集成指南

  1. 定义工具函数:编写具有清晰参数和返回值的函数。
  2. 注册工具:使用@app.call_tool()装饰器注册,并通过@app.list_tools()暴露元数据。
  3. 完善Schema:为参数添加详细描述,确保inputSchema准确反映需求。
  4. 处理上下文:利用context_kwarg注入会话或请求上下文。
  5. 测试验证:通过simple-chatbot等示例客户端验证工具的可用性和正确性。

本节来源

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐