Resources
从你的 server 向 LLMs 暴露数据和内容
Resources 是 Model Context Protocol (MCP) 中的一个核心原语,它允许服务器暴露可以被 clients 读取并用作 LLM 交互上下文的数据和内容。
Resources 被设计为由应用控制,这意味着客户端应用程序可以决定如何以及何时使用它们。 不同的 MCP clients 可能会以不同的方式处理 resources。例如:
- Claude Desktop 目前要求用户在可以使用 resources 之前显式地选择它们
- 其他 clients 可能会根据启发式方法自动选择 resources
- 某些实现甚至可能允许 AI 模型本身来确定使用哪些 resources
服务器作者在实现 resource 支持时,应该准备好处理任何这些交互模式。为了自动向模型暴露数据,服务器作者应该使用模型控制原语,例如 Tools。
概述
Resources 代表 MCP server 想要提供给 clients 的任何类型的数据。这可以包括:
- 文件内容
- 数据库记录
- API 响应
- 实时系统数据
- 屏幕截图和图像
- 日志文件
- 等等
每个 resource 都由一个唯一的 URI 标识,并且可以包含文本或二进制数据。
Resource URIs
Resources 使用以下格式的 URIs 进行标识:
例如:
file:///home/user/documents/report.pdf
postgres://database/customers/schema
screen://localhost/display1
协议和路径结构由 MCP server 实现定义。服务器可以定义自己的自定义 URI 方案。
Resource 类型
Resources 可以包含两种类型的内容:
文本资源
文本资源包含 UTF-8 编码的文本数据。这些适用于:
- 源代码
- 配置文件
- 日志文件
- JSON/XML 数据
- 纯文本
二进制资源
二进制资源包含以 base64 编码的原始二进制数据。这些适用于:
- 图像
- PDFs
- 音频文件
- 视频文件
- 其他非文本格式
Resource 发现
Clients 可以通过两种主要方法发现可用的 resources:
直接 resources
服务器通过 resources/list
端点暴露一个具体的 resources 列表。每个 resource 包括:
Resource 模板
对于动态 resources,服务器可以暴露 URI 模板,clients 可以使用它们来构造有效的 resource URIs:
读取 resources
要读取 resource,clients 使用 resource URI 发送 resources/read
请求。
服务器使用一个 resource 内容列表进行响应:
服务器可能会响应一个 resources/read
请求返回多个 resources。例如,当读取目录时,可以使用此方法返回目录中的文件列表。
Resource 更新
MCP 通过两种机制支持 resources 的实时更新:
列表更改
当可用 resources 列表发生更改时,服务器可以通过 notifications/resources/list_changed
通知 clients。
内容更改
Clients 可以订阅特定 resources 的更新:
- Client 使用 resource URI 发送
resources/subscribe
- 当 resource 更改时,服务器发送
notifications/resources/updated
- Client 可以使用
resources/read
获取最新内容 - Client 可以使用
resources/unsubscribe
取消订阅
实现示例
以下是在 MCP server 中实现 resource 支持的简单示例:
最佳实践
在实现 resource 支持时:
- 使用清晰、描述性的 resource 名称和 URIs
- 包含有用的描述以指导 LLM 理解
- 在已知时设置适当的 MIME 类型
- 为动态内容实现 resource 模板
- 对频繁更改的 resources 使用订阅
- 使用清晰的错误消息优雅地处理错误
- 考虑对大型 resource 列表进行分页
- 在适当的时候缓存 resource 内容
- 在处理之前验证 URIs
- 记录你的自定义 URI 方案
安全考虑
在暴露 resources 时:
- 验证所有 resource URIs
- 实现适当的访问控制
- 清理文件路径以防止目录遍历
- 谨慎处理二进制数据
- 考虑对 resource 读取进行速率限制
- 审核 resource 访问
- 加密传输中的敏感数据
- 验证 MIME 类型
- 为长时间运行的读取操作实现超时
- 适当处理 resource 清理