在MCP框架中,资源(Resources)是一种强大的机制,允许AI应用访问和管理各种类型的数据。本文将深入探讨MCP的资源系统,展示如何创建和使用不同类型的资源,包括静态文本、模板化内容、结构化数据和文件资源。通过这些示例,你将了解如何为AI应用提供丰富的数据访问能力,使其能够获取所需的信息来完成复杂任务。
资源系统简介
MCP的资源系统允许开发者以统一的方式定义和访问各种数据源。每个资源都通过唯一的URI标识,客户端可以使用这些URI来请求资源内容。资源系统的主要特点包括:
- 统一访问接口:所有资源通过相同的API进行访问
- 多种数据类型支持:文本、JSON、二进制数据等
- 动态内容生成:基于参数动态生成资源内容
- MIME类型控制:指定资源的内容类型
资源类型与实现
1. 静态URI文本资源
最简单的资源类型是静态文本资源,它返回预定义的文本内容:
python
@mcp.resource("data://static/text")
def get_static_text():
"""一个简单的静态URI文本资源示例"""
return """这是一个静态URI文本资源。
它使用简单的纯文本格式,没有特殊的格式化。
适用于提供简单的文本信息。"""
这种资源适用于提供固定的说明文档、帮助信息或其他不需要动态生成的文本内容。
2. 模板化URI资源
模板化URI资源允许在URI中包含参数,从而根据请求动态生成内容:
python
@mcp.resource("data://template/{name}")
def get_template(name: str):
"""一个带参数的模板化URI资源示例"""
return f"""你好,{name}!
这是一个针对你定制的模板化资源。
模板化URI允许根据URI参数动态生成内容。"""
通过在URI路径中使用花括号定义参数,MCP会自动解析这些参数并传递给资源函数。这对于创建个性化内容或基于输入参数返回不同数据非常有用。
3. JSON数据资源
对于结构化数据,可以使用JSON格式并指定适当的MIME类型:
python
@mcp.resource("data://json", mime_type="application/json")
def get_json_data():
"""一个包含JSON格式数据的资源示例"""
data = {
"name": "JSON资源示例",
"type": "结构化数据",
"features": ["易于解析", "支持嵌套", "广泛应用"],
"timestamp": datetime.now().isoformat(),
"metadata": {
"version": "1.0",
"author": "MCP示例"
}
}
return json.dumps(data, ensure_ascii=False, indent=2)
通过指定mime_type="application/json"
,客户端可以知道这是JSON数据,从而进行适当的处理。
4. 二进制数据资源
MCP也支持二进制数据资源,通常以Base64编码字符串的形式返回:
python
@mcp.resource("data://binary", mime_type="application/octet-stream")
def get_binary_data():
"""一个包含二进制数据的资源示例"""
# 生成二进制数据 ("Hello MCP" 的ASCII码)
binary_data = bytes([0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x4D, 0x43, 0x50])
# 将二进制数据编码为Base64字符串返回
return base64.b64encode(binary_data).decode('ascii')
对于二进制数据,我们使用mime_type="application/octet-stream"
,并将数据编码为Base64字符串。
5. 文件资源
MCP提供了FileResource
类,用于直接从文件系统加载资源内容:
python
# 使用绝对路径创建FileResource
mcp.add_resource(FileResource(
uri="file://demo.txt",
name="demo.txt",
path=Path(data_html_path), # 使用绝对路径
encoding="utf-8" # 显式指定UTF-8编码
))
文件资源特别适合提供较大的文本文件、配置文件或其他需要从文件系统加载的内容。
客户端访问资源
在客户端,我们可以使用session.read_resource()
方法来访问资源:
python
# 列出所有可用资源
resources = await session.list_resources()
# 读取静态文本资源
result = await session.read_resource("data://static/text")
# 读取带参数的模板化资源
result = await session.read_resource("data://template/张三")
# 读取JSON数据资源
result = await session.read_resource("data://json")
# 读取二进制数据资源
result = await session.read_resource("data://binary")
# 读取文件资源
result = await session.read_resource("file://demo.txt")
输出的结果如下:
bash
data.html 文件绝对路径: D:\svn\github.com\ai-learning\mcp\..\demo.txt
=== 可用资源列表 ===
资源列表类型: <class 'mcp.types.ListResourcesResult'>
resources 属性类型: <class 'list'>
资源列表内容:
meta=None nextCursor=None resources=[Resource(uri=AnyUrl('data://static/text'), name='get_static_text', description='一个简单的静态 URI 文本资源示例', mimeType='text/plain', size=None, annotations=None), Resource(uri=AnyUrl('data://json'), name='get_json_data', description='一个包含 JSON 格式数据
的资源示例', mimeType='application/json', size=None, annotations=None), Resource(uri=AnyUrl('data://binary'), name='get_binary_data', description='一个包含二进制数据的资源示例', mimeType='application/octet-stream', size=None, annotations=None), Resource(uri=AnyUrl('file://demo.txt/'), name='demo.txt', description=None, mimeType='text/plain', size=None, annotations=None)]
资源对象属性:
meta: None
nextCursor: None
resources: [Resource(uri=AnyUrl('data://static/text'), name='get_static_text', description='一个
简单的静态 URI 文本资源示例', mimeType='text/plain', size=None, annotations=None), Resource(uri=AnyUrl('data://json'), name='get_json_data', description='一个包含 JSON 格式数据的资源示例', mimeType='application/json', size=None, annotations=None), Resource(uri=AnyUrl('data://binary'), name='get_binary_data', description='一个包含二进制数据的资源示例', mimeType='application/octet-stream', size=None, annotations=None), Resource(uri=AnyUrl('file://demo.txt/'), name='demo.txt', description=None, mimeType='text/plain', size=None, annotations=None)]
资源对象可用方法和属性:
meta: None
D:\svn\github.com\ai-learning\mcp\02_resource_examples.py:120: PydanticDeprecatedSince211: Accessing the 'model_computed_fields' attribute on the instance is deprecated. Instead, you should access this attribute from the model class. Deprecated in Pydantic V2.11 to be removed in V3.0.
attr_value = getattr(resources, attr_name)
model_computed_fields: {}
model_config: {'extra': 'allow'}
model_extra: {}
D:\svn\github.com\ai-learning\mcp\02_resource_examples.py:120: PydanticDeprecatedSince211: Accessing the 'model_fields' attribute on the instance is deprecated. Instead, you should access this attribute from the model class. Deprecated in Pydantic V2.11 to be removed in V3.0.
attr_value = getattr(resources, attr_name)
model_fields: {'meta': FieldInfo(annotation=Union[dict[str, Any], NoneType], required=False, default=None, alias='_meta', alias_priority=2), 'nextCursor': FieldInfo(annotation=Union[str, NoneType], required=False, default=None), 'resources': FieldInfo(annotation=list[Resource], required=True)}
model_fields_set: {'resources'}
nextCursor: None
resources: [Resource(uri=AnyUrl('data://static/text'), name='get_static_text', description='一个
简单的静态 URI 文本资源示例', mimeType='text/plain', size=None, annotations=None), Resource(uri=AnyUrl('data://json'), name='get_json_data', description='一个包含 JSON 格式数据的资源示例', mimeType='application/json', size=None, annotations=None), Resource(uri=AnyUrl('data://binary'), name='get_binary_data', description='一个包含二进制数据的资源示例', mimeType='application/octet-stream', size=None, annotations=None), Resource(uri=AnyUrl('file://demo.txt/'), name='demo.txt', description=None, mimeType='text/plain', size=None, annotations=None)]
继续测试各个资源...
=== 测试静态 URI 文本资源 ===
结果类型: <class 'mcp.types.ReadResourceResult'>
内容:
meta=None contents=[TextResourceContents(uri=AnyUrl('data://static/text'), mimeType='text/plain', text='这是一个静态 URI 文本资源。\n它使用简单的纯文本格式,没有特殊的格式化。\n适用于提供简单的文本
信息。')]
=== 测试模板化 URI 资源 ===
内容:
meta=None contents=[TextResourceContents(uri=AnyUrl('data://template/%E5%BC%A0%E4%B8%89'), mimeType='text/plain', text='你好,%E5%BC%A0%E4%B8%89!\n这是一个针对你定制的模板化资源。\n模板化 URI 允许
根据 URI 参数动态生成内容。')]
=== 测试 JSON 数据资源 ===
结果: meta=None contents=[TextResourceContents(uri=AnyUrl('data://json'), mimeType='application/json', text='{\n "name": "JSON 资源示例",\n "type": "结构化数据",\n "features": [\n "易于解析",\n "支持嵌套",\n "广泛应用"\n ],\n "timestamp": "2025-06-22T19:07:40.470767",\n "metadata": {\n {"version": "1.0",\n "author": "MCP 示例"\n }\n}')]
\n "version": "1.0",\n "author": "MCP 示例"\n }\n}')]
n "支持嵌套",\n "广泛应用"\n ],\n "timestamp": "2025-06-22T19:07:40.470767",\n "metadata":
{\n "version": "1.0",\n "author": "MCP 示例"\n }\n}')] tet-st
=== 测试二进制数据资源 ===
结果: meta=None contents=[TextResourceContents(uri=AnyUrl('data://binary'), mimeType='application/octet-stream', text='SGVsbG8gTUNQ')] , text
=== 测试文件资源 ===
结果: meta=None contents=[TextResourceContents(uri=AnyUrl('file://demo.txt/'), mimeType='text/plain', text='this is demo file content')]
资源的返回值可能是简单的字符串,也可能是包含内容和MIME类型的元组,具体取决于MCP的实现版本。
资源使用最佳实践
- 合理组织URI命名空间 :使用有意义的前缀和路径结构,如
data://
、file://
等 - 提供清晰的资源描述:为每个资源函数添加详细的文档字符串
- 适当使用MIME类型:为不同类型的内容指定正确的MIME类型
- 处理异常情况:在资源函数中添加适当的错误处理
- 考虑资源缓存:对于不经常变化的大型资源,考虑实现缓存机制