☰
MCP 7-28 到底解决什么?它是工具协议,不是 Agent 大脑——TaoToken 视角下的 Client/Server 拆解
2026/10/2 9:46:21 网站建设 项目流程

1. 先把 MCP 7-28 的定位说清楚:它是工具协议,不是 Agent 大脑

MCP 7-28 到底解决什么?一句话概括:它规范的是 Client 与 Server 之间如何发现、描述和调用外部能力,也就是工具协议这一层。它不负责规划任务、不负责决定什么时候调用工具、不负责判断任务是否完成,更不负责业务授权和幂等。很多刚接触 Agent 开发的朋友容易把 MCP 当成“接上就能自动干活”的万能层,实际上它更像一根标准化的数据线,插上之后能不能跑、跑得对不对,取决于上层的 Agent Runtime 和后面的业务系统。

我先把层次拆开讲,这样后面配置和排障才不会混。最底下是 Tool Calling,模型生成结构化的工具请求;往上一层是 MCP,负责 Client 和 Server 之间的能力发现与调用;再往上是 Agent Runtime,负责执行循环、重试、预算、handoff 和 trace;再往上是 Graph/Workflow,管状态、分支、并行、恢复和人工介入;然后是 Verifier,用规则、测试和证据检查完成度;最上面是业务系统,管权限、幂等、审计、合规和数据一致性。MCP 只占其中一层,把它当成大脑,架构一定会出问题。

2026-07-28 正式版有几个变化值得平台团队关注。协议层移除了握手和隐式 session,让请求可以落到任意 Server 实例;用 Multi Round-Trip Requests 承载中途交互,Server 返回resultType: "input_required",Client 补齐inputResponses后重试原调用;增加Mcp-Method、Mcp-Name、缓存元数据和 W3C Trace Context,方便网关路由、缓存与追踪;建立正式 Extensions 机制,MCP Apps 和重新设计后的 Tasks 作为扩展演进;工具的inputSchema与outputSchema升级为完整 JSON Schema 2020-12;授权继续加固,引入 issuer 校验、凭据绑定,并明确从 DCR 转向 CIMD;建立正式弃用策略,把 Roots、Sampling、Logging 和旧 HTTP+SSE transport 标记为 deprecated;SDK Tier 与一致性测试用来表达不同实现的支持成熟度。

这里要特别提醒一句:OAuth 2.1 和 PKCE 不是 7-28 才出现的。上一版 2025-11-25 授权规范已经基于 OAuth 2.1 的安全要求,并明确要求 MCP Client 实现 PKCE、优先使用 S256。7-28 继续收紧的是互操作和身份边界,比如 Authorization Server 应按 RFC 9207 返回iss,Client 在兑换 authorization code 前必须校验,降低 mix-up attack 风险;Dynamic Client Registration 期间声明 OIDCapplication_type,减少桌面端和 CLI 的 localhost redirect 被错误拒绝;Client credentials 必须绑定到签发它的 authorization server issuer,不能跨授权服务器复用;DCR 已正式 deprecated,规范转向 Client ID Metadata Documents(CIMD)。

还有一个常见误解是无状态。错误理解是“无状态等于不保存任何状态”,正确理解是“协议请求尽量自包含,需要延续的业务状态通过显式句柄、数据库或任务系统管理,而不是依赖某台 Server 的进程内存”。这样更容易做负载均衡、弹性扩缩和网关治理。订单、审批、长任务进度当然仍然有状态,只是不能偷偷绑在某个 Server 实例的内存会话上。

Roots、Sampling、Logging 被标记为 deprecated,也不是说 7 月 28 日立刻删除。官方发布说明明确表示这些能力仍然可用,并至少保留十二个月,新实现不应再依赖它们。旧 HTTP+SSE transport 也进入一年弃用期。对新项目应该按替代方案设计,对旧项目先盘点依赖,再按 SDK 支持情况迁移,不要因为看到 deprecated 就当天删掉所有兼容代码。

Schema 是契约,不是文档装饰。退款工具至少要同时声明输入和输出 schema,服务端必须真的执行校验,而不是只把 schema 展示给模型。正确顺序是:输入 schema 校验、身份和业务授权、幂等业务执行、输出 schema 校验。Schema 能拒绝错误结构,但不能替代授权、审批和幂等。这一点在接入任何 MCP Server 之前都要想清楚。

2. TaoToken 前置:统一 Key 与 API 通道,把模型推理和工具协议分开

在讲可复制配置之前,先说明为什么这里要引入 TaoToken。MCP 负责工具协议层,模型推理层则需要一个稳定的 API 通道。TaoToken 在这里扮演的是统一 Key 和 API 通道的角色,让你在调试 MCP Client/Server 时,模型调用和工具调用各归各层,不会因为 Key 管理混乱而把问题混在一起。

你可以把 TaoToken 理解成一个统一的模型接入入口。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api 。注意 API 地址不加 UTM 参数,配置时直接用这个 base URL 即可。对于 MCP 调试场景,我建议把模型推理的 Key 和 MCP Server 的鉴权分开管理,这样出问题时能快速定位是协议层还是模型层。

具体操作上,先到模型对话页面确认你的 Key 能正常调用模型,再到 API Keys 页面生成或查看 Key。模型对话入口是 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite ,API Keys 入口是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。如果你打算长期做编码类 Agent,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,控制台在 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。

为什么要在 MCP 文章里讲这些?因为很多人在调试 MCP 时,把模型调用失败和工具调用失败混为一谈。模型返回 401,可能是 Key 问题;MCP Server 返回 401,可能是 OAuth 或 issuer 校验问题。两者排查路径完全不同。TaoToken 的统一通道让模型层先稳定下来,你再去调 MCP 层,变量就少了一个。

另外,Claude Code 这类工具接入时,Base URL、Key、Model ID 三件套要写全。Claude Code 的 Anthropic 兼容入口可以参考 https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude_code&utm_campaign=rewrite 。如果你用 CC Switch 或 Cline MCP,同样要把这三件套配齐,不要只填一个 Base URL 就以为能跑。

这里再强调一次边界:TaoToken 提供的是模型 API 通道,不是 MCP Server 本身。MCP Server 的鉴权、工具实现、业务授权仍然由你自己的服务负责。把这两层分开,是理解 MCP 7-28 定位的第一步。

3. 可复制配置:MCP Client/Server 片段与 settings 示例

这一节给可直接复制的配置片段。先给一个 MCP Server 的server.json或等价配置,再给 Client 侧的 settings 片段。注意路径和字段名要和你实际使用的 SDK 版本对齐,7-28 之后inputSchema和outputSchema要用完整 JSON Schema 2020-12。

先看一个退款工具的 Server 端 schema 定义,这段可以直接放进你的工具注册代码里:

{ "name": "create_refund", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "order_id": {"type": "string", "minLength": 1}, "amount": {"type": "number", "exclusiveMinimum": 0}, "idempotency_key": {"type": "string", "minLength": 16} }, "required": ["order_id", "amount", "idempotency_key"], "additionalProperties": false }, "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "refund_id": {"type": "string"}, "status": {"enum": ["created", "duplicate"]} }, "required": ["refund_id", "status"], "additionalProperties": false } }

服务端必须真的执行校验,不能只把 schema 展示给模型。下面这段 Python 示例展示了正确顺序:输入 schema 校验、身份和业务授权、幂等业务执行、输出 schema 校验。

from jsonschema import Draft202012Validator INPUT_SCHEMA = { "type": "object", "properties": { "order_id": {"type": "string", "minLength": 1}, "amount": {"type": "number", "exclusiveMinimum": 0}, "idempotency_key": {"type": "string", "minLength": 16}, }, "required": ["order_id", "amount", "idempotency_key"], "additionalProperties": False, } OUTPUT_SCHEMA = { "type": "object", "properties": { "refund_id": {"type": "string"}, "status": {"enum": ["created", "duplicate"]}, }, "required": ["refund_id", "status"], "additionalProperties": False, } refunds: dict[str, dict] = {} def execute_create_refund(arguments: dict, roles: set[str]) -> dict: Draft202012Validator(INPUT_SCHEMA).validate(arguments) if "refund_operator" not in roles: raise PermissionError("当前身份没有退款权限") if arguments["amount"] > 500: raise PermissionError("超过 500 元的退款必须先完成人工审批") key = arguments["idempotency_key"] old = refunds.get(key) if old: if old["order_id"] != arguments["order_id"] or old["amount"] != arguments["amount"]: raise ValueError("同一幂等键不能对应不同业务参数") result = {"refund_id": old["refund_id"], "status": "duplicate"} else: refund_id = f"refund-{len(refunds) + 1:06d}" refunds[key] = {**arguments, "refund_id": refund_id} result = {"refund_id": refund_id, "status": "created"} Draft202012Validator(OUTPUT_SCHEMA).validate(result) return result

接下来是 Client 侧的 settings 片段。以常见的 MCP Client 配置为例,你需要把 Server 的启动命令、环境变量和模型 API 通道分开写。下面是一个settings.json风格的示例,注意 Base URL 用 TaoToken 的 API 地址,Key 单独放环境变量:

{ "mcpServers": { "refund-server": { "command": "python", "args": ["-m", "refund_server"], "env": { "MCP_SERVER_TOKEN": "${MCP_SERVER_TOKEN}", "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "${TAOTOKEN_API_KEY}", "TAOTOKEN_MODEL_ID": "your-model-id" } } } }

如果你用 TOML 风格配置,等价写法如下:

[mcp_servers.refund-server] command = "python" args = ["-m", "refund_server"] [mcp_servers.refund-server.env] MCP_SERVER_TOKEN = "${MCP_SERVER_TOKEN}" TAOTOKEN_BASE_URL = "https://taotoken.net/api" TAOTOKEN_API_KEY = "${TAOTOKEN_API_KEY}" TAOTOKEN_MODEL_ID = "your-model-id"

注意这里的三件套:Base URL、Key、Model ID。无论你用 CC Switch、Cline MCP 还是 Codex 的auth.json,这三个字段都要写全。Codex 的auth.json里通常需要base_url、api_key和model三个字段,缺一个都可能出现local proxy failed或reading choices报错。

配置完成后,先不要急着跑复杂任务。用一个最小工具调用验证协议层是否通。下面是一个验证请求的示例,Client 发送tools/list再发送tools/call:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }

拿到工具列表后,再发一次调用:

{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "create_refund", "arguments": { "order_id": "order-1001", "amount": 99.5, "idempotency_key": "idem-20260728-0001" } } }

如果 Server 返回resultType: "input_required",说明进入了 Multi Round-Trip Requests,Client 需要补齐inputResponses后重试原调用。这是 7-28 正式版的一个关键交互变化,不要当成错误。

4. 验证请求与成功结果:一次工具调用到底看什么

配置写完之后,怎么确认 MCP 7-28 的协议层真的通了?我建议分三步验证:先验证模型通道,再验证工具发现,最后验证工具调用。每一步都有明确的成功标志,不要跳步。

第一步,验证模型通道。用 TaoToken 的模型对话页面发一条简单消息,确认返回正常。如果这里就 401,先检查 API Key 和 Base URL,不要往下走。模型对话入口在 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite ,你可以直接在那里试。

第二步,验证工具发现。Client 发送tools/list,Server 应返回工具数组,每个工具包含name、description、inputSchema和outputSchema。成功结果类似:

{ "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "create_refund", "description": "创建退款单", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "order_id": {"type": "string", "minLength": 1}, "amount": {"type": "number", "exclusiveMinimum": 0}, "idempotency_key": {"type": "string", "minLength": 16} }, "required": ["order_id", "amount", "idempotency_key"], "additionalProperties": false }, "outputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "refund_id": {"type": "string"}, "status": {"enum": ["created", "duplicate"]} }, "required": ["refund_id", "status"], "additionalProperties": false } } ] } }

如果这里返回的 schema 不是 2020-12 格式,或者缺少outputSchema,说明你的 SDK 版本还没对齐 7-28。官方发布说明称 TypeScript、Python、Go、C# 四个 Tier 1 SDK 已支持新规范,Rust SDK 发布时仍处于 Beta。实际迁移仍要核对安装版本、兼容模式和 changelog。

第三步,验证工具调用。发送tools/call,成功结果应包含refund_id和status:

{ "jsonrpc": "2.0", "id": 2, "result": { "content": [ { "type": "text", "text": "{\"refund_id\": \"refund-000001\", \"status\": \"created\"}" } ] } }

再发一次相同idempotency_key的调用,应返回status: "duplicate",且refund_id不变。这说明幂等生效了。注意,幂等是业务层保证的,不是 MCP 协议层自动给的。MCP 只负责把调用传过去,重试时是否幂等,取决于你的 Server 实现。

如果你在 Client 侧看到resultType: "input_required",说明 Server 需要更多输入。这时 Client 要补齐inputResponses后重试原调用。这个机制是 7-28 的 Multi Round-Trip Requests,用来承载中途交互。不要把它当成失败,它是正常流程的一部分。

验证过程中,建议打开 W3C Trace Context,观察Mcp-Method和Mcp-Name头是否正确传递。这对网关路由和缓存很有用。如果你在网关层看到请求没有落到预期实例,先检查这两个头。

最后,把验证结果记录下来:模型通道是否通、工具发现是否返回 2020-12 schema、工具调用是否返回预期结构、幂等是否生效。这四项都过了,才说明协议层接入完成。至于 Agent 怎么规划、怎么重试、怎么审批,那是 Runtime 和业务层的事,不在 MCP 职责范围内。

5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth

这一节对照真实报错,把排查路径写清楚。很多问题看起来像 MCP 的问题,实际上是模型通道或配置三件套的问题。

第一个常见报错是 401。分两种情况:模型通道 401 和 MCP Server 401。模型通道 401 通常是 API Key 错误或 Base URL 写错。检查TAOTOKEN_BASE_URL是否为https://taotoken.net/api,Key 是否从 API Keys 页面正确复制。MCP Server 401 则可能是 OAuth 或 issuer 校验问题。7-28 要求 Authorization Server 按 RFC 9207 返回iss,Client 在兑换 authorization code 前必须校验。如果iss缺失或不匹配,就会 401。另外,Client credentials 必须绑定到签发它的 authorization server issuer,不能跨授权服务器复用。

第二个报错是local proxy failed。这个通常出现在 Codex 或类似工具的auth.json配置里。检查三件套:base_url、api_key、model是否都写了。只写base_url不写model,或者 Key 用了环境变量但没导出,都会导致本地代理启动失败。如果你用 CC Switch,同样检查这三项。Cline MCP 的配置里也要确认 Base URL、Key、Model ID 齐全。

第三个报错是reading choices。这个多半是模型返回结构不符合预期,或者 Client 在解析响应时字段对不上。先确认模型通道本身能正常返回,再检查 MCP Client 的版本是否支持 7-28 的响应格式。如果 SDK 还是旧版,可能不认识新的resultType字段。升级 SDK 后仍报错,检查inputSchema和outputSchema是否为 2020-12 格式。

第四个是 OAuth 相关报错。7-28 之后,DCR 已正式 deprecated,规范转向 CIMD。如果你的 Client 还在用 DCR,可能遇到兼容问题。DCR 暂时保留兼容,但会在未来版本移除。新项目应按 CIMD 设计。另外,Dynamic Client Registration 期间声明 OIDCapplication_type,可以减少桌面端和 CLI 的 localhost redirect 被错误拒绝。如果你在本地调试时 redirect 被拒,先检查这个字段。

还有一个容易忽略的点:Roots、Sampling、Logging 被标记为 deprecated。如果你的 Server 还在依赖 Sampling 让 Client 代为调用模型,新设计更适合由应用 Runtime 直接集成模型供应商 API。Logging 在 stdio 传输下可以写 stderr,跨服务观测交给 OpenTelemetry。Roots 的边界表达可以改用工具参数、resource URI 或 Server 配置。这些能力至少保留十二个月,但新实现不应再依赖。

排查顺序建议:先确认模型通道通,再确认 MCP Client 和 Server 版本对齐 7-28,然后检查三件套配置,最后看 OAuth 和 issuer 校验。每一步都用最小请求验证,不要一上来就跑复杂 Agent 任务。把变量控制住,问题定位会快很多。

如果你在排障过程中需要重新生成 Key 或查看接入文档,API Keys 入口是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。控制台可以看调用情况:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。

6. 语义一致 CTA:把协议层和决策层分开,再决定要不要上 MCP

回到标题的问题:MCP 7-28 到底解决什么?它解决的是 Client 与 Server 之间能力发现和调用的统一协议问题。它不解决 Agent 怎么规划、怎么重试、怎么审批、怎么保证业务幂等。把这两层分开,你才能在架构上做对决策。

什么时候不需要 MCP?只有一个应用进程内的两三个函数,不会被其他 Client 复用,直接注册本地 tool 更简单;极低延迟热路径,先测量协议、序列化和网关开销;团队没有能力运营远程 Server 的鉴权、升级、监控和故障恢复,先把普通 API 做稳;工具契约和权限边界尚未理清,不要用 MCP 包装一个本来就不安全的接口。判断标准是跨 Client 复用、统一发现和平台治理能否抵消新的运维故障面。

接入一个 MCP Server 前,问自己几个问题:Server 能访问哪些文件、数据库和外部网络?调用时代表哪个用户或服务身份?读操作和写操作是否分开授权?高风险工具是否经过人工审批?输入输出 schema 是否真正校验?是否记录调用者、目标资源和业务结果?重试时如何保证幂等?Server 被入侵后,最坏影响范围是什么?“支持 MCP”只说明协议兼容,不说明这些问题已经解决。

如果你要长期做编码类 Agent,或者需要稳定的模型 API 通道来支撑 MCP 调试,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite 。模型对话验证在 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite 。Claude Code 接入参考 https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude_code&utm_campaign=rewrite 。

关键结论:MCP 负责把工具接进来,Agent Runtime 决定怎么用,业务系统保证用得安全。把这三层分清楚,你的 Agent 架构才不会把协议层当成大脑,也不会把业务安全寄托在协议兼容上。

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

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

立即咨询