MCP的Resources 和 Prompts

在 Model Context Protocol (MCP) 中,Resources 和 Prompts 是两种核心功能(Primitives),用于增强 AI 模型与外部数据和工具的交互能力。


Resources 和 Prompts 的定义与作用

  1. Resources
  • 定义:Resources 是 MCP 服务器暴露给客户端的只读数据或内容,类似于文件、数据库记录或 API 响应。它们通过唯一的 URI 标识,可以是文本(UTF-8 编码)或二进制数据(Base64 编码)。Resources 由应用程序控制,客户端决定如何以及何时使用这些数据。

  • 作用:

    • 提供上下文数据给 AI 模型,例如日志文件、配置文件、实时 API 数据等。
    • 支持动态数据更新,服务器可以通过通知机制(如 resources/list_changed 或 resources/updated)告知客户端资源的变化。
    • 适合需要结构化、可重复访问的数据场景,例如文件内容、数据库查询结果等。
  • 特点:

    • 数据由服务器管理,客户端通过 resources/list 获取可用资源列表,通过 resources/read 读取具体内容。
    • 支持自定义 URI 方案,例如 file:///logs/app.log 或 greetings://{name}。
    • 客户端可能需要用户明确选择资源(例如 Claude Desktop),也可能自动选择(取决于客户端实现)。
  1. Prompts
  • 定义:Prompts 是 MCP 服务器提供的结构化模板,用于标准化与语言模型的交互。它们定义了可重用的消息序列和工作流,支持参数化以定制交互。

  • 作用:

    • 提供一致的提示工程框架,确保 AI 模型以可预测的方式响应。
    • 允许用户或客户端通过参数(如用户名、风格)动态生成提示。
    • 适合需要引导 AI 行为或生成特定输出的场景,例如生成个性化问候、格式化查询等。
  • 特点:

    • 通过 prompts/list 获取可用提示列表,通过 prompts/get 获取具体提示内容。
    • 支持参数化,例如一个提示模板可以接受 name 参数生成个性化消息。
    • 客户端可以直接使用提示,或者将其嵌入到更复杂的交互中。

总结

特性 Resources Prompts
本质 只读数据或内容 结构化提示模板
用途 提供上下文或数据 引导 AI 模型生成特定输出
控制方 应用程序(客户端决定使用方式) 用户或客户端(可动态参数化)
示例场景 读取日志文件、API 响应 生成个性化问候、格式化查询
交互方式 通过 URI 访问 通过模板名称和参数调用

如何配置 Resources 和 Prompts

在搭建 MCP 服务器时,Resources 和 Prompts 的配置通常基于 MCP 的 SDK(例如 Python 或 TypeScript SDK)。以下是具体步骤和代码示例:

  1. 环境准备
  • 安装 SDK:

    • Python: pip install mcp 或 uv add "mcp[cli]"。
    • TypeScript: npm install @modelcontextprotocol/sdk。
  • 选择传输方式:MCP 支持 Stdio(标准输入/输出)或 SSE(服务器推送事件)。本地开发通常使用 Stdio。

  • 工具:推荐使用 MCP Inspector 进行调试,验证服务器功能。

  1. 配置 Resources
  • 步骤:

    1. 定义资源列表(resources/list),包括 URI、名称、描述和 MIME 类型。
    2. 实现资源读取逻辑(resources/read),根据 URI 返回内容。
    3. 可选:实现资源更新通知(如 resources/list_changed)。
  • 代码示例(Python SDK):

    python

    python 复制代码
    from mcp import Server, types
    from mcp.server.stdio import stdio_server
    
    app = Server("example-server", capabilities={"resources": {}})
    
    # 列出可用资源
    @app.list_resources()
    async def list_resources() -> list[types.Resource]:
        return [
            types.Resource(
                uri="file:///logs/app.log",
                name="Application Logs",
                mimeType="text/plain"
            )
        ]
    
    # 读取资源内容
    @app.read_resource()
    async def read_resource(uri: str) -> str:
        if uri == "file:///logs/app.log":
            return "Log content: Server started at 2025-04-27"
        raise ValueError("Resource not found")
    
    # 启动服务器
    async with stdio_server() as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())
    • 说明:此示例定义了一个资源 file:///logs/app.log,客户端可以通过 resources/read 获取其内容(文本格式)。
  • 动态资源示例(TypeScript SDK):

    typescript

    javascript 复制代码
    import { Server, ListResourcesRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/server/index.js";
    
    const server = new Server({
        name: "example-server",
        version: "1.0.0",
        capabilities: { resources: {} }
    });
    
    // 列出动态资源
    server.setRequestHandler(ListResourcesRequestSchema, async () => ({
        resources: [{
            uri: "greetings://alice",
            name: "Personal Greeting",
            mimeType: "text/plain"
        }]
    }));
    
    // 读取动态资源
    server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
        const uri = request.params.uri;
        if (uri.startsWith("greetings://")) {
            const name = uri.split("://")[1];
            return {
                contents: [{
                    uri,
                    mimeType: "text/plain",
                    text: `Hello, ${name}! Welcome to MCP.`
                }]
            };
        }
        throw new Error("Resource not found");
    });
    • 说明:此示例支持动态 URI(如 greetings://alice),根据 URI 中的参数生成个性化内容。
  1. 配置 Prompts
  • 步骤:

    1. 定义提示列表(prompts/list),包括提示名称、描述和参数。
    2. 实现提示生成逻辑(prompts/get),根据参数返回结构化提示内容。
  • 代码示例(Python SDK):

    python

    python 复制代码
    from mcp import Server, types
    from mcp.server.stdio import stdio_server
    
    app = Server("example-server", capabilities={"prompts": {}})
    
    # 列出可用提示
    @app.list_prompts()
    async def list_prompts() -> list[types.Prompt]:
        return [
            types.Prompt(
                name="greeting",
                description="A friendly greeting prompt",
                arguments=[types.PromptArgument(name="name", description="The name to greet", required=True)]
            )
        ]
    
    # 生成提示内容
    @app.get_prompt()
    async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
        name_arg = arguments.get("name", "friend")
        user_message = types.PromptMessage(
            role="user",
            content=types.TextContent(f"Hello {name_arg}! How can I assist you today?")
        )
        return types.GetPromptResult(
            description="A personalized greeting message",
            messages=[user_message]
        )
    
    # 启动服务器
    async with stdio_server() as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())
    • 说明:此示例定义了一个 greeting 提示,接受 name 参数,生成个性化问候消息。
  • 代码示例(TypeScript SDK):

    typescript

    php 复制代码
    import { Server, ListPromptsRequestSchema, GetPromptRequestSchema } from "@modelcontextprotocol/sdk/server/index.js";
    
    const server = new Server({
        name: "example-server",
        version: "1.0.0",
        capabilities: { prompts: {} }
    });
    
    // 列出提示
    server.setRequestHandler(ListPromptsRequestSchema, async () => ({
        prompts: [{
            name: "greeting",
            description: "A friendly greeting prompt",
            arguments: [{ name: "name", description: "The name to greet", required: true }]
        }]
    }));
    
    // 生成提示
    server.setRequestHandler(GetPromptRequestSchema, async (request) => {
        const { name, arguments: args } = request.params;
        const nameArg = args.name || "friend";
        return {
            description: "A personalized greeting message",
            messages: [{
                role: "user",
                content: { type: "text", text: `Hello ${nameArg}! How can I assist you today?` }
            }]
        };
    });
    • 说明:此示例实现了一个参数化的提示,客户端可以传递 name 参数生成自定义消息。

使用范例

  1. AlphaVantage MCP Server
  • 简介:为 AlphaVantage 金融 API 提供 MCP 服务器,支持实时股票数据和技术分析。

  • Resources 使用:

    • 资源:stock://AAPL(返回苹果公司股票的实时数据)。

    • 实现:

      python

      less 复制代码
      @app.list_resources()
      async def list_resources() -> list[types.Resource]:
          return [
              types.Resource(
                  uri="stock://AAPL",
                  name="Apple Stock Data",
                  mimeType="application/json"
              )
          ]
      
      @app.read_resource()
      async def read_resource(uri: str) -> str:
          if uri.startswith("stock://"):
              symbol = uri.split("://")[1]
              data = await fetch_stock_data(symbol)  # 调用 AlphaVantage API
              return json.dumps(data)
          raise ValueError("Resource not found")
    • 用途:为 AI 模型提供实时金融数据,作为上下文用于分析或报告生成。

  • Prompts 使用:

    • 提示:stock-analysis(生成股票分析报告,接受股票代码和分析类型参数)。

    • 实现:

      python

      less 复制代码
      @app.list_prompts()
      async def list_prompts() -> list[types.Prompt]:
          return [
              types.Prompt(
                  name="stock-analysis",
                  description="Generate a stock analysis report",
                  arguments=[
                      types.PromptArgument(name="symbol", description="Stock symbol", required=True),
                      types.PromptArgument(name="type", description="Analysis type (e.g., technical)", required=False)
                  ]
              )
          ]
      
      @app.get_prompt()
      async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
          symbol = arguments.get("symbol", "AAPL")
          analysis_type = arguments.get("type", "technical")
          return types.GetPromptResult(
              description="Stock analysis report",
              messages=[types.PromptMessage(
                  role="user",
                  content=types.TextContent(f"Analyze {symbol} stock with {analysis_type} analysis.")
              )]
          )
    • 用途:引导 AI 模型生成结构化的股票分析报告,支持动态参数。

  • 知名度:在金融领域开发者中流行,展示 MCP 如何集成复杂 API 数据。

  1. AbletonMCP Server
  • 简介:连接 Claude AI 和 Ableton Live(数字音频工作站),支持音乐创作和编辑。

  • Resources 使用:

    • 资源:ableton://project/tracks(返回当前 Ableton 项目中的音轨列表)。

    • 实现:

      python

      less 复制代码
      @app.list_resources()
      async def list_resources() -> list[types.Resource]:
          return [
              types.Resource(
                  uri="ableton://project/tracks",
                  name="Ableton Project Tracks",
                  mimeType="application/json"
              )
          ]
      
      @app.read_resource()
      async def read_resource(uri: str) -> str:
          if uri == "ableton://project/tracks":
              tracks = await get_ableton_tracks()  # 调用 Ableton API
              return json.dumps(tracks)
          raise ValueError("Resource not found")
    • 用途:为 AI 提供当前音乐项目的上下文,例如音轨信息,用于生成音乐建议。

  • Prompts 使用:

    • 提示:compose-track(生成新音轨的提示,接受乐器和风格参数)。

    • 实现:

      python

      less 复制代码
      @app.list_prompts()
      async def list_prompts() -> list[types.Prompt]:
          return [
              types.Prompt(
                  name="compose-track",
                  description="Compose a new track in Ableton",
                  arguments=[
                      types.PromptArgument(name="instrument", description="Instrument type", required=True),
                      types.PromptArgument(name="style", description="Music style", required=False)
                  ]
              )
          ]
      
      @app.get_prompt()
      async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
          instrument = arguments.get("instrument", "piano")
          style = arguments.get("style", "classical")
          return types.GetPromptResult(
              description="New track composition",
              messages=[types.PromptMessage(
                  role="user",
                  content=types.TextContent(f"Compose a {style} track using {instrument} in Ableton.")
              )]
          )
    • 用途:引导 AI 生成音乐创作指令,直接控制 Ableton Live。

  • 知名度:在创意领域备受关注,展示 MCP 在艺术和音乐创作中的潜力。

  1. Composio MCP
  • 简介:一个集成平台,简化 AI 代理与外部工具和 API 的连接,支持 Linear、Slack 等。

  • Resources 使用:

    • 资源:linear://issues(返回 Linear 项目中的问题列表)。

    • 实现:

      python

      less 复制代码
      @app.list_resources()
      async def list_resources() -> list[types.Resource]:
          return [
              types.Resource(
                  uri="linear://issues",
                  name="Linear Issues",
                  mimeType="application/json"
              )
          ]
      
      @app.read_resource()
      async def read_resource(uri: str) -> str:
          if uri == "linear://issues":
              issues = await fetch_linear_issues()  # 调用 Linear API
              return json.dumps(issues)
          raise ValueError("Resource not found")
    • 用途:为 AI 提供项目管理数据,作为上下文用于任务分配或状态更新。

  • Prompts 使用:

    • 提示:create-issue(创建 Linear 问题,接受项目 ID 和标签参数)。

    • 实现:

      python

      less 复制代码
      @app.list_prompts()
      async def list_prompts() -> list[types.Prompt]:
          return [
              types.Prompt(
                  name="create-issue",
                  description="Create a Linear issue",
                  arguments=[
                      types.PromptArgument(name="project_id", description="Project ID", required=True),
                      types.PromptArgument(name="label", description="Issue label", required=False)
                  ]
              )
          ]
      
      @app.get_prompt()
      async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
          project_id = arguments.get("project_id")
          label = arguments.get("label", "TODO")
          return types.GetPromptResult(
              description="Create a Linear issue",
              messages=[types.PromptMessage(
                  role="user",
                  content=types.TextContent(f"Create an issue in project {project_id} with label {label}.")
              )]
          )
    • 用途:生成结构化提示,简化 AI 创建和管理 Linear 问题的流程。

  • 知名度:因其一键集成特性广受欢迎,适合快速构建复杂工作流。

相关推荐
TeamDev5 小时前
使用 MCP 自动化 JxBrowser
浏览器自动化·jxbrowser·mcp·模型上下文协议·mcp 自动化·jxbrowser 自动化·jxbrowser mcp
ChaITSimpleLove12 小时前
使用 .net10 构建 AI 友好的 RSS 订阅机器人
人工智能·.net·mcp·ai bot·rss bot
妮妮分享1 天前
维智 MCP 接口服务技术支持指南
mcp·mcp server·维智 mcp·智能体接口
感谢地心引力1 天前
【AI】免费的代价?Google AI Studio 使用指南与 Cherry Studio + MCP 实战教程
人工智能·ai·google·chatgpt·gemini·mcp·cherry studio
AI架构师易筋1 天前
模型上下文协议(MCP)完全指南:从AI代理痛点到实战开发
人工智能·microsoft·语言模型·llm·mcp
qdprobot1 天前
齐护AiTall pro ESP32S3 小智AI对话 MQTT MCP 开发板Mixly Scratch Steam图形化编程创客教育
人工智能·mqtt·scratch·mixly·mcp·小智ai·齐护机器人aitall pro
路西法012 天前
Office-Word-MCP-Server在Cursor中使用方法
cursor·mcp
Light602 天前
【MCP原生时代】第2篇|前端如何舞动 MCP:新一代交互范式——从 Hook 到流式渲染,打造 AI 原生前端体验
状态模式·前端架构·mcp·react hook·流式渲染·ai交互
渣渣苏3 天前
MCP实战指南
mcp
爬点儿啥4 天前
[Ai Agent] 10 MCP基础:快速编写你自己的MCP服务器(Server)
人工智能·ai·langchain·agent·transport·mcp