[MCP] MCP Resources

Resources

资源也是 MCP Server 向客户端应用提供信息的一种形式。

例如:

  • File contents(文件内容)

    比如本地的 .txt.md.js.json 文件

  • Database records(数据库记录)

    比如 SQL 查询结果或某个表格的内容

  • Screenshots and images(截图和图像)

    图像类资源

URI

URI 英语全称为 Uniform Resource Identifier,中文是“统一资源标识符”,用于互联网上某个资源的唯一标识。

URI 的格式为:

[protocol]://[host]/[path]

例如:

  • file:///home/user/documents/report.pdf:文件资源,这个例子里面没有 host
  • postgres://database/customers/schema:是一个数据库资源
  • screen://localhost/display1:屏幕资源

在 MCP 协议中,不强制 URI 规则,允许 Server 自定义。

  • notebook://cell/123
  • log://app/service/error
  • chat://conversation/abc123

回头在 MCP Server 中,所有的资源都会有一个 URI.

资源类型

MCP 中的资源分为两类:Text resources 和 Binary resources

文本资源

文本资源是用 UTF-8 编码的纯文本数据,适合用来展示、编辑、分析。

  • Source code(源代码):如 .js.ts.py.cpp 等文件的内容,可以作为上下文供 LLM 阅读和理解。
  • Configuration files(配置文件): 如 .envconfig.yamltsconfig.json 等。
  • Log files(日志文件):包括运行日志、错误日志,供分析或总结。
  • JSON/XML data:结构化的文本格式,广泛用于数据交换。
  • Plain text(纯文本):普通的 .txt 文件或文档片段。

二进制资源

二进制资源是原始的二进制数据,必须通过 base64 编码传输。

  • Images(图像):如 PNG、JPG、SVG 等,可用于截图、照片识别等任务。

  • PDFs:常用于展示格式化文档或技术手册。

  • Audio files(音频):如 MP3、WAV,用于语音识别、分析等。

  • Video files(视频):如 MP4、WEBM,可用于视频摘要或分析。

  • Other non-text formats(其它非文本格式):如 .zip 压缩包、.docx 文档、.exe 文件等。

发现资源

MCP 提供了两种发现资源的方式:

  1. 直接资源
  2. 资源模板

直接资源

服务器直接暴露一组固定资源,通过 JSON-RPC 方法 resources/list 提供给客户端。

工具:tools/list

每个资源包含字段如下:

{
  uri: string;         // 资源的唯一 URI(例如 file:///xxx)
  name: string;        // 人类可读的名称
  description?: string;// 可选描述,解释用途或内容
  mimeType?: string;   // MIME 类型,如 text/plain, image/png
  size?: number;       // 文件大小(单位:字节)
}

例如:

{
  uri: "file:///logs/build.log",
  name: "构建日志",
  description: "包含最近一次构建的所有输出信息",
  mimeType: "text/plain",
  size: 18423
}

资源模板

后面再说。

读取资源

客户端通过发送 JSON-RPC 请求:

方法名为 resources/read,在 params 中写上资源的 URI

{
  "method": "resources/read",
  "params": {
    "uri": "file:///logs/error.log"
  }
}

服务器返回一个 JSON 对象,包含一个 contents 数组,每个数组元素表示一个资源内容对象,结构如下:

{
  contents: [
    {
      uri: string;          // 必填,资源的唯一 URI
      mimeType?: string;    // 可选,MIME 类型,如 text/plain、image/png

      // 以下两者二选一
      text?: string;        // 文本资源内容(UTF-8 编码)
      blob?: string;        // 二进制资源内容(Base64 编码)
    }
  ]
}

MCP 支持 一次 resources/read 返回多个资源内容

比如:读取一个目录:file:///project/src/,返回值可能是里面多个文件的内容(如多个 .ts 文件)

课堂练习

为 MCP 服务器注册资源上下文。

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { readResourse } from "./utils.js";

const server = new McpServer({
  name: "resources-mcp-server",
  version: "0.1.0",
});

server.registerResource(
  "香蕉手机", // 资源的名称
  "bananaphone://info", // 资源URI
  {
    title: "香蕉手机信息",
    description: "香蕉手机的产品以及特性的介绍文字",
    mimeType: "text/plain",
  },
  async (uri) => {
    console.error("uri>>>", uri);
    const content = await readResourse("src/assets", "bananaphone.txt", false);
    return {
      contents: [
        {
          uri: uri.href,
          name: "香蕉手机信息",
          text: content,
        },
      ],
    };
  }
);

// 注册图像资源(二进制)
server.registerResource(
  "书籍图片", // 资源的名称
  "pics://books", // 资源URI
  {
    title: "书籍图片",
    description: "一张有很多书籍的图片",
    mimeType: "image/jpeg",
  },
  async (uri) => {
    console.error("uri>>>", uri);
    const content = await readResourse("src/assets", "books.jpeg", true);
    return {
      contents: [
        {
          uri: uri.href,
          name: "书籍图片",
          blob: content,
        },
      ],
    };
  }
);

server.connect(new StdioServerTransport());
import fs from "fs";
import path from "path";

/**
 *
 * @param {*} filepath 文件的路径
 * @param {*} filename 文件的名称
 * @param {*} isBinary 是否是二进制数据
 */
export async function readResourse(filepath, filename, isBinary) {
  try {
    const filePath = path.join(process.cwd(), filepath, filename);
    let content = null; // 存储最终读取到的资源
    if (isBinary) {
      // 说明是二进制数据
      const buffer = fs.readFileSync(filePath);
      // 需要将二进制数据转换为base64编码
      content = buffer.toString("base64");
    } else {
      // 非二进制数据
      content = fs.readFileSync(filePath, "utf8");
    }
    return content;
  } catch (err) {
    return `读取资源失败☹️:${err.message}`;
  }
}

调试工具:

npx @modelcontextprotocol/inspector

在线base64图片预览:https://jaredwinick.github.io/base64-image-viewer/

data:image/png;base64,<base64编码>
posted @ 2025-09-29 13:59  Zhentiw  阅读(25)  评论(0)    收藏  举报