MCP 的 Resources 是什么?一文介绍及使用

MCP (模型上下文协议) 如何通过 Resources 为大语言模型提供外部上下文?本文从基础概念、协议交互到高级用法,详细介绍 Resources 的工作原理与具体使用方法,帮助你理解和应用这一核心功能。

用 Apifox,节省研发团队的每一分钟

MCP 的 Resources 是什么?一文介绍及使用

免费使用 Apifox

相关推荐

最新文章

API

一体化协作平台

API 设计

API 文档

API 调试

自动化测试

API Mock

API Hub

立即体验 Apifox
目录

Model Context Protocol(MCP)是一个为语言模型提供上下文的标准化协议。在与模型交互时,我们常常需要提供文件、数据、甚至是应用状态等外部信息,以获得更精准的回答。MCP 通过其核心概念 Resources,为这种需求提供了一套标准化的解决方案。

     

简单来说,Resources 是服务器向客户端暴露数据的一种方式。这些数据可以是文件、数据库模式、API 描述或任何能为语言模型提供上下文的信息。每一个资源都通过一个唯一的 URI (Uniform Resource Identifier) 来标识。

   

什么是 Resources?

在 MCP 中,Resources 的设计遵循“应用驱动”的原则。这意味着协议本身不强制规定用户界面(UI)应该如何呈现或使用这些资源,而是将决定权交给了宿主应用。

   

应用可以根据自身的需求,以多种方式整合 Resources。例如,一个代码编辑器可以通过一个树状视图展示项目中的所有文件,让用户手动选择需要作为上下文的文件。一个数据分析工具可能会提供搜索和筛选功能,帮助用户从大量的数据库表中找到相关的几个。也有些应用可能会基于某些启发式规则,或者根据 AI 模型自身的判断,自动将相关资源包含在上下文中。

     

这种设计的灵活性确保了 Resources 能够适应不同应用的特定场景,而不是将所有应用都限制在单一的交互模式里。协议只负责定义“如何暴露和获取资源”,而“如何使用资源”则由应用开发者决定。

     

如何与 Resources 交互?

客户端与服务器之间关于 Resources 的交互遵循一套明确的协议消息。整个过程从发现资源开始,到读取内容,再到处理可能的变更。

   

声明能力

在客户端使用 Resources 功能之前,服务器必须首先在 capabilities 中声明自己支持此功能。这是一个初始握手步骤,用于告知客户端服务器具备哪些能力。

   

一个支持 Resources 的服务器会在其能力声明中包含 resources 对象:

{
  "capabilities": {
    "resources": {
      "subscribe": true,
      "listChanged": true
    }
  }
}

   

resources 对象内有两个可选的布尔值字段,subscribelistChanged,它们分别表示两种额外的能力。

字段 类型 含义
subscribe boolean true 表示客户端可以订阅单个资源,以便在该资源内容发生变化时收到通知。
listChanged boolean true 表示当可用的资源列表发生变化(如新增或删除资源)时,服务器会主动发送通知。

       

服务器可以根据自身实现,选择支持其中一个、两个或全都不支持。例如,一个只读的文件系统可能就不需要支持任何变更通知。

       

列出可用资源

客户端要发现服务器提供了哪些资源,需要发送一个 resources/list 请求。这个操作支持分页,允许客户端逐页获取完整的资源列表。

   

请求的格式很简单:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "resources/list",
  "params": {
    "cursor": "optional-cursor-value"
  }
}

   

服务器会返回一个包含资源列表的响应。如果资源过多,nextCursor 字段会提供一个用于获取下一页数据的凭证。

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resources": [
      {
        "uri": "file:///project/src/main.rs",
        "name": "main.rs",
        "title": "Rust Software Application Main File",
        "description": "Primary application entry point",
        "mimeType": "text/x-rust"
      }
    ],
    "nextCursor": "next-page-cursor"
  }
}

 

响应中的每个 resource 对象都包含了描述资源的基本信息,如 uriname(名称)、title(用于展示的标题)、description(描述)和 mimeType(媒体类型)。

 

读取资源内容

当客户端确定了想要获取其内容的资源后,就可以通过该资源的 uri 发送一个 resources/read 请求。

 

请求中只需指定目标的 uri

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "resources/read",
  "params": {
    "uri": "file:///project/src/main.rs"
  }
}

 

服务器收到请求后,会返回该资源的内容。资源的内容可以是文本(text)或二进制(blob)数据。二进制数据会以 Base64 编码的字符串形式提供。

 

这是一个返回文本内容的示例:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "contents": [
      {
        "uri": "file:///project/src/main.rs",
        "mimeType": "text/x-rust",
        "text": "fn main() {\n    println!(\"Hello world!\");\n}"
      }
    ]
  }
}

 

如果资源是一个图片文件,响应可能会是这样:

{
  "uri": "file:///example.png",
  "mimeType": "image/png",
  "blob": "base64-encoded-data"
}

 

通过 resources/listresources/read 这两个核心请求,客户端就完成了一次完整的“发现-获取”流程。  

如何与 Resources 交互?

 

更高级的用法

除了基本的读写,MCP Resources 还提供了一些高级功能,以应对更复杂的场景,如动态资源和内容变更通知。

 

使用资源模板

有时,资源不是静态的,而是需要通过参数动态生成。例如,访问项目中的任意文件。如果为每个文件都创建一个静态资源,列表会变得非常冗长。Resource Templates(资源模板)就是为了解决这类问题。它使用 URI 模板(RFC 6570)来定义一类可参数化的资源。

 

客户端可以通过 resources/templates/list 请求获取所有可用的资源模板:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "resources/templates/list"
}

 

服务器返回的模板列表中,uriTemplate 字段定义了模板格式,例如 file:///{path},其中 {path} 就是一个需要客户端填充的参数。

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "resourceTemplates": [
      {
        "uriTemplate": "file:///{path}",
        "name": "Project Files",
        "title": "📁 Project Files",
        "description": "Access files in the project directory"
      }
    ]
  }
}

 

订阅资源变更

对于内容可能频繁变动的资源,例如一个正在被编辑的文件或一个实时更新的日志,反复轮询 resources/read 是低效的。如果服务器在能力声明中设置了 subscribe: true,客户端就可以订阅特定资源的变更。

 

客户端发送 resources/subscribe 请求来订阅一个资源:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "resources/subscribe",
  "params": {
    "uri": "file:///project/src/main.rs"
  }
}

 

订阅成功后,一旦该资源的内容发生变化,服务器就会主动向客户端发送一个 notifications/resources/updated 通知。

{
  "jsonrpc": "2.0",
  "method": "notifications/resources/updated",
  "params": {
    "uri": "file:///project/src/main.rs"
  }
}

 

收到通知后,客户端就可以再次调用 resources/read 来获取最新的资源内容。

   

使用注解提供线索

为了帮助客户端更好地理解和使用资源,MCP 允许在资源、资源模板和内容块中添加 annotations(注解)。这些注解提供了一些额外的元数据,作为给客户端的“提示”。

   

常见的注解包括:

  • audience: 一个数组,表明资源的目标受众,可选值为 "user""assistant"
  • priority: 一个从 0.0 到 1.0 的数字,表示资源的重要性。1.0 表示最重要。
  • lastModified: 一个 ISO 8601 格式的时间戳,表示资源最后修改的时间。

 

一个带有注解的资源定义如下:

{
  "uri": "file:///project/README.md",
  "name": "README.md",
  "annotations": {
    "audience": ["user"],
    "priority": 0.8,
    "lastModified": "2025-01-12T15:00:58Z"
  }
}

 

客户端可以利用这些注解来实现更智能的功能,比如根据 priority 优先选择包含哪些上下文,或者根据 lastModified 显示文件的最近修改时间。

 

注意事项

在使用 Resources 时,还有一些重要的实践和规范需要注意。

 

关于 URI 方案

URI 是 Resources 的核心标识。协议推荐了几种常见的 URI 方案,但并不局限于此。

  • https://: 用于表示可通过 Web 直接访问的资源。只有当客户端能够自行获取资源时才应使用。
  • file://: 用于标识行为类似文件系统的资源,但不一定映射到物理文件系统。
  • git://: 用于 Git 版本控制集成。

应用也可以定义自己的 custom URI schemes,只要它们符合 RFC 3986 规范即可。

   

错误处理

MCP 使用标准的 JSON-RPC 错误码。例如,当请求的资源不存在时,服务器应该返回 -32002 错误码。

{
  "jsonrpc": "2.0",
  "id": 5,
  "error": {
    "code": -32002,
    "message": "Resource not found",
    "data": {
      "uri": "file:///nonexistent.txt"
    }
  }
}

 

安全考虑

最后,安全是不可忽视的一环。服务器必须对所有传入的资源 URI 进行验证,防止路径遍历等攻击。对于敏感资源,应实现严格的访问控制。同时,在处理二进制数据时,必须确保其被正确编码和解码,以防范安全风险。

   

开发必备:API 全流程管理神器 Apifox

介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档API 调试API 设计API 测试API Mock自动化测试等功能于一体的 API 管理工具,Apifox 可以说是开发者提升效率的必备工具之一。

 
如果你正在开发项目需要进行接口调试,不妨试试 Apifox。注册过程非常简单,你可以直接在这里注册使用

Apifox



注册成功后可以先看看官方提供的示例项目,这些案例都是经过精心设计的,能帮助你快速了解 Apifox 的主要功能。

 
使用 Apifox 的一大优势是它完全兼容 PostmanSwagger 数据格式,如果你之前使用过这些工具,数据导入会非常方便。而且它的界面设计非常友好,即使是第一次接触的新手也能很快上手,快去试试吧!

Apifox