☰
Claude MCP 服务端原语进阶:Resources 与 Prompts 的选型、实现与源码级解析(claude-plugins-official 实践指南)
2026/10/1 9:19:13 网站建设 项目流程
  • AI 插件
  • 开发工具
  • 插件系统

【免费下载链接】claude-plugins-official

Official, Anthropic-managed directory of high quality Claude Code Plugins.

项目地址:https://gitcode.com/GitHub_Trending/cl/claude-plugins-official
点击查看免费下载

本指南以官方 Claude 插件仓库 claude-plugins-official 中 build-mcp-server 技能 的参考文档 resources-and-prompts.md 为主体,系统讲解 MCP(Model Context Protocol)除工具(Tools)之外的两大服务端原语——资源(Resources)与提示(Prompts)。读完本文,你将掌握"资源适合被主机浏览读取、提示适合被用户以斜杠命令触发"的完整判断模型,能在 TypeScript SDK 与 FastMCP(Python)两套框架中落地静态资源、动态资源模板、订阅通知与参数化提示,并依据决策表在 Tool / Resource / Prompt / Elicitation 之间做出正确选型。


一、三大原语:谁触发,谁读取?

MCP 规范定义了三种服务端原语,其中只有Tools(工具)是模型控制的——Claude 自行决定何时调用某个工具、传入什么参数。而另外两种原语的触发权完全不在模型手里:

原语谁触发触发形态心智模型
Tools(工具)模型(Claude)函数调用"Claude 调用一个函数"
Resources(资源)宿主应用(Host)浏览、拉取入上下文"宿主读取一份数据"
Prompts(提示)用户斜杠命令 / 菜单项"用户点一个模板"

这一点在 resources-and-prompts.md 中被反复强调:资源是 application-controlled,提示是 user-controlled。绝大多数 MCP 服务器只需要工具;只有当你的集成形态不再适配"Claude 调用函数"这个模型时,才应该考虑引入资源与提示。build-mcp-server 技能在 Phase 5 之外也专门提醒开发者:"Most servers start with tools and never need the others, but knowing they exist prevents reinventing wheels"(SKILL.md 的 "Beyond tools" 小节),即:知道它们的存在,能避免重复造轮子。


二、Resources:被"读取"而非被"调用"的数据

资源(Resource)是由 URI 标识的数据。它与工具的本质区别在于:工具是被call的,资源是被read的。宿主应用会先浏览服务器暴露了哪些资源,再决定把哪些加载进上下文。

2.1 什么时候资源优于工具?

参考文档给出了非常清晰的取舍标准(resources-and-prompts.md):

资源占优的场景:

  • 大型参考数据(文档、Schema、配置文件)——Claude 应当能够"浏览"而不是"一次性取回";
  • 独立于对话而变化的内容(日志文件、实时数据)——内容随时间漂移,不适合作为工具返回快照;
  • 任何"由 Claude 决定去取"都是错误心智模型的场景。

工具占优的场景:

  • 操作有副作用(写库、发请求、改状态);
  • 结果依赖 Claude 选择的参数;
  • 你希望Claude(而非宿主 UI)决定何时拉取。

一句话概括:资源是"读"语义,工具是"做"语义。前者关注数据的可浏览性与实时性,后者关注动作的可执行性与参数化。

2.2 静态资源:两种框架的注册写法

TypeScript SDK(resources-and-prompts.md):

server.registerResource( "config", "config://app/settings", { name: "App Settings", description: "Current configuration", mimeType: "application/json" }, async (uri) => ({ contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(config) }], }), );

注意四个参数的次序:资源名(逻辑 ID)→ URI(协议config://+ 路径)→ 元数据对象 → 读取回调。元数据中的mimeType声明内容类型,读取回调返回contents[]数组,每个元素包含uri、mimeType与text。宿主按需调用该回调,把文本内容注入上下文。

FastMCP(Python)(resources-and-prompts.md):

@mcp.resource("config://app/settings") def get_settings() -> str: """Current application configuration.""" return json.dumps(config)

FastMCP 采用装饰器语法,函数返回值即资源内容,一行装饰器完成注册。build-mcp-server 技能在 Phase 4 中将 FastMCP(fastmcp,PyPI 包)与官方 TypeScript SDK 并列为主推框架:TS SDK "best spec coverage, first to get new features",FastMCP "decorator-based, very low boilerplate"(SKILL.md 的 Phase 4 表格)。

2.3 动态资源:RFC 6570 URI 模板

静态资源每个 URI 需要一次注册;当资源是一整族动态数据(如"任意路径下的文件"、"数据库中的任意表")时,用RFC 6570 URI 模板让一次注册服务无数 URI。

TypeScript SDK(resources-and-prompts.md):

import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; server.registerResource( "file", new ResourceTemplate("file:///{path}", { list: undefined }), { name: "File", description: "Read a file from the workspace" }, async (uri, { path }) => ({ contents: [{ uri: uri.href, text: await fs.readFile(path, "utf8") }], }), );

关键点:模板file:///{path}中的{path}会作为第二个参数的解构项传入回调;ResourceTemplate的第二个参数{ list: undefined }控制是否允许宿主枚举该资源族(此处禁用列表)。回调内部执行真实读取(fs.readFile),把文件内容以文本形式返回。

FastMCP(Python)(resources-and-prompts.md):

@mcp.resource("file:///{path}") def read_file(path: str) -> str: return Path(path).read_text()

装饰器路径中的{path}自动绑定为函数参数。动态资源是"暴露一整个命名空间"的利器,例如文档中提到的db://{table}这类场景。

2.4 订阅(Subscriptions):资源变更主动通知

静态与动态资源解决的是"读取",订阅解决的是"变更感知"(resources-and-prompts.md):

  1. 在服务器 capabilities 中声明subscribe: true;
  2. 资源内容变化时,服务器发出notifications/resources/updated通知;
  3. 宿主收到通知后重新读取该资源。

典型适用场景:日志尾部(log tails)、实时仪表盘(live dashboards)、被监控的文件。这让资源从"一次性快照"进化为"可持续跟踪的数据流"。注意订阅功能属于服务器能力(server capabilities)体系的一部分——该参考文件列出了其余可选能力(instructions系统提示注入、sampling 采样委托、roots 工作区边界、logging 结构化日志、progress 进度上报、cancellation 取消、completion 自动补全),并明确指出部分能力需要客户端配合:如 Logging 由服务端声明logging: {}、无客户端支持时退化为 stderr;Sampling、Elicitation、Roots 则必须先检查clientCapabilities再使用。


三、Prompts:用户触发的参数化消息模板

提示(Prompt)是一个参数化的消息模板。宿主把它暴露为斜杠命令或菜单项,用户主动挑选、填写参数,随后生成的 messages 落入当前对话。

3.1 适用场景与 UX 价值

参考文档给出的判断非常直接(resources-and-prompts.md):

When to use:canned workflows users run repeatedly —/summarize-thread,/draft-reply,/explain-error. Near-zero code, high UX leverage.

即:用户会反复执行的固化工作流(如"总结本线程"、"起草回复"、"解释这个报错")。提示几乎不写逻辑,却带来极高的用户体验杠杆——用户不需要背工具名,只需要点一个菜单项。

3.2 注册一个带参数与参数校验的提示

TypeScript SDK(resources-and-prompts.md):

server.registerPrompt( "summarize", { title: "Summarize document", description: "Generate a concise summary of the given text", argsSchema: { text: z.string(), max_words: z.string().optional() }, }, ({ text, max_words }) => ({ messages: [{ role: "user", content: { type: "text", text: `Summarize in ${max_words ?? "100"} words:\n\n${text}` }, }], }), );

argsSchema使用 zod 描述参数约束(z.string()),max_words可选并带默认值兜底(?? "100");回调接收参数、返回messages[],消息体遵循 MCP 内容类型规范({ type: "text", text: ... })。

FastMCP(Python)(resources-and-prompts.md):

@mcp.prompt def summarize(text: str, max_words: str = "100") -> str: """Generate a concise summary of the given text.""" return f"Summarize in {max_words} words:\n\n{text}"

Python 版通过函数签名声明参数、默认值即模板占位,装饰器@mcp.prompt完成注册——与 TS 版是同一套 wire protocol 的两种写法。

3.3 三条硬性约束

参考文档明确列出提示的三条约束(resources-and-prompts.md):

  1. 参数只能是字符串(string-only)——没有 number、boolean、object;需要类型转换时在 handler 内部做;
  2. 返回messages[]数组——不仅可以包含纯文本,还可以内嵌资源(resources)与图片,不限于 text;
  3. 无副作用——handler 只负责"构建一条消息",不执行任何实际操作。

最后一条与工具形成鲜明对比:工具可以写数据、调外部 API;提示永远只产出文本注入对话。如果提示 handler 里出现真实动作,那就是设计错误,应当把动作放回工具。

3.4 提示参数的自动补全(进阶能力)

如果你的提示参数存在大量合法取值,可以进一步为它注册自动补全。同目录的 server-capabilities.md 给出了completable()示例:当用户输入部分值时,服务器实时返回以该前缀过滤的候选值。文档同时提醒这是低优先级能力("Low priority unless your prompts have many valid values"),提示参数只有有限枚举时才值得实现。


四、快速决策表:Tool / Resource / Resource Template / Prompt / Elicitation

参考文档以一张决策表收尾(resources-and-prompts.md),这是整篇的选型精华:

你的诉求应选方案
让 Claude 按需取某样东西、且带参数Tool(工具)
暴露可浏览的上下文(文件、文档、Schema)Resource(资源)
暴露一整个动态资源族(如db://{table})Resource template(资源模板)
给用户一个一键工作流Prompt(提示)
在工具执行中途向用户提问Elicitation(详见 elicitation.md)

决策背后的底层逻辑

结合 SKILL.md 的 "Beyond tools" 小节,这张表可以进一步归纳为触发权的四象限:模型触发→工具;宿主触发→资源;用户触发→提示;服务器中途触发→ Elicitation / Sampling。四个原语各管一段触发权,互不重叠。

关于Elicitation(表末第五行),elicitation.md 给出了规范级说明:它让服务器在工具调用中途暂停、向用户索要结构化输入,宿主渲染原生表单(无需 iframe/HTML)。但宿主支持还很新——Claude Code 自 v2.1.76 起支持(form与url两种模式),Claude Desktop 未确认,claude.ai 未知;SDK 在客户端未声明该能力时会直接抛出CapabilityNotSupported。因此标准做法是先检查caps.elicitation再调用,并提供文本回退(让 Claude 转述问题、用户答复后重试)。此外,安全红线是:不得通过 Elicitation 索取密码、API Key 或令牌(规范要求,这些必须走 OAuth 或敏感配置项)。


五、在 build-mcp-server 技能工作流中的定位

把本指南放回上下文:build-mcp-server是 mcp-server-dev 插件的入口技能,完整路径为 plugins/mcp-server-dev/skills/build-mcp-server/SKILL.md,它通过五个阶段引导开发者——询问用例(连接对象、使用者、动作数量、是否需要中途输入与展示、上游认证方式)→ 推荐部署模型(远程流式 HTTP / MCP App / MCPB / 本地 stdio)→ 选择工具设计模式(小表面一动作一工具;大表面 search + execute)→ 选择框架(TS SDK 或 FastMCP)→ 脚手架搭建与交接。

Resources 与 Prompts 是这条主流程之外的"第二层原语"(该技能在 Phase 5 与 Phase 6 之间专门列出 "Beyond tools" 小节),并显式指向本参考文件(references/resources-and-prompts.md)。技能文档给出的定位建议与参考文件完全一致:

  • 需要给 Claude 暴露可浏览的文档/文件/Schema→ 资源;
  • 需要给用户提供固化工作流(/summarize-thread之类)→ 提示;
  • 需要中途结构化提问→ Elicitation;
  • 需要在工具逻辑里做LLM 推理→ Sampling(references/server-capabilities.md)。

一个值得记住的实践结论:多数服务器从工具起步、终其一生不需要资源和提示;资源与提示是"形状不对时才伸手去够"的备用件——一旦用对,能省掉大量重复的"取数据/拼提示词"工具逻辑,同时把触发权交还给最合适的一方(宿主与用户)。


六、小结与延伸阅读

本文完整继承了参考文档的全部内容:三大原语的触发权模型、资源优于/劣于工具的六条标准、静态资源与动态资源模板的 TS/Python 双版本代码、订阅机制、提示的适用场景与三条硬约束,以及五选一决策表,并补充了来自同仓库其他参考文件的源码级证据(Elicitation 能力检查与回退模式、sampling 委托、completion 补全、logging 退化策略等)。

若需继续深入,可在当前仓库按以下顺序阅读:

  • resources-and-prompts.md(本文主体)
  • server-capabilities.md(instructions / sampling / roots / logging / progress / cancellation / completion)
  • elicitation.md(中途结构化提问:能力检查 + 回退 + 安全红线)
  • SKILL.md(build-mcp-server 入口技能:五阶段决策流)
  • tool-design.md(工具描述与 Schema 编写指南)
  • 插件总览 README(三个技能的协作关系)
  • AI 插件
  • 开发工具
  • 插件系统

【免费下载链接】claude-plugins-official

Official, Anthropic-managed directory of high quality Claude Code Plugins.

项目地址:https://gitcode.com/GitHub_Trending/cl/claude-plugins-official
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询