云加社区

一文搞懂MCP开发

关注腾讯云开发者,一手技术干货提前解锁👇
Image
Image
Image

开发者公众号专属群聊

扫码加入获取更多一手教程、科技前沿报告

MCP(Model Context Protocol)是 Anthropic 于 2024 年底开源的协议,定义了 AI 应用发现和调用外部能力的标准方式。本文从"为什么需要 MCP"出发,逐步讲解协议的核心概念、安全模型与传输机制。

基于 MCP 规范 2026-07-28 和 TypeScript SDK v2(@modelcontextprotocol/server)。

01

什么是 MCP

 1.1 什么是 MCP

在 MCP 出现之前,AI 应用对接外部系统时,每个组合都需要编写一套专用的胶水代码:对接 Notion 的 API、将响应转换为模型可消费的格式、再接入 Cursor 的工具系统。更换 Host(Claude、VS Code)或数据源(Sentry、TAPD)后,整套集成工作需要重新实现。3 个 AI 应用 × 3 个数据源 = 9 套集成。

没有 MCP:每个组合各写一套

Image

MCP 的方案是在中间引入一层标准协议,将"如何建立连接、如何发现能力、如何调用工具"统一约定:

  1. Server 侧:数据源方按协议暴露能力——声明工具(名称、描述、参数 schema)、资源与提示模板。底层仍然调用自身的 REST API,但对 Host 仅暴露统一的 tools/list、tools/call 等接口。

  2. Host 侧:AI 应用实现一次 Client——具备发现工具、将 schema 传递给模型、按协议发起调用、将结果回注对话上下文的能力。此后对接任何 MCP Server 均可复用同一条路径。

  3. 模型侧:无需感知底层是 Notion 还是 Sentry,仅依据工具描述与参数 schema 决定调用时机和传参内容。

由此 M×N 降为 M+N:每个数据源实现一个 Server,每个 AI 应用完成一次 Client 适配。Notion 发布官方 MCP Server 后,Cursor、Claude、VS Code 均可直接接入,无需各自重复实现 Notion 集成。

有 MCP:协议居中,两侧各实现一次

Image

 1.2 MCP vs Function Calling

一个常见的问题是:"MCP 和 OpenAI 的 Function Calling 有什么区别?"两者并非替代关系,而是分属不同抽象层次:

Image

概括而言:Function Calling 定义了"模型如何表达调用意图",MCP 定义了"调用意图如何标准化地到达外部系统"。

两者的差异可直接体现在代码层面。以"搜索文档"工具为例:

Function Calling(无 MCP):工具 schema 与执行逻辑均由应用侧维护。

const tools = [{  name: 'search_docs',  description: '按关键词搜索文档',  parameters: { type: 'object', properties: { query: { type: 'string' } } }}];const res = await openai.chat.completions.create({ messages, tools });// 模型返回 function_call 后,执行逻辑仍需由业务侧实现:const result = await searchDocs(JSON.parse(res.function_call.arguments));

更换数据源时,schema 与执行代码均需重复实现。

MCP:schema 与执行逻辑封装于 Server 内,应用侧仅需一行配置。

{ "mcpServers": { "docs": { "url": "https://mcp.docs.example.com" } } }

实际运行中两者是串联的——Host 将 MCP Server 的 tools/list 转换为 Function Calling 格式交给模型,模型选定工具后,Host 再通过 MCP 协议发起调用:

Image

对应上一节的 M×N 问题:Function Calling 标准化了"模型 → 工具"这一环节,但"工具 → 外部系统"的后续环节仍需各应用独立实现——MCP 标准化的正是后者。

 1.3 Agent / Skill / MCP / CLI

MCP 并非独立使用,它与 Agent、Skill、CLI 分属不同层次。以类比说明:Agent 相当于项目经理,负责分解任务与决策调度;Skill 相当于操作手册,规定"这件事按什么步骤执行";MCP 相当于外部服务的标准接口,类似于企业内部的 API 网关;CLI 则是可直接调用的现有工具。

Image
Image

实际任务中它们常组合使用。以"按文档站规范检查一篇稿件并提交 PR"为例:

  1. Agent 分解目标:查阅规范 → 检查内容 → 修复问题 → 提交 PR

  2. Skill 提供检查清单:标题层级、代码块标注语言、术语首次出现使用全称

  3. MCP 获取外部数据:从 iWiki 检索最新术语表、从 TAPD 查询关联需求编号

  4. CLI 执行本机操作:pnpm lint 检查格式、gh pr create 提交 PR

选型原则:固定流程写入 Skill,动态数据通过 MCP 获取,本机操作交由 CLI 执行。

 1.4 适用场景

需要明确一个前提:MCP 是面向 AI 应用的协议,而非面向终端用户的 API。它架设在已有的 API 或数据层之上,约定的是"模型如何发现和调用能力",并不替代业务中间层本身。

适合引入的场景:

  • 多个 AI 应用需要共享同一套能力(Cursor + Claude + 自研产品)

  • 底层已具备稳定的 API 或数据层

  • 读写操作需要分级授权,关键操作需要审计

不适合引入的场景:

  • 调用方不涉及模型参与(网页前端、脚本、定时任务)——此时直接调用 REST API 即可

  • 仅有一个完全可控的 AI 应用,将工具定义硬编码即可满足需求

  • 底层 REST API 尚未稳定——MCP 无法弥补底层业务能力的缺失

生态层面,主流服务商已普遍跟进,官方和社区的 Server 实现层出不穷,以下仅列举部分代表:

Image

02

核心概念

以一次完整的工具调用串联所有概念:用户在 Cursor 中输入"搜索文档站里关于认证的内容",从这条指令出发,观察各层如何协作。以下是全流程时序总览,后续小节将逐一展开。

Image

 2.1 三个角色

指令首先到达 Host(Cursor),Host 内部为每个已配置的 MCP Server 维护一个 Client 实例,由 Client 负责与对应的 Server 通信。

Image

Host 与 Server 不直接交互,中间始终经过 Client。一个 Host 可同时持有多个 Client(文档站、TAPD、iWiki 等),各连接彼此隔离。

 2.2 两层架构

Client 与 Server 之间的通信分为两层:

  • 数据层:基于 JSON-RPC 2.0,定义方法(tools/list、tools/call、resources/read、server/discover 等)及其请求 / 响应格式。

  • 传输层:决定消息的传输方式——本地部署使用 stdio(Host 以子进程方式启动 Server),远程部署使用 Streamable HTTP。第 3 节将展开传输层细节。

 2.3 能力协商

在发起任何工具调用之前,Client 首次连接时需先发送 server/discover 请求,获取 Server 的能力声明:

// 请求{  "jsonrpc": "2.0",  "id": 0,  "method": "server/discover",  "params": {    "_meta": {      "protocolVersion": "2026-07-28",      "clientInfo": { "name": "cursor", "version": "0.50" }    }  }}
// 响应{  "jsonrpc": "2.0",  "id": 0,  "result": {    "protocolVersion": "2026-07-28",    "serverInfo": { "name": "docs-assistant", "version": "1.0.0" },    "capabilities": {      "tools": {},      "resources": { "subscribe": true },      "prompts": {}    }  }}

请求通过 _meta 声明 Client 期望的协议版本,响应中的 protocolVersion 即双方最终协商的版本——版本不匹配时 Server 返回 UnsupportedProtocolVersion 错误。capabilities 中声明的键即为 Server 支持的能力集:tools 表示支持工具调用,resources 表示支持资源读取,subscribe: true 表示 Server 支持资源变更的主动推送。Client 根据此响应确定可用的方法集合,避免向不支持对应能力的 Server 发送无效请求。

 2.4 三种原语

能力协商完成后,Host 已获知 Server 支持的能力集。MCP 将 Server 的能力抽象为三种原语,核心区分在于控制权归属:

原语
控制方
在此场景中
其他典型用途
Tools
模型决定调用
模型判断需要搜索,自主调用 search-docs
create-issue
、send-message
Resources
应用层注入上下文
Cursor 将写作规范注入对话,供模型参考
数据库 schema、API 文档
Prompts
用户主动选择
用户选择"审校文档"模板,预组装一组消息
"写发布说明"、"分析错误日志"

Tools

Tools 是实际开发中使用频率最高的原语。与传统 API 不同,MCP 的调用方是概率模型——模型依据工具的 description 决定调用时机与传参内容,因此工具描述的质量直接影响调用准确率。

模型决定调用 search-docs 后,Client 向 Server 发出如下 JSON-RPC 请求:

{  "jsonrpc": "2.0",  "id": 1,  "method": "tools/call",  "params": {    "name": "search-docs",    "arguments": { "query": "认证", "limit": 5 },    "_meta": {      "protocolVersion": "2026-07-28",      "clientInfo": { "name": "cursor", "version": "0.50" }    }  }}

Server 处理完成后返回响应:

{  "jsonrpc": "2.0",  "id": 1,  "result": {    "content": [      { "type": "text", "text": "找到 1 篇文档:\n\n- **身份认证** (id: authentication)" }    ]  }}

注意 _meta 字段:协议要求所有客户端请求都必须携带它(server/discover、tools/call、resources/read、prompts/get 等无一例外,缺失会收到 -32602 错误),其中声明协议版本与客户端身份信息。自 2026-07-28 规范起,MCP 采用无状态协议设计——服务端不维护连接上下文,不依赖前序请求的状态。这使得远程 Server 天然具备水平扩展能力;但相应地,跨请求的业务状态(如购物车、工作流 ID)需由 Client 在每次请求中显式传递。

Resources

Resources 是 Server 向 Host 暴露的只读数据。与 Tools 的核心区别在于:Tools 是模型主动调用的"动作",Resources 是应用层主动拉取的"上下文"——由 Host 决定何时读取并注入对话,模型不直接参与控制。

Client 通过 resources/list 发现可用资源,再通过 resources/read 读取内容:

// 请求{  "jsonrpc": "2.0",  "id": 2,  "method": "resources/read",  "params": {    "uri": "docs://style-guide",    "_meta": {      "protocolVersion": "2026-07-28",      "clientInfo": { "name": "cursor", "version": "0.50" }    }  }}
// 响应{  "jsonrpc": "2.0", "id": 2,  "result": {    "contents": [      {        "uri": "docs://style-guide",        "mimeType": "text/markdown",        "text": "# 写作规范\n\n- 标题不超过三级\n- 术语首次出现用全称..."      }    ]  }}

若 Server 在能力协商中声明了 resources.subscribe: true,Client 可订阅指定资源的变更通知。当资源更新时,Server 主动推送 notifications/resources/updated,Client 重新拉取最新内容,无需轮询。

Prompts

Prompts 是 Server 预定义的消息模板,由用户在 Host 的界面中主动选择触发(如 Cursor 的斜杠命令)。Host 调用 prompts/get 获取预组装的消息数组,直接注入对话上下文:

// 请求{  "jsonrpc": "2.0",  "id": 3,  "method": "prompts/get",  "params": {    "name": "review-doc",    "arguments": { "doc_id": "authentication" },    "_meta": {      "protocolVersion": "2026-07-28",      "clientInfo": { "name": "cursor", "version": "0.50" }    }  }}
// 响应{  "jsonrpc": "2.0", "id": 3,  "result": {    "messages": [      {        "role": "user",        "content": {          "type": "text",          "text": "请按照写作规范审校以下文档,检查标题层级、术语用法和代码块标注..."        }      }    ]  }}

Prompts 的核心价值在于将领域知识固化在 Server 侧:审校规则、输出格式、上下文组装逻辑均由 Server 维护,用户无需每次手动编写复杂的 prompt。模板支持参数化(如 doc_id),由 Host 在调用时注入具体值。

 2.5 反向能力:Sampling 与 Elicitation

前述三种原语均属于 Host → Server 方向的交互:Host 发现能力、调用工具、读取资源。MCP 还定义了两种 Server → Host 方向的能力,使 Server 在处理请求时可以反向利用 Host 侧的资源。

Sampling:委托模型推理

Server 在执行工具逻辑时,有时需要模型的推理能力,但 Server 本身并不持有模型。Sampling 机制允许 Server 向 Client 发送 sampling/createMessage 请求,由 Host 调用自身的模型完成一次推理,再将结果返回给 Server。

Image

典型场景:日志分析 Server 接收到一段 5000 行的原始日志,自身不具备文本摘要能力,于是通过 Sampling 请求 Host 调用模型提取关键错误信息,获得摘要后再执行后续分析。

Host 对 Sampling 请求拥有完全控制权——可以拒绝请求、修改 prompt 内容,或通过弹窗向用户请求确认。Server 无法绕过 Host 直接操控模型。

Elicitation:向用户征集信息

Server 执行过程中可能缺少关键输入。Elicitation 允许 Server 向 Client 发送 elicitation/create 请求,由 Host 向用户展示表单或确认对话框,收集用户输入后回传给 Server。

典型场景:部署工具检测到存在多个可选环境,通过 Elicitation 请求用户选择"部署到 staging 还是 production";或数据库工具在执行 DROP 操作前,请求用户输入确认文本。

两种反向能力的共同特征:请求由 Server 发起,但控制权始终归属于 Host 和用户。Host 可拒绝任何反向请求,Server 无法直接触达用户。

 2.6 Tool Annotations

注册工具时可附加 annotations,向 Host 声明工具的行为特征:

Image

tools/list 返回的每个工具都携带自己的注解,例如:

{  "name": "search-docs",  "title": "搜索文档",  "description": "按关键词搜索文档标题和内容",  "inputSchema": { "type": "object", "properties": { "query": { "type": "string" } } },  "annotations": {    "readOnlyHint": true,    "destructiveHint": false,    "idempotentHint": true,    "openWorldHint": false  }}

search-docs 声明自己是只读、幂等且不访问外网的查询工具——Host 据此可以免确认、允许自动重试,并适度放宽沙箱限制。而一个删除类工具通常会声明 destructiveHint: true、idempotentHint: false,促使 Host 展示确认对话框。

字段名中的 Hint 后缀是规范的刻意设计——注解仅作为参考建议,不构成安全约束。具体原因由下文的信任模型进一步阐述。

 2.7 信任边界

MCP 涉及多方参与者,厘清信任关系是做出正确安全决策的前提:

Image

三条核心原则:

  1. Host 信任用户,不信任 Server。Server 提供的 Tool Annotations、工具描述、返回内容均可能包含恶意信息。Host 必须对破坏性操作执行独立校验(如展示确认对话框),不应仅凭 destructiveHint: false 就跳过安全确认。

  2. Server 不信任 Client。任何请求参数均可能被伪造,Server 必须执行输入校验与权限检查,不应假定 Client 一定来自合法 Host。

  3. 反向能力受 Host 管控。Sampling 和 Elicitation 请求由 Host 拦截与审核,Server 无法绕过 Host 直接触达模型或用户。

这正是 Tool Annotations 采用 Hint 后缀的设计意图——它们属于 Server 的自我声明,而非 Host 的安全策略。Host 可将注解作为 UI 提示的参考依据,但安全决策必须基于自身的策略引擎。

03

本地 vs 远程

 3.1 协议演进

在展开两种部署模式之前,先简要回顾协议的关键演进节点。若在早期文档或代码中遇到 initialize、SSE transport、session ID 等概念,它们属于历史版本,当前规范已不再使用。

Image

 3.2 从本地到远程

MCP 最初仅支持本地部署:Host 启动一个子进程,通过 stdin/stdout 通信。这种模式适用于本机文件访问、个人密钥管理、开发者本地安装的工具等场景——进程与编辑器共存,配置存储于本机,通过环境变量注入 API Key 即可运行。

但本地模式很快暴露出局限性:

  • 分发成本高:团队 20 人使用同一个内部工具,每人均需安装 Node、配置环境变量、跟踪版本。Server 升级后,全员需要同步更新。

  • 凭证管理分散:API Key 存储于各开发者的本机配置中,无法集中吊销、轮换,审计也难以实施。

  • SaaS 无法开箱即用:Stripe、Sentry、Vercel 等云服务无法接受"先安装依赖、配置环境变量"的接入门槛——这类服务的预期接入形态是仅提供一个 URL,配置后即可使用。

  • 无法跨设备共享:同一套能力仅存在于一台机器上,云端 Agent、CI 流水线、移动端 Host 均无法接入。

远程 MCP(Streamable HTTP)正是为解决这些问题而设计的:Server 由提供方统一部署与维护,Client 仅需配置一个 URL;鉴权采用 OAuth 2.1,权限与 token 集中管理;一个端点可同时服务 Cursor、Claude、自研产品等多种 Host。本地模式并未消失,而是适用边界更加明确——本机能力继续使用 stdio,共享能力和第三方服务使用远程模式。

Image

 3.3 传输机制

stdio:Host 启动一个子进程,stdin 发送请求、stdout 接收响应。每条消息是独占一行的完整 JSON-RPC 对象,以换行符分隔。

Image

这意味着 console.log 会破坏协议——stdout 中混入非 JSON-RPC 文本会导致 Client 解析失败,连接立即中断。所有日志输出必须使用 console.error(stderr)。

stdio 模式下,进程存活期间复用同一个 Server 实例,工厂函数仅在启动时执行一次。适用于存在初始化开销的场景:建立数据库连接池、加载搜索索引等。

Streamable HTTP:Client 对 Server 的 URL(如 https://mcp.vercel.com)发送 POST 请求。响应有两种格式,取决于 Accept 请求头:

  • JSON:标准请求-响应模式,Content-Type: application/json,适用于快速操作

  • SSE 格式响应流:Content-Type: text/event-stream,服务端可推送多条消息——进度通知、中间结果——最后一条为完整响应

Image

默认每个 HTTP 请求相互独立、无会话状态——工厂函数在每次请求时执行,请求结束后即释放,任意实例均可处理任意请求。仅当 Client 需要接收服务器主动推送的通知时,才协商可选会话。跨请求的业务状态(如工作流 ID)需由 Client 在每次请求中显式传递。

 3.4 为何弃用 SSE 长连接

早期远程传输采用 HTTP + SSE 双通道设计(2025-03 引入,2025-11 废弃,生命周期仅八个月)——先通过 GET 建立 SSE 长连接,后续请求 POST 至另一端点,两条通道靠 Mcp-Session-Id 关联。该架构的根本缺陷是双通道与强制有状态:

  • 双通道拼接:旧设计将通信拆分为两条独立的 HTTP 通道——Client → Server 的请求通过 HTTP POST 发送,Server → Client 的消息通过由 Client 发起的 GET SSE 长连接返回。两条通道依赖 session ID 手工关联,任一连接中断都会破坏完整的通信链路。

  • 强有状态:服务器须在内存中维护"session ↔ SSE 连接"的映射。负载均衡需配置会话粘滞以保证两条通道路由至同一实例;服务器重启或扩容即丢失全部会话,无法水平扩展,亦不适配不支持长连接的 Serverless 平台。

  • 恢复困难:SSE 长连接中断期间的推送无法补发,Client 只能重建会话,存在消息丢失窗口。

  • 基础设施不友好:长连接占用连接资源,且 GET + SSE 流难以被企业代理、CDN 等标准 HTTP 基础设施统一处理。

Streamable HTTP 正是为规避上述缺陷而设计:所有消息 POST 至同一端点,SSE 从独立传输通道降格为请求作用域的响应格式,无状态成为默认、会话成为可选。两者对比:

Image

 3.5 Vercel MCP 案例

Vercel MCP 将上述远程模式落地为一个具体的产品实现。所有 Host 仅需配置同一个 URL 即可接入,无需各自重复实现 Vercel 集成——这正是第 1 章 M+N 方案的典型实践。

{  "mcpServers": {    "vercel": { "url": "https://mcp.vercel.com" }  }}

鉴权:OAuth 2.1 握手

首次连接时,Server 返回 401 并在 WWW-Authenticate 响应头中携带 OAuth 元数据。Host 自动引导用户完成授权流程,获取 token 后所有后续请求携带 Bearer 凭证。凭证由 Vercel 集中签发、轮换与吊销,不再分散存储于各开发者本机的 .env 文件中。

Image

权限裁剪:同一端点,差异化能力

同一个 URL 根据 token 的 scope 动态裁剪 tools/list 的返回结果:

Image

实际效果

当用户提出"my-app 最近一次部署为什么失败"时,模型自动编排工具调用链,全程无需打开 Dashboard 或执行 vercel logs:

Image

小结:Vercel MCP 恰好对应远程模式需要解决的四个核心问题:

  1. 统一端点分发 — Cursor、Claude、VS Code 通过同一 URL 接入

  2. OAuth 集中管控凭证 — 集中签发与吊销,取代分散的本机环境变量管理

  3. 按权限暴露能力 — 同一端点根据 scope 动态裁剪工具列表

  4. 破坏性操作隔离 — 写操作独立为单独工具,Host 可在调用前拦截确认

04

总结

MCP 的核心思路可以用一句话概括:在 AI 应用与外部系统之间插入一层标准协议,将 M×N 的集成问题降为 M+N。

围绕这一目标,协议定义了三个层面的机制:

  • 能力暴露:Server 通过 Tools、Resources、Prompts 三种原语向 Host 暴露能力,各原语按控制权归属区分——模型驱动、应用注入、用户选择。Server 还可通过 Sampling 和 Elicitation 反向利用 Host 侧的模型推理与用户交互能力,但控制权始终归属 Host。

  • 安全模型:Host 不信任 Server,Server 不信任 Client。Tool Annotations 是建议而非约束,安全决策由 Host 的策略引擎独立执行。

  • 部署模式:本机能力使用 stdio,共享能力和第三方服务使用 Streamable HTTP。远程模式天然无状态,配合 OAuth 2.1 实现集中鉴权与权限裁剪。

理解这三个层面,就具备了评估"是否该用 MCP"以及"如何设计一个 MCP Server"的基础认知。

 参考资料

MCP 规范(2026-07-28) :https://modelcontextprotocol.io/specification/2026-07-28/basic

TypeScript SDK v2 文档 :https://ts.sdk.modelcontextprotocol.io/v2/index.html

Anthropic 发布公告: https://www.anthropic.com/research/model-context-protocol

a16z 播客:MCP 共创者访谈: https://a16z.com/podcast/mcp-co-creator-on-the-next-wave-of-llm-innovation/

Vercel MCP 文档: https://vercel.com/docs/mcp

-End-
原创作者|陈畅
感谢你读到这里,不如关注一下?👇
扫码领取腾讯云开发者专属服务器代金券!
图片
Image
Image
Image
Image
Image