第四章 FastMCP 服务器框架之工具注册机制
目录
- 工具注册流程概述
- 核心组件分析
- @tool装饰器实现原理
- 元数据提取与参数Schema生成
- 结构化输出判定逻辑
- 上下文注入机制
- 同步/异步函数注册
- 工具注册示例
工具注册流程概述
FastMCP框架的工具注册机制通过@tool装饰器和ToolManager.add_tool方法实现,形成了一套完整的工具注册与管理流程。该机制允许开发者通过简单的装饰器语法将普通函数注册为可调用的MCP工具,同时支持丰富的元数据配置和类型验证功能。
工具注册的核心流程始于FastMCP类的tool方法,该方法作为装饰器工厂返回一个装饰器函数。当开发者使用@server.tool()装饰一个函数时,该装饰器会调用add_tool方法,将函数及其配置参数传递给ToolManager进行处理。ToolManager通过Tool.from_function静态方法创建Tool实例,并将其存储在内部的工具字典中,完成注册过程。
本节来源
- server.py
- tool_manager.py
核心组件分析
工具注册机制涉及多个核心组件的协同工作,包括ToolManager、Tool、FuncMetadata和上下文注入工具等。这些组件共同构成了一个完整的工具注册与执行框架。
图源
- server.py
- tool_manager.py
- base.py
- func_metadata.py
- context_injection.py
本节来源
- tool_manager.py
- base.py
@tool装饰器实现原理
@tool装饰器是FastMCP框架中工具注册的核心入口,其实现基于Python的装饰器模式。该装饰器由FastMCP类的tool方法提供,返回一个闭包函数作为实际的装饰器。
tool方法接受多个可选参数,包括name、title、description、annotations、icons、meta和structured_output,这些参数用于配置工具的元数据。当装饰器被调用时,它首先检查是否直接传递了函数而非调用装饰器,以防止使用错误。然后返回一个decorator函数,该函数接收被装饰的函数作为参数。
图源
- server.py
- tool_manager.py
- base.py
本节来源
- server.py
元数据提取与参数Schema生成
工具注册过程中的元数据提取和参数Schema生成是通过func_metadata函数实现的,该函数位于func_metadata.py文件中。这个函数是整个工具注册机制的核心,负责从函数签名中提取类型信息并生成相应的Pydantic模型。
func_metadata函数首先通过_get_typed_signature获取函数的签名,然后遍历所有参数,为每个参数创建相应的FieldInfo。对于参数名与BaseModel属性冲突的情况,函数会使用别名机制避免命名冲突。接着,使用create_model动态创建一个继承自ArgModelBase的Pydantic模型,该模型用于验证和解析传入的参数。
图源
- func_metadata.py
本节来源
- func_metadata.py
结构化输出判定逻辑
结构化输出的判定逻辑是工具注册机制中的一个重要特性,它决定了工具的输出是否需要进行结构化处理。这一逻辑主要由structured_output参数控制,该参数有三种可能的值:True、False和None。
当structured_output为None时,系统会根据函数的返回值类型注解自动判断是否需要结构化输出。如果返回值类型注解为空且structured_output为True,系统会抛出InvalidSignature异常,因为无法为无返回值类型注解的函数创建结构化输出模型。
图源
- func_metadata.py
本节来源
- func_metadata.py
上下文注入机制
上下文注入机制允许工具函数访问Context对象,从而获得日志记录、进度报告、资源访问等MCP能力。这一机制通过find_context_parameter函数实现,该函数位于context_injection.py文件中。
find_context_parameter函数通过检查函数参数的类型注解来识别哪个参数应该接收Context对象。它首先获取函数的所有类型提示,然后遍历这些提示,查找直接或间接(如Optional[Context])继承自Context类的参数。
图源
- context_injection.py
本节来源
- context_injection.py
同步/异步函数注册
FastMCP框架支持同步和异步函数的注册,这一功能通过_is_async_callable函数实现。该函数能够正确识别协程函数以及实现了__call__方法的异步可调用对象。
对于同步函数,工具执行时直接调用函数;对于异步函数,工具执行时使用await关键字调用。这种设计使得开发者可以自由选择使用同步或异步编程模式,而无需担心工具注册和执行的兼容性问题。
本节来源
- base.py
工具注册示例
以下是一些工具注册的典型示例,展示了如何使用@tool装饰器注册不同类型的工具:
@server.tool()
def my_tool(x: int) -> str:
return str(x)
@server.tool()
def tool_with_context(x: int, ctx: Context) -> str:
ctx.info(f"Processing {x}")
return str(x)
@server.tool()
async def async_tool(x: int, context: Context) -> str:
await context.report_progress(50, 100)
return str(x)
这些示例展示了基本工具注册、带上下文注入的工具注册以及异步工具注册的用法。通过这些简单的装饰器语法,开发者可以轻松地将普通函数转换为功能完整的MCP工具。
本节来源
- server.py










