MCP 经中转站:哪些能通、哪些一定不通,以及怎么在十分钟内测出来

教程 发布于 2026-10-19 47 次阅读 API指南针
MCP 本身不经过模型 API,所以「中转站支不支持 MCP」是个错问题。真正会卡住你的是 tool use 的多轮往返、流式参数分片与并行调用。本文给出十分钟可完成的判据。

先把问题问对

「你们家支持 MCP 吗?」——这是我在选型群里见过最多、也最容易得到错误答案的问题。

原因很简单:MCP(Model Context Protocol)是「客户端 ↔ 工具服务器」之间的协议,它不经过模型 API。

一次带工具的对话,实际发生的是三件事:

  1. 客户端把「有哪些工具可用」写进请求的 tools 字段,发给模型 API;
  2. 模型返回 tool_calls,说明它想调用哪个工具、参数是什么;
  3. 客户端自己去执行这个工具(可能是本地子进程,也可能是远程的 MCP 服务器),把结果作为一条 role: tool 的消息再发回模型。

MCP 规范里的两种传输层 —— stdio 和 Streamable HTTP —— 描述的都是第 3 步中「客户端怎么和工具服务器说话」,模型 API 全程不参与。

所以:中转站无法「支持」或「不支持」MCP,它只能支持或不支持 tool use。 一家站说自己「支持 MCP」,通常只是说「我们的模型能返回格式正确的 tool_calls」。这句话本身没有信息量,因为格式正确是及格线,不是能力。

真正会卡住你的三件事

把「支持 MCP」翻译成可验证的问题,只剩三条:

一、多轮往返

工具调用的本质是多轮:模型发起调用 → 客户端执行 → 结果回传 → 模型继续。很多网关只保证第一轮正确。

典型失效:第二轮请求带着 role: tool 的消息回去,网关的协议转换层不认识这个 role,直接 400 或静默丢弃,模型于是「忘记自己调用过工具」,开始编造结果。

这一类在 Anthropic 与 OpenAI 之间做协议转换的网关上最常见,因为两家的工具消息结构不同:OpenAI 是 assistant.tool_calls 加独立的 role: tool 消息,Anthropic 是 assistant 内容块里的 tool_use 加 user 内容块里的 tool_result。转换器漏掉一个 tool_use_id 的映射,整条链路就断在这里。

二、流式下的参数分片

tool_calls[].function.arguments 是一个 JSON 字符串,而在流式响应里它是分片下发的 —— 你会收到一串 arguments 的片段,需要自己按 index 拼起来再解析。

问题在于:有些网关会「帮你聚合」,把分片拼成一个完整的 arguments 再下发,看起来更友好。但只要聚合逻辑有 bug(比如把多个并行调用的分片混进同一个 index),客户端拿到的就是一个语法非法的 JSON,报错信息往往只是 Expecting ',' delimiter,和网络毫无关系,非常难查。

判据:流式下发起一次工具调用,把收到的每个 chunk 原样打印出来。你要看到的是「多个 delta 片段」或「一个完整字符串」,不能是「拼了一半的字符串」。后者说明聚合器有截断。

三、并行工具调用

用户问「北京和上海今天多少度」,模型应该一次返回两个 tool_calls。这要求网关支持 parallel_tool_calls,并且能在下一轮把两个 tool 结果都正确配对回去。

很多网关只处理 tool_calls[0]。表现是:模型明明要查两个城市,你只收到一个调用;或者两个结果都回传了,模型只认了其中一个。

十分钟测法

不用装任何 MCP 服务器,两个假工具就够了:

tools = [
  {"type": "function", "function": {
    "name": "get_weather",
    "description": "Get current weather for a city",
    "parameters": {"type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"]}}},
  {"type": "function", "function": {
    "name": "get_time",
    "description": "Get current time for a city",
    "parameters": {"type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"]}}}
]

三轮测试,每轮记一个结论:

轮次你发什么看什么不通过说明
1「北京天气怎么样」,带上面 2 个工具tool_calls 里是否有 get_weather,arguments 能否 json.loads模型不发工具,说明工具能力没接上
2把 role: tool 的结果回传模型是否基于结果作答,而不是重发调用400 或重复调用,说明多轮往返断了
3「北京和上海分别多少度」是否一次返回两个 tool_calls只回一个,说明并行调用不支持

三轮全过,MCP 就能正常跑。任何一轮不过,换站比调代码快。

报错对照

看到下面这几条,基本可以确定是网关的问题,不是你的代码:

  • tool_use ids were found without tool_result blocks —— 结果回传时 id 没对上,Anthropic 风格报错,多数是网关改写 id 后没同步;
  • messages.1.content: unexpected tool_use_id —— 同上,OpenAI 风格;
  • Invalid schema for function —— 网关对 parameters 做了二次校验,且只认 JSON Schema 的一个子集。把 $ref、oneOf 去掉再试,能过就是它的问题;
  • 工具调用完全正常,但流式下报 Expecting ',' delimiter —— 参数分片聚合 bug,见上文第二条。

一个容易忽略的边界

如果你的工具是远程 MCP 服务器(Streamable HTTP),那么客户端需要同时连两个地方:模型 API(中转站)和 MCP 服务器(多半是你自己的云主机或第三方服务)。

这意味着:

  • 中转站挂了不影响 MCP 服务器,但整个链路一样不可用;
  • 反过来,MCP 服务器在你的内网、不可公网访问时,只能走 stdio 模式(本地起进程),这时候根本没有网络协议的问题;
  • 客户端所在机器的出网策略会同时影响这两条连接,排查时必须分开测。

先把两条连接分开验证:先确认模型 API 能返回合法 tool_calls,再确认 MCP 服务器能被客户端连上。混在一起测,永远说不清是谁的问题。

小结

  1. MCP 不经过模型 API,所以「中转站支不支持 MCP」是伪问题,真正要问的是 tool use 的三项能力;
  2. 三项能力按重要性排序:多轮往返 > 参数分片 > 并行调用;
  3. 用两个假工具、三轮对话、十分钟即可测完,不需要真的搭一套 MCP;
  4. 报错里出现 tool_use_id、tool_result、Expecting ',' delimiter,先怀疑网关的协议转换层;
  5. 远程 MCP 的两条连接必须分开验证,否则排查方向一定是错的。

这篇文章对你有帮助吗?如果你在实际使用中发现了文中没提到的情况,欢迎 提交纠错或补充,我们会核验后更新到正文里。

相关文章

视频生成接口进中转:三种形态、四个计量陷阱,以及一份验收清单

2026-10-19

中转站选型决策树:从你的场景倒推到站点

2026-10-07

日志与对账:把 token 消耗算到项目维度

2026-10-06

灰度切换供应商:不中断业务地换掉一家 API 站

2026-10-06

自建探针:二十行脚本监控你的 API 供应商

2026-10-06

IP 白名单、子账号、权限分级:中转站的治理能力盘点

2026-10-06

顺着看下去:本站收录的部分中转站

本文没有指向特定模型系列,下面是本站收录站点中综合评分靠前的几家,供你顺着看下去。排序依据是评分与可用率,不构成推荐。

完整清单见 中转站导航,或按 模型系列 浏览。