理解MCP中的Prompts、Resources、Tools、Roots、Sampling原语

原语解释

MCP 协议目前定义了 5 个核心原语,可以按"谁做主"分成 3 组

分组 原语 控制权 作用一句话 典型使用场景示例
用户主导 Prompts(提示模板) 用户 把常见对话流程变成可复用模板 IDE 里输入 /explain-code 自动套用"逐行解释"模板
应用主导 Resources(资源) 应用/客户端 把外部只读数据注入上下文 Claude Desktop 把本地 file:///home/user/budget.xlsx塞进对话做报表分析
模型主导 Tools(工具) LLM 让 LLM 主动调用函数完成动作 用户说"把这张表存成 CSV",LLM 调用 save_csv(tool_input)
客户端辅助 Roots(根目录) 客户端 告诉服务器"只能动哪些目录" VS Code 里 MCP Git 插件只被允许读写当前工作区
反向调用 Sampling(采样) 服务器 MCP 服务器反过来让 LLM 生成内容 服务器先自己写好一段 SQL,再让 LLM 优化

代码示例

所有代码都可直接跑在 Node 20+ 环境,先装依赖: npm i @modelcontextprotocol/sdk


  1. Prompts(提示模板) 场景:用户敲 /explain-code 让 IDE 自动生成逐行讲解。
ts 复制代码
// server.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new Server(
  { name: 'demo-prompts', version: '1.0.0' },
  { capabilities: { prompts: {} } }
);

server.setRequestHandler('list_prompts', async () => ({
  prompts: [
    {
      name: 'explain-code',
      description: '逐行解释选中的源码',
      arguments: [
        { name: 'code', description: '要解释的源码', required: true }
      ]
    }
  ]
}));

server.setRequestHandler('get_prompt', async ({ name, arguments: args }) => {
  if (name === 'explain-code') {
    return {
      description: `逐行解释以下代码:\n${args.code}`,
      messages: [
        {
          role: 'user',
          content: { type: 'text', text: `逐行解释以下代码:\n${args.code}` }
        }
      ]
    };
  }
  throw new Error('Unknown prompt');
});

const transport = new StdioServerTransport();
server.connect(transport);

  1. Resources(只读资源) 场景:把本地 todo.md 注入对话,让 AI 基于它回答问题。
js 复制代码
server.setRequestHandler('list_resources', async () => ({
  resources: [
    {
      uri: 'file:///Users/alice/todo.md',
      name: '今日待办',
      mimeType: 'text/markdown'
    }
  ]
}));

server.setRequestHandler('read_resource', async ({ uri }) => {
  if (uri === 'file:///Users/alice/todo.md') {
    const fs = await import('fs/promises');
    const text = await fs.readFile('/Users/alice/todo.md', 'utf8');
    return { contents: [{ uri, mimeType: 'text/markdown', text }] };
  }
  throw new Error('Resource not found');
});

  1. Tools(LLM 可调用的函数) 场景:用户说"把这段文字存成文件",LLM 调用 write_file 工具。
js 复制代码
import { z } from 'zod';
const WriteFileArgs = z.object({ path: z.string(), content: z.string() });

server.setRequestHandler('list_tools', async () => ({
  tools: [
    {
      name: 'write_file',
      description: '把内容写入磁盘',
      inputSchema: WriteFileArgs
    }
  ]
}));

server.setRequestHandler('call_tool', async ({ name, arguments: args }) => {
  if (name === 'write_file') {
    const { path, content } = WriteFileArgs.parse(args);
    const fs = await import('fs/promises');
    await fs.writeFile(path, content, 'utf8');
    return { content: [{ type: 'text', text: `已写入 ${path}` }] };
  }
  throw new Error('Unknown tool');
});

  1. Roots(安全根目录) 客户端在连接时把工作目录设为 root,服务器只能访问该目录:
js 复制代码
server.setRequestHandler('initialize', async (params) => {
  const roots = params.roots ?? []; // 如:[{ uri: 'file:///workspace/project' }]
  console.log('允许访问的根目录:', roots);
  return {
    protocolVersion: '2024-11-05',
    capabilities: { tools: {}, resources: {}, prompts: {} },
    serverInfo: { name: 'demo-roots', version: '1.0.0' }
  };
});

  1. Sampling(服务器反向让 LLM 生成) 场景:MCP 服务器自己写好 SQL 后,再让 LLM 优化。
js 复制代码
// 假设 server 已具备 sampling 能力
const optimized = await server.request(
  { method: 'sampling/createMessage', params: {
    messages: [
      { role: 'user', content: { type: 'text', text: '请把以下 SQL 优化成 JOIN 形式:SELECT * FROM orders, users WHERE orders.user_id = users.id' } }
    ],
    maxTokens: 200
  }}
);
console.log('LLM 优化结果:', optimized.content.text);
相关推荐
米小虾7 小时前
MCP 协议深度解析:AI 时代的「USB-C」接口如何重塑智能体生态
人工智能·mcp
库洛西鲁7 小时前
OpenClaw 16G 内存怎么配模型?实测 3 套方案,最后一套跑满不卡
claude·mcp
JaydenAI7 小时前
[MCP在LangChain中的应用-03]在Session构建的上下文中与MCP Server交互
python·langchain·ai编程·ai agent·mcp·fastmcp
Elastic 中国社区官方博客9 小时前
通过 Elastic MCP Server 将 Cursor 连接到生产日志
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索·mcp
冲上云霄的Jayden9 小时前
一文详细介绍Skill、Slash Command、MCP、Rules怎么选?Skill适用那些场景?
rules·skill·mcp·ai时代·slash command·skill场景
易生一世10 小时前
Kiro CLI调用MCP servers
agent·mcp·kiro
sinat_367104561 天前
claude code 接入 百度搜索 mcp
百度·mcp·claude code
用户3397995308311 天前
Qwen2.5-72B 指令微调映射,DМ‌XΑ‌РΙ 稳调通义模型输出
mcp
一直会游泳的小猫1 天前
Claude Code 连 MySQL:保姆级教程
mysql·mcp·claude code
最强小杰2 天前
OpenClaw 安装踩坑全记录:npm 和 Bun 两种方式的原理差异与实战配置(2026)
ai编程·mcp