在 Model Context Protocol (MCP) 中,Resources 和 Prompts 是两种核心功能(Primitives),用于增强 AI 模型与外部数据和工具的交互能力。
Resources 和 Prompts 的定义与作用
- 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),也可能自动选择(取决于客户端实现)。
- 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)。以下是具体步骤和代码示例:
- 环境准备
-
安装 SDK:
- Python: pip install mcp 或 uv add "mcp[cli]"。
- TypeScript: npm install @modelcontextprotocol/sdk。
-
选择传输方式:MCP 支持 Stdio(标准输入/输出)或 SSE(服务器推送事件)。本地开发通常使用 Stdio。
-
工具:推荐使用 MCP Inspector 进行调试,验证服务器功能。
- 配置 Resources
-
步骤:
- 定义资源列表(resources/list),包括 URI、名称、描述和 MIME 类型。
- 实现资源读取逻辑(resources/read),根据 URI 返回内容。
- 可选:实现资源更新通知(如 resources/list_changed)。
-
代码示例(Python SDK):
python
pythonfrom 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
javascriptimport { 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 中的参数生成个性化内容。
- 配置 Prompts
-
步骤:
- 定义提示列表(prompts/list),包括提示名称、描述和参数。
- 实现提示生成逻辑(prompts/get),根据参数返回结构化提示内容。
-
代码示例(Python SDK):
python
pythonfrom 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
phpimport { 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 参数生成自定义消息。
使用范例
- 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 数据。
- 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 在艺术和音乐创作中的潜力。
- 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 问题的流程。
-
-
知名度:因其一键集成特性广受欢迎,适合快速构建复杂工作流。