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 问题的流程。

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

相关推荐
MobotStone10 小时前
MCP还是AI智能体?如何为你的AI应用选择最佳"大脑"架构
mcp
shelgi12 小时前
Cursor结合MCP实现自动编写项目文档
人工智能·mcp
小白跃升坊13 小时前
干货分享|智能问数方案及步骤详解
ai·大语言模型·it运维·mcp·max kb
yaocheng的ai分身14 小时前
Building MCP Servers: Part 3 — Adding Prompts
mcp
一只韩非子15 小时前
什么是MCP?为什么引入MCP?(通俗易懂版)
人工智能·aigc·mcp
MCPFlow16 小时前
Cursor+高德MCP制定五一出游攻略
mcp
叫我阿杰好了16 小时前
Trae中 使用MCP 案例
mcp·trae
Yan-英杰17 小时前
百度搜索AI开放计划:让应用连接精准流量的秘诀
ai·mcp·百度搜索开放平台·百度ai开放计划·mcpserver·create2025
码云之上17 小时前
聊聊MCP Client及其实践
前端·架构·mcp