资源与模板
向您的MCP客户端公开数据源和动态内容生成器。
资源代表MCP客户端可以读取的数据或文件,而资源模板通过允许客户端根据URI中传递的参数请求动态生成的资源,扩展了这一概念。
FastMCP简化了静态和动态资源的定义,主要通过使用@mcp.resource装饰器来实现。
什么是资源?
资源为LLM或客户端应用程序提供对数据的只读访问权限。当客户端请求资源URI时:
- FastMCP 查找对应的资源定义。
- 如果是动态的(由函数定义),则执行该函数。
- 内容(文本、JSON、二进制数据)将返回给客户端。
这使得LLM能够访问与对话相关的文件、数据库内容、配置或动态生成的信息。
资源
@resource 装饰器
定义资源最常见的方式是通过装饰一个Python函数。装饰器需要资源的唯一URI。
关键概念:
- URI:
@resource的第一个参数是客户端用来请求此数据的唯一URI(例如"resource://greeting")。 - 延迟加载: 装饰函数(
get_greeting,get_config)仅在客户端通过resources/read明确请求该资源URI时才会执行。 - Inferred Metadata: By default:
- 资源名称:取自函数名称(
get_greeting)。 - 资源描述:取自函数的文档字符串。
- 资源名称:取自函数名称(
返回值
FastMCP 会自动将您函数的返回值转换为适当的 MCP 资源内容:
str: 作为TextResourceContents发送(默认使用mime_type="text/plain")。dict,list,pydantic.BaseModel: 自动序列化为JSON字符串并作为TextResourceContents发送(默认使用mime_type="application/json")。bytes: 经过Base64编码后作为BlobResourceContents发送。您应该指定适当的mime_type(例如"image/png"、"application/octet-stream")。None: 将返回一个空的资源内容列表。
资源元数据
您可以通过装饰器中的参数自定义资源的属性:
uri: 资源的唯一标识符(必填)。name: 一个人类可读的名称(默认为函数名称)。description: 资源的说明(默认为文档字符串)。mime_type: 指定内容类型(FastMCP通常会推断默认值如text/plain或application/json,但对于非文本类型显式指定更佳)。tags: 一组用于分类的字符串,客户端可能用于过滤。
访问MCP上下文
New in version: 2.2.5
资源和资源模板可以通过Context对象访问额外的MCP信息和功能。要访问它,请在你的资源函数中添加一个参数,并使用Context类型注解:
有关Context对象及其所有功能的完整文档,请参阅Context文档。
异步资源
对于执行I/O操作(例如从数据库或网络读取)的资源函数,使用async def以避免阻塞服务器。
资源类别
虽然@mcp.resource非常适合动态内容,但您也可以直接使用mcp.add_resource()和具体的Resource子类来注册预定义的资源(如静态文件或简单文本)。
常用资源类:
TextResource: 用于简单的字符串内容。BinaryResource: 用于原始bytes内容。FileResource: 从本地文件路径读取内容。支持文本/二进制模式及惰性读取。HttpResource: 从HTTP(S) URL获取内容(需要httpx)。DirectoryResource: 列出本地目录中的文件(返回JSON格式)。- (
FunctionResource: 由@mcp.resource使用的内部类)。
当内容是静态的或直接来自文件/URL时使用这些方法,可以绕过对专用Python函数的需求。
自定义资源键
New in version: 2.2.0
当直接使用mcp.add_resource()添加资源时,可以选择提供一个自定义的存储键:
请注意,该参数仅在直接使用add_resource()而非通过@resource装饰器时可用,因为使用装饰器时会显式提供URI。
资源模板
资源模板允许客户端请求内容依赖于URI中嵌入参数的资源。使用相同的@mcp.resource装饰器定义模板,但在URI字符串中包含{parameter_name}占位符,并将相应的参数添加到函数签名中。
资源模板与常规资源共享大部分配置选项(名称、描述、mime_type、标签),但增加了定义URI参数映射到函数参数的能力。
资源模板会为每组独特参数生成一个新资源,这意味着可以根据需求动态创建资源。例如,如果注册了资源模板"user://profile/{name}",MCP客户端就可以请求"user://profile/ford"或"user://profile/marvin"来获取这两个用户配置文件作为资源,而无需单独注册每个资源。
不支持将带有*args的函数作为资源模板。不过与工具和提示不同,资源模板确实支持**kwargs,因为URI模板定义了将被收集并作为关键字参数传递的特定参数名称。
以下是一个完整示例,展示如何定义两个资源模板:
定义好这两个模板后,客户端可以请求各种资源:
weather://london/current→ 返回伦敦的天气信息weather://paris/current→ 返回巴黎的天气数据repos://jlowin/fastmcp/info→ 返回关于jlowin/fastmcp仓库的信息repos://prefecthq/prefect/info→ 返回关于prefecthq/prefect仓库的信息
通配符参数
New in version: 2.2.4
请注意:FastMCP对通配符参数的支持是对扩展Model Context Protocol标准的实现,该标准其他方面遵循RFC 6570规范。由于所有模板处理都在FastMCP服务器端完成,这不会与其他MCP实现产生兼容性问题。
资源模板支持可以匹配多个路径段的通配符参数。标准参数({param})仅匹配单个路径段且不跨越"/"边界,而通配符参数({param*})可以捕获包括斜杠在内的多个段。通配符会捕获所有后续路径段直到URI模板中定义的部分(无论是字面量还是另一个参数)。这允许您在单个URI模板中使用多个通配符参数。
通配符参数在以下情况下非常有用:
- 处理文件路径或层级数据
- 创建需要捕获可变长度路径段的API
- 构建类似REST API的URL模式
请注意,与常规参数类似,每个通配符参数仍必须是函数签名中的命名参数,并且所有必需的函数参数都必须出现在URI模板中。
默认值
New in version: 2.2.0
在创建资源模板时,FastMCP对URI模板参数和函数参数之间的关系强制执行两条规则:
- 必填函数参数:所有没有默认值的函数参数(必填参数)都必须出现在URI模板中。
- URI参数:所有URI模板参数必须作为函数参数存在。
然而,带有默认值的函数参数不需要包含在URI模板中。当客户端请求资源时,FastMCP将:
- 从URI中提取模板中包含的参数值
- 对URI模板中未包含的任何函数参数使用默认值
这允许灵活的API设计。例如,一个带有可选参数的简单搜索模板:
通过此模板,客户端可以请求search://python,该函数将被调用并传入参数query="python", max_results=10, include_archived=False。MCP开发者仍可直接调用底层的search_resources函数并指定更具体的参数。
更强大的模式是使用多个URI模板注册单个函数,允许通过不同方式访问相同数据:
现在LLM或客户端可以通过两种不同的方式检索用户信息:
users://email/alice@example.com→ 通过邮箱查找用户(name参数为None)users://name/Bob→ 按名称查找用户(email=None)
在这个堆叠装饰器模式中:
- 仅当使用
users://name/{name}模板时才会提供name参数 - 仅在使用
users://email/{email}模板时才会提供email参数 - 当URI中未包含时,每个参数默认为
None - 函数逻辑处理提供的任何参数
模板提供了一种强大的方式,遵循类似REST的原则来暴露参数化的数据访问点。
错误处理
New in version: 2.3.4
如果你的资源函数遇到错误,可以抛出标准Python异常(ValueError、TypeError、FileNotFoundError、自定义异常等)或FastMCP的ResourceError。
出于安全考虑,大多数异常在被发送到客户端之前都会被封装在通用的ResourceError中,内部错误细节会被隐藏。但是,如果您直接抛出ResourceError,其内容会包含在响应中。这允许您选择性地向客户端提供信息性错误消息。
此错误处理模式适用于常规资源和资源模板。
服务器行为
重复资源
New in version: 2.1.0
您可以配置FastMCP服务器如何处理尝试注册具有相同URI的多个资源或模板的情况。在FastMCP初始化期间使用on_duplicate_resources设置。
重复行为选项包括:
"warn"(默认): 记录警告日志,新资源/模板会替换旧资源/模板。"error": 抛出ValueError错误,阻止重复注册。"replace": 静默地用新资源/模板替换现有资源/模板。"ignore": 保留原始资源/模板并忽略新的注册尝试。