MCP进阶指南:资源管理与动态数据访问

在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的实现版本。

资源使用最佳实践

  1. 合理组织URI命名空间 :使用有意义的前缀和路径结构,如data://file://
  2. 提供清晰的资源描述:为每个资源函数添加详细的文档字符串
  3. 适当使用MIME类型:为不同类型的内容指定正确的MIME类型
  4. 处理异常情况:在资源函数中添加适当的错误处理
  5. 考虑资源缓存:对于不经常变化的大型资源,考虑实现缓存机制
相关推荐
coder_pig33 分钟前
🙋‍♂️挑战用1天,让AI从0到1搭建纯前端 "塔防游戏"
aigc·mcp·trae
顺丰同城前端技术团队1 小时前
我想蹭一波 Trae 的流量,所以我写了关于 MCP 的这篇文章并起了这个标题...
前端·程序员·mcp
ZackSock5 小时前
FastMCP 快速入门
mcp
bastgia6 小时前
LangGraph + MCP + Ollama 实战教程:打造强大的多智能体聊天机器人
llm·mcp
掘我的金9 小时前
MCP高级应用:构建智能函数工具
mcp
掘我的金9 小时前
MCP入门指南:打造智能AI工具的第一步
mcp
叶 落12 小时前
三种语言写 MCP
java·python·ai·typescript·mcp
小码农叔叔13 小时前
【AI智能体】Spring AI MCP 服务常用开发模式实战详解
mcp·springboot使用mcp·mcp使用详解·mcp使用·spring ai mcp·mcp 详解·mcp开发模式
qife19 小时前
GitHub MCP Server - 无缝集成GitHub API的自动化工具
go·github·自动化编程·mcp·api集成