MCP 是什么?按 2026-07-28 新版规范讲清架构、调用流程和配置

36 阅读13分钟

在 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 对接一个 ServerClaude 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

消息内容一样,区别在怎么送过去。新版规范定义了两种标准传输:

传输怎么工作适合
stdioHost 启动一个本地子进程,通过标准输入输出收发、每行一条 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 CallingMCPSkills / 自定义指令
是什么模型 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 要注意的安全问题

规范写得很直白:工具代表任意代码执行,要谨慎对待。几条习惯:

  1. 只装可信来源的 Server。npx -y 某个包 等于在你机器上运行别人的代码。
  2. 工具描述也可能是攻击面。规范要求 Client 把工具的 annotations 当作不可信信息,除非来自可信 Server。恶意的工具描述或返回内容可以夹带提示词注入。
  3. 项目级 .mcp.json 要看一眼再批准。Claude Code 对项目作用域的 Server 会在交互会话里先请求批准,clone 别人的仓库后别无脑点同意。
  4. 密钥走环境变量,不要写进提交到 Git 的配置文件。
  5. 按需开启工具。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。

参考资料