在 Claude Code、Codex、Cursor 里配过 MCP 的人不少,但问一句「MCP 到底是什么、和 Function Calling 有什么区别」,很多人答不上来。今年 7 月 28 日 MCP 发布了新版规范 2026-07-28,官方博客称这是发布以来改动最大的一版,握手和会话都去掉了,而网上不少入门文章还停留在旧版本。
下面按官方规范(2026-07-28 版)和 Claude Code、Codex 的官方文档,依次讲 MCP 解决什么问题、由哪几部分组成、一次工具调用怎么走,以及新版改了什么。
一、MCP 解决的是什么问题
假设你有 3 个 AI 应用(Claude Code、Cursor、自己写的 Agent),想让它们都能查 GitHub、读数据库、操作 Notion。每个应用都要给每个服务写一遍接入代码:
没有统一协议:每个应用 × 每个服务,各写一套
Claude Code ──┬── GitHub 接入代码
├── 数据库接入代码
└── Notion 接入代码
Cursor ───────┬── GitHub 接入代码(又写一遍)
...
3 个应用 × 3 个服务 = 9 套代码
有 MCP:服务方写一个 MCP Server,应用方实现一次 MCP Client
3 个应用 + 3 个服务 = 6 份实现,而且能互相通用
MCP(Model Context Protocol,模型上下文协议)规定的就是 AI 应用和外部工具、数据之间怎么通信。规范里自己举的类比是 LSP(Language Server Protocol):LSP 让一个语言插件能在 VS Code、Vim、JetBrains 里通用,MCP 想让一个工具服务能在各种 AI 应用里通用。
它最早由 Anthropic 在 2024 年 11 月开源,现在由 Linux 基金会下的 Agentic AI Foundation(AAIF)托管。规范按日期发版,到目前一共有这几版:
| 版本 | 说明 |
|---|---|
| 2024-11-05 | 首个公开版本 |
| 2025-03-26 | 引入 Streamable HTTP 传输 |
| 2025-06-18 | 结构化工具输出、Elicitation 等 |
| 2025-11-25 | 加入实验性的 Tasks 等 |
| 2026-07-28 | 当前最新:无状态核心、扩展框架 |
注:中间几版的主要变化来自第三方整理的版本时间线,细节以各版规范原文为准。
二、架构:Host、Client、Server
规范里定义了三个角色:
| 角色 | 是什么 | 例子 |
|---|---|---|
| Host(宿主) | 发起连接的 LLM 应用,用户直接用的那个程序 | Claude Code、Codex、Cursor、Cherry Studio |
| Client(客户端) | Host 内部的连接器,一个 Client 对接一个 Server | Claude Code 里每配一个 MCP 服务,就有一个对应的 Client |
| Server(服务端) | 对外提供上下文和能力的服务 | GitHub MCP、数据库 MCP、浏览器 MCP |
画出来是这样:
┌──────────── Host(如 Claude Code)────────────┐
│ │
│ LLM ◄──► Host 逻辑(权限确认、上下文拼装) │
│ │ │ │ │
│ Client A Client B Client C │
└────────────────┼──────────┼──────────┼────────┘
│ stdio │ HTTP │ HTTP
本地 Server 远程 Server 远程 Server
(文件系统) (GitHub) (Notion)
要注意,模型本身并不直接连 MCP Server。模型只是在回复里说「我要调用某个工具,参数是什么」,真正去发请求的是 Host 里的 Client。所以要不要让工具执行、执行前弹不弹确认框,都由 Host 决定。规范的安全章节里也写明,Host 在调用任何工具前应该取得用户的明确同意。
三、Server 能提供哪些东西
按 2026-07-28 版规范,Server 可以提供三类能力:
| 能力 | 规范里的定位 | 谁来决定用 | 典型用法 |
|---|---|---|---|
| Tools(工具) | 给模型执行的函数 | 模型自己判断何时调用 | 查 issue、跑 SQL、截网页 |
| Resources(资源) | 给用户或模型用的上下文数据 | 通常由应用或用户选择 | 文件内容、数据库表结构、文档 |
| Prompts(提示模板) | 给用户用的模板化消息和工作流 | 用户主动选择 | 预设的「代码审查」「写周报」流程 |
日常用得最多的是 Tools,Claude Code 里的 mcp__github__create_issue 这类工具就是 MCP Server 暴露的 Tools。
反方向上,Client 也可以给 Server 提供能力。新版规范里核心只留下了 Elicitation:Server 执行到一半,可以请 Host 向用户要补充信息,比如让用户填个用户名。
旧版里还有 Roots(告诉 Server 能访问哪些目录)、Sampling(Server 反过来借用 Host 的模型生成内容)、Logging(协议级日志)。2026-07-28 版把这三个标成了弃用。按官方的弃用政策,弃用的功能至少还能用 12 个月,但新写的实现不该再依赖它们。旧教程里讲 Sampling 的部分,知道它正在退出就行。
四、一次工具调用在协议里怎么走
MCP 底层用的是 JSON-RPC 2.0 消息。以一个天气工具为例,流程分两步:先列出工具,再调用。
第一步:Client 问 Server 有哪些工具。
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
Server 返回工具列表,每个工具有名字、描述和参数的 JSON Schema:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"tools": [
{
"name": "get_weather",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "City name or zip code" }
},
"required": ["location"]
}
}
],
"ttlMs": 300000,
"cacheScope": "public"
}
}
Host 把这些工具定义放进发给模型的上下文里。模型读到 description 和 inputSchema,才知道有这个工具、该怎么填参数。工具描述写得好不好,直接影响模型会不会用、用得对不对。
第二步:模型决定调用,Client 发 tools/call。
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "location": "New York" }
}
}
Server 执行完返回结果,Host 再把结果交给模型继续推理:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "complete",
"content": [
{ "type": "text", "text": "Current weather in New York: 72°F, Partly cloudy" }
],
"isError": false
}
}
为了好读,上面的请求省略了
_meta字段。按新版规范,每个请求都必须在_meta里带上协议版本、客户端信息和客户端能力,下一节会讲。
规范区分了两种错误。「工具不存在」「请求格式不对」这类是协议错误,走 JSON-RPC 的 error;「日期格式不对」「API 调用失败」这类是工具执行错误,放在结果里并设 isError: true。规范建议把后一种交给模型,让它改参数重试。所以写 MCP Server 时,业务错误要写清楚,模型才有机会自己纠正。
五、两种传输方式:stdio 和 Streamable HTTP
消息内容一样,区别在怎么送过去。新版规范定义了两种标准传输:
| 传输 | 怎么工作 | 适合 |
|---|---|---|
| stdio | Host 启动一个本地子进程,通过标准输入输出收发、每行一条 JSON-RPC 消息 | 本地工具:文件系统、本地数据库、浏览器自动化 |
| Streamable HTTP | 每条消息是一次 HTTP POST,回复是一个 JSON 或请求级的 SSE 流 | 远程服务:GitHub、Notion、公司内部服务 |
老的 HTTP+SSE 传输已经正式弃用,官方给了一年左右的过渡期。Claude Code 文档里也把 --transport sse 标成了 deprecated,新接的远程服务直接用 http。
六、2026-07-28 版改了什么
这一版的核心变化是从有状态变成无状态:
| 变化 | 以前 | 现在 |
|---|---|---|
| 握手 | 先 initialize / initialized 交换能力 | 去掉;可选用 server/discover 提前查询 Server 能力 |
| 会话 | HTTP 下用 Mcp-Session-Id 绑定会话 | 去掉;每个请求在 _meta 里自带协议版本、客户端身份和能力 |
| 中途要输入 | Server 主动发请求,需要一直保持连接 | 多轮请求(MRTR):Server 返回 input_required,Client 带着答案重发原请求 |
| HTTP 路由 | 网关要解析 JSON 才知道调的是什么 | 请求头必须带 Mcp-Method 和 Mcp-Name |
| 列表缓存 | 没有约定 | tools/list 等返回 ttlMs 和 cacheScope,顺序固定 |
| 扩展 | 实验功能混在核心里 | 正式的扩展框架,Tasks、MCP Apps 都成了可选扩展 |
官方博客和 AAIF 的文章给的理由差不多:有状态的设计在负载均衡、Kubernetes、多地域部署时很麻烦,同一会话的请求必须落到同一台机器。改成无状态后,Server 前面挂个普通的轮询负载均衡就能横向扩容。
需要状态的场景,比如购物车、打开着的浏览器,规范建议用显式句柄:创建状态的工具返回一个 ID(比如 basket_id),模型在后续调用里把它当普通参数传回去。官方的理由是:藏在传输层的状态模型看不见,显式的句柄模型看得见。
我觉得这个思路是对的。按规范的建议,句柄过期时 Server 返回一个说明情况的工具执行错误,模型就能重新创建;状态藏在连接里时,断线后模型并不知道状态已经丢了。
「列表顺序固定」对用户也有好处:工具列表会进入发给模型的前缀,顺序每次一样,提示词缓存更容易命中。
另外两个扩展:
- Tasks:长时间运行的操作返回一个
taskId,Client 用tasks/get轮询进度,断线了句柄还在。适合跑测试、批量导出这类要几分钟的活。 - MCP Apps:Server 可以返回交互式界面(图表、表单),在对话里以沙箱 iframe 的形式渲染;Host 不支持时退回普通文本输出。
授权方面,新版要求 Client 校验授权服务器返回的 iss(RFC 9207),用来防混淆攻击;动态客户端注册(DCR)被弃用,改推 Client ID Metadata Documents(CIMD)。
对普通用户的影响:基本没有。Claude Code、Codex 里的配置写法不变,升级是 SDK 和 Server 作者的事。官方称 TypeScript、Python、Go、C# 四个一级 SDK 在发布时都已支持新版。如果你自己维护 MCP Server,并且依赖了会话 ID 或 Sampling,就需要按迁移指南改一下。
七、MCP 和 Function Calling、Skills 是什么关系
| Function Calling | MCP | Skills / 自定义指令 | |
|---|---|---|---|
| 是什么 | 模型 API 的能力:模型按 schema 输出「我要调哪个函数」 | 应用和外部服务之间的通信协议 | 给 Agent 的结构化说明和工作流 |
| 工具代码在哪 | 写在你自己的应用里 | 在独立的 Server 进程或远程服务里 | 通常是说明文档加脚本 |
| 能否跨应用复用 | 不能,每个应用自己实现 | 能,配一下就能在多个 Host 里用 | 看平台支持 |
| 解决的问题 | 模型怎么表达调用意图 | 工具怎么被发现、调用、授权 | 模型怎么按套路做事 |
简单说,Function Calling 是模型那一层的能力,MCP 是应用和工具之间那一层的协议,两者不冲突。Host 从 MCP Server 拿到工具列表,转换成模型 API 的工具定义发给模型;模型用 Function Calling 的方式说「调 get_weather」;Host 再通过 MCP 去调 Server。
至于 Skills,社区已经有「Skills over MCP」工作组在研究怎么通过 MCP 分发技能,还处在工作组阶段。
八、实际用起来:在 Claude Code 和 Codex 里配 MCP
Claude Code(命令来自官方文档):
# 远程服务,用 http 传输
claude mcp add --transport http notion https://mcp.notion.com/mcp
# 本地服务,用 stdio;-- 后面是启动 Server 的命令
claude mcp add --env AIRTABLE_API_KEY=YOUR_KEY --transport stdio airtable \
-- npx -y airtable-mcp-server
# 查看、删除
claude mcp list
claude mcp remove notion
配置有三个作用域:local(默认,只对当前项目、只有你自己)、project(写进项目根目录的 .mcp.json,可以提交到 Git 和团队共享)、user(你所有项目都能用)。用 --scope 指定。进入 Claude Code 后,输入 /mcp 可以看连接状态、做 OAuth 登录。
团队共享时,.mcp.json 里别写死密钥,用环境变量展开:
{
"mcpServers": {
"api-server": {
"type": "http",
"url": "${API_BASE_URL:-https://api.example.com}/mcp",
"headers": {
"Authorization": "Bearer ${API_KEY}"
}
}
}
}
Codex CLI 写在 ~/.codex/config.toml:
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
[mcp_servers.figma]
url = "https://mcp.figma.com/mcp"
bearer_token_env_var = "FIGMA_OAUTH_TOKEN"
也可以用命令添加:codex mcp add context7 -- npx -y @upstash/context7-mcp。
自己写一个最小 Server(Python SDK 官方 README 的示例,本文未实测):
pip install "mcp[cli]"
from mcp.server import MCPServer
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
# 用官方 Inspector 调试
uv run mcp dev server.py
# 以 Streamable HTTP 方式运行
uv run mcp run server.py --transport streamable-http
函数的 docstring 会变成工具描述,类型注解会变成 inputSchema。注意新版 Python SDK(v2)的入口是 MCPServer,很多老教程里写的 FastMCP 写法以官方迁移指南为准。
九、用 MCP 要注意的安全问题
规范写得很直白:工具代表任意代码执行,要谨慎对待。几条习惯:
- 只装可信来源的 Server。
npx -y 某个包等于在你机器上运行别人的代码。 - 工具描述也可能是攻击面。规范要求 Client 把工具的 annotations 当作不可信信息,除非来自可信 Server。恶意的工具描述或返回内容可以夹带提示词注入。
- 项目级
.mcp.json要看一眼再批准。Claude Code 对项目作用域的 Server 会在交互会话里先请求批准,clone 别人的仓库后别无脑点同意。 - 密钥走环境变量,不要写进提交到 Git 的配置文件。
- 按需开启工具。Codex 支持
enabled_tools/disabled_tools和逐个工具的审批模式,用不到的写操作工具可以直接关掉。
十、常见问题
| 问题 | 原因和处理 |
|---|---|
| 配了 MCP 但 Claude Code 里看不到工具 | 先 /mcp 看连接状态;stdio 服务多半是启动命令写错或依赖没装 |
JSON 里写了 url 还是连不上 | Claude Code 把没有 type 的条目当 stdio 处理,远程服务要写 "type": "http" |
| 工具返回内容被截断 | Claude Code 默认 MCP 输出上限 25000 token,可设 MAX_MCP_OUTPUT_TOKENS 调大 |
| Server 启动超时 | Claude Code 用 MCP_TIMEOUT 调启动超时;Codex 用 startup_timeout_sec(默认 10 秒) |
| 装了很多 MCP 后上下文变大 | 工具定义要占上下文;Claude Code 默认开启工具搜索,按需加载工具,但用自定义 ANTHROPIC_BASE_URL 时不会启用 |
| 旧教程里的 SSE 地址还能用吗 | 暂时还能,但 HTTP+SSE 已弃用,新接入优先 http |
总结
MCP 是一个让 AI 应用和外部工具互通的协议:Server 提供工具、资源和提示模板,Host 里的 Client 负责连接和调用,模型只负责决定调什么。2026-07-28 这一版把它从「本地进程间通信」推向了「能在普通 HTTP 基础设施上横向扩展的分布式协议」,代价是 Server 作者要做一次迁移。只做配置的人写法不变,记住两点:远程服务用 http,别装来路不明的 Server。
参考资料
- MCP 规范(2026-07-28):modelcontextprotocol.io/specificati…
- MCP 规范 · Tools:modelcontextprotocol.io/specificati…
- MCP 规范 · Transports:modelcontextprotocol.io/specificati…
- MCP 官方博客《The 2026-07-28 Specification》:blog.modelcontextprotocol.io/posts/2026-…
- AAIF《MCP 2026-07-28: What's changing and how to migrate》:aaif.io/blog/mcp-20…
- Google Developers Blog《Scaling AI Agent Infrastructure with the MCP Stateless updates》:developers.googleblog.com/scaling-ai-…
- MCP 版本时间线(第三方整理):hidekazu-konishi.com/entry/mcp_s…
- Claude Code 文档 · MCP:code.claude.com/docs/en/mcp
- Codex 文档 · MCP:learn.chatgpt.com/docs/extend…
- MCP Python SDK:github.com/modelcontex…