第四章 FastMCP 服务器框架之工具管理
目录
工具注册机制
FastMCP框架通过@tool装饰器实现工具的注册机制。该装饰器由FastMCP类提供,用于将普通函数注册为可调用的MCP工具。工具注册的核心流程由ToolManager类管理,其内部维护一个工具字典_tools,以工具名称为键存储工具实例。
当使用@tool()装饰函数时,会触发装饰器的decorator函数,该函数调用add_tool方法将函数转换为Tool对象并添加到工具管理器中。如果启用了warn_on_duplicate_tools设置且存在同名工具,系统会发出警告。工具名称默认使用函数名,但可通过name参数显式指定。
本节来源
工具调用流程
工具调用流程始于客户端发送tools/call请求,服务器端通过call_tool协议方法处理。该方法首先获取当前请求上下文,然后委托给ToolManager的call_tool方法执行具体调用。
ToolManager.call_tool首先通过工具名称查找对应的Tool实例,若未找到则抛出ToolError异常。找到工具后,调用Tool.run方法执行实际的函数调用。执行过程中会进行参数验证、上下文注入和结果转换。最终结果根据convert_result标志决定是否进行格式转换,然后返回给客户端。
图源
@tool装饰器详解
@tool装饰器是FastMCP框架中工具注册的核心组件,提供丰富的配置选项。装饰器支持同步和异步函数,通过检查函数是否为协程函数来自动识别执行模式。
装饰器参数包括:
name: 工具的程序化名称,默认为函数名title: 工具的可读标题,用于UI展示description: 工具功能描述annotations: 工具的附加注解信息icons: 工具的图标列表meta: 工具的元数据structured_output: 控制输出是否为结构化格式
装饰器会检查是否正确调用(即使用@tool()而非@tool),若使用错误会抛出TypeError。装饰器通过闭包返回原始函数,确保函数的正常调用行为不受影响。
本节来源
工具元数据提取与验证
工具元数据提取由func_metadata.py模块中的func_metadata函数负责。该函数分析函数签名,创建包含参数验证模型和输出模型的FuncMetadata对象。
输入验证通过创建ArgModelBase子类实现,该类继承自BaseModel,包含所有参数的类型注解和默认值。系统会检查参数名是否与BaseModel属性冲突,若冲突则使用别名避免警告。
输出验证根据返回类型注解自动配置。支持多种返回类型:
BaseModel子类:直接使用- 基本类型(str, int等):包装在包含
result字段的模型中 TypedDict:转换为Pydantic模型- 泛型类型(list, dict等):包装在
result字段中
系统使用StrictJsonSchema生成器确保JSON模式的有效性,任何警告都会转化为异常。
图源
Context上下文注入
Context上下文注入机制允许工具函数访问MCP核心功能。通过在函数参数中添加Context类型注解,系统会自动注入上下文对象。
find_context_parameter函数负责在函数签名中查找Context参数。它使用typing.get_type_hints解析类型注解,并支持Optional[Context]等泛型类型。找到参数后,Tool.run方法在调用函数时将上下文作为关键字参数传递。
Context类提供以下功能:
- 日志记录:
debug,info,warning,error方法 - 进度报告:
report_progress方法 - 资源访问:
read_resource方法 - 用户交互:
elicit方法 - 请求信息:
request_id,client_id属性
上下文对象在请求处理期间有效,确保工具只能在请求上下文中访问这些功能。
图源
结构化输出配置
结构化输出配置通过structured_output参数控制。该参数有三种模式:
None:根据返回类型注解自动检测True:强制创建结构化工具False:无条件创建非结构化工具
当启用结构化输出时,系统会根据返回类型创建相应的Pydantic模型。对于字典类型且键为字符串的情况,使用RootModel;对于其他类型,包装在包含result字段的模型中。
输出转换由FuncMetadata.convert_result方法处理。该方法根据配置决定返回格式:
- 无结构化输出:直接返回非结构化内容
- 有结构化输出:返回包含非结构化和结构化内容的元组
CallToolResult:直接返回,支持完全控制输出格式
系统会验证结构化输出是否符合outputSchema,确保数据完整性。
本节来源
工具冲突检测与覆盖策略
工具管理器通过warn_on_duplicate_tools设置控制冲突检测行为。当尝试添加同名工具时,系统会检查_tools字典中是否已存在该名称的工具。
如果存在冲突且warn_on_duplicate_tools为True,系统会记录警告但不会覆盖现有工具。这种策略确保工具注册的稳定性,防止意外覆盖。如果需要更新工具,必须先使用remove_tool方法显式删除旧工具。
工具名称冲突检测在add_tool方法中实现,使用字典的get方法检查是否存在同名工具。系统优先保留先注册的工具,确保注册顺序的确定性。
本节来源
list_tools与call_tool协议方法
list_tools和call_tool是MCP客户端交互的核心协议方法。list_tools返回所有可用工具的元数据,包括名称、描述、输入模式和输出模式。该方法将内部Tool对象转换为符合MCP规范的MCPTool对象。
call_tool处理工具调用请求,接收工具名称和参数字典。该方法通过ToolManager调度执行,确保输入验证、上下文注入和结果转换的正确执行。两个方法都通过_setup_handlers在服务器初始化时注册到MCP协议处理器中。
客户端通过ClientSession的对应方法与这些协议交互,实现工具发现和调用功能。
图源
实现示例
工具实现应遵循最佳实践,包括参数类型注解、错误处理和进度报告。对于需要上下文的工具,应添加Context参数以访问日志、进度和资源功能。
异步工具应使用async/await语法,确保非阻塞执行。结构化输出工具应提供清晰的返回类型注解,便于客户端解析。工具应处理可能的异常,并通过上下文记录错误信息。
示例工具应包含详细的文档字符串,说明功能、参数和返回值。对于复杂逻辑,应添加进度报告以提升用户体验。
本节来源
更多推荐


所有评论(0)