一为什么要做这场分享

社区目前 1 万多个 MCP server,绝大多数只用了协议里最容易的那一块——工具(tools)。但 MCP 协议设计里其实有 5 个原语(3 个 server 端 + 2 个 client 端),合在一起能让 LLM 应用做出比"工具调用"丰富得多的交互。

这次演讲的目标:

  1. 把 5 个原语过一遍,重点讲少有人用的那几个;
  2. 用一个聊天 App 例子演示怎么把 5 个原语组合起来;
  3. 谈 MCP 下一步——从本地走向 Web。

二5 个原语的全景

最关键的区别在于"谁来发起":

原语谁来发起一句话定位典型场景
Prompts用户预制好的提示模板,用户主动调入上下文slash 命令、@cmd 命令
Resources应用原始数据/内容,由 client 应用决定怎么用文件式挂载、RAG embedding
Tools模型可被模型自主调用的动作查数据库、改文件
SamplingServer让 client 帮 server 做一次模型推理server 内部想用 LLM 但不持模型
RootsServer询问 client 当前开着哪些工作区/目录像 IDE 这类多 workspace 的环境
"应该让数据出现的时机和意图,决定你用哪个原语"——这是 David 给的核心判断准则。

三Prompts:用户主动调入的"模板"

Prompts 是 MCP 里最被忽视的原语之一。 一句话:MCP server 可以暴露一组"提示模板",让用户在 client 里主动选用。

它解决了什么问题

  • 你(作者)最懂自己的 server 该怎么用——把"招牌玩法"打包成 prompt,让用户开箱即上手;
  • prompts 是动态执行的——背后就是代码,不只是静态模板。可以在用户调用时去远端抓数据。

例子:把 PR comments 拉进上下文

用户敲 /pr-comments,prompt 背后就去 GitHub 拉 PR 评论,直接进上下文,然后用户跟模型说"按这些 review 意见把代码改一下"。

鲜为人知的加分项:Prompt Completion

定义 prompt 时还能给参数附补全函数。用户敲完 /pr-comments 后,弹出可选 PR 列表供选择。在 TypeScript 里实现这个需求只要几行——一个 completion 函数 + 一个生成 prompt 的函数,Claude Code + Claude 4 基本能直接给你写出来。

四Resources:应用驱动的"原始数据接入"

Prompts 是给用户用的,Resources 是给应用(client)用的。

Resource 的三种消费方式

  • 方式一:加入上下文窗口
  • 方式二:做 embedding / RAG 召回
  • 方式三:像文件一样挂在边栏

它解决了什么问题

  • 应用决定怎么用这份数据——上下文/索引/UI 渲染都行;
  • 是 MCP 中比较被低估的原语:很多人只想着"加进上下文",但 client 完全可以拿来做 embedding/RAG。

例子:暴露数据库 schema

用 Astra DB 的 MCP server 把库表 schema 作为 resource 暴露。在 Claude Desktop 里像挂文件一样把表挂上,然后说"画一张 ER 图",Claude 自己读 schema 自己画图。

五Tools:模型驱动的动作

第三个 server 端原语,大家都熟:模型在跑的过程中自己决定要不要调用。David 说"建过 MCP server 的人,第一次看到模型自己调用你建的工具——是最有魔力的时刻"。

六决定用哪一个:Interaction Model(交互模型)

3 个 server 原语功能上有重叠(都能往上下文里塞东西),到底用谁?协议规范里其实埋着答案,叫 interaction model:

原语由谁触发同一份数据按"何时出现"决定用谁
Prompts用户 主动用户想立刻把它推到上下文里时
Resources应用 决定应用层有自己的策略——索引、按需召回、UI 渲染
Tools模型 自主模型在解决任务时按需调用

七Sampling:server 反过来让 client 跑一次模型

David 抛了个具体问题:

"我想给一个 issue tracker 做 MCP server,支持「总结某 issue 的讨论」。总结需要模型——但 server 又不知道 client 用的是哪个模型,更没有 client 的 API key。怎么办?"

最朴素的做法是 server 自己装 Anthropic SDK + 自己要个 key——立刻就尴尬:

  • 用户要在 server 上又配一把 API key;
  • 把"哪个模型、谁付钱、谁审隐私"的控制权从 client 抢走。

Sampling 的本质

让 server 反过来请求 client 帮忙做一次推理。

它带来的两个红利:
  1. Client 始终掌握安全 / 隐私 / 成本——用户在 client 那里看清楚每次推理付了多少 token、走了哪个模型,不用再额外给 server 一把 key;
  2. 可递归 / 可链式——server A 调 server B,B 再要 sampling,请求一路冒泡到最上层的 client。任何一个 MCP server 想用模型,都向上要,永远是同一个 client 守门。
David 坦言:sampling 是最让他兴奋、但目前 client 支持最差的原语。 Anthropic 第一方产品今年内会落地。

八Roots:server 反过来问 client "你都开了哪些工作区"

第二个 client 端原语。命名 David 自己也吐槽"起得不好"。

它解决什么

想象你做一个 git MCP server——希望它在 IDE 里跑 git 命令。问题:

server 怎么知道用户的 IDE 此刻开着哪些工程目录?

Roots 就是 client 暴露给 server 的"我现在打开了这些目录"接口,server 拿到后只在这些目录里干活,不乱跑。

VS Code 目前已经支持 roots。

九把 5 个原语组合起来:一个聊天应用的 MCP server

David 给的端到端例子——给 Slack / Discord 这类聊天 App 做 MCP server:

原语在这个 server 里怎么用
Promptssummarize-this-discussion、what-happened-since-yesterday 这种 slash 命令,用户直接调入
Prompt Completion在 summarize-this-discussion 的参数里给"最近的 thread 列表"做自动补全
Resources把"频道列表""最近 thread"暴露给 client;client 自己决定要不要 index、要不要做 RAG
Toolssearch_messages、read_channel、read_thread 这些动作
Sampling在 summarize_thread 内部要做总结时,反过来让 client 跑模型
用户、应用、模型三条交互链路都被覆盖,不再只是"等模型调工具"。

十MCP 的下一步:从本地走向 Web

社区现在 1 万多个 server,绝大多数是本地的——Docker 容器、本地可执行。下一步:让 MCP server 成为网站——client 直接连 URL 就能用。

要走这一步需要两块基础:

  1. Authorization(授权)——把私有数据安全地接入 LLM 应用;
  2. Scaling(可伸缩)——server 能像普通 Web API 一样横向扩展。

授权:OAuth 2.1

MCP 规范现在要求远程 server 走 OAuth 2.1。这个名字听着唬人,实际上就是 OAuth 2.0 + 业界已经在做的安全加固。

场景关键收益
公网产品用户在 client 里直接配 mcp.payment.com,OAuth 登一下,不再需要信任随便一个开发者放在本地的 Docker 镜像——信任锚回到原服务
企业内部现有 SSO / 身份提供方(Okta / Azure AD)继续生效,员工早上登一次,全天调任何内部 MCP server 都自动鉴权

可伸缩:Streamable HTTP

新增的 Streamable HTTP 让 MCP server "像普通 REST API 一样水平扩展":

情形行为
简单 tool 调用直接 return application/json,连接关闭,下一次请求另一个 Lambda 接
需要流式 / 后续推送(sampling、notification 等)升级到 stream,server 可以在最终 return 之前来回发消息

结果:MCP server 可以放在 Lambda / Cloud Run / 任何 serverless 上,跟普通 API 一样部署。

十一未来几个月路线图

类别功能说明
协议规范Async tasks支持几小时级长任务
Elicitationserver 向用户主动要输入
官方 Registry统一发现/发布
多模态结果流式、其他媒介
生态Ruby SDKShopify 捐赠
Go SDKGoogle Go 团队官方实现

特别提一下 Elicitation:服务器能反过来问用户拿输入。例如"我需要你确认这个邮箱地址再继续"。这在做 MCP agent 时非常关键。

十二一页速查

原语方向触发者何时考虑
Promptsserver → client用户想给 server 配一组"招牌玩法"或 slash 命令
Resourcesserver → client应用想让 client 用更高级的方式(RAG / 索引)消费数据
Toolsserver → client模型经典动作调用
Samplingclient → serverserver 反向server 内部要用 LLM 但不该自己持模型/key
Rootsclient → serverserver 反向server 需要知道 client 当前的 workspace 范围
一句话外带:大多数人把 MCP 当成"暴露工具的协议",实际上 MCP 是一份关于"AI 应用 / 用户 / 模型三方协作"的完整协议——5 个原语恰好覆盖了 3 方所有方向的交互。要做出比工具调用更丰富的体验,先把 prompts / resources / sampling / roots 这四个被冷落的原语用起来。