Google 把 REST 收进 API Gateway 的 MCP 之后,发现面为什么还是 JSON?从 OpenAPI 3.x 到 tools/list

截至 2026 年 9 月 30 日:API Gateway Public Preview(9 月 24 日博文)把 OpenAPI 3.x 操作变成远程 MCP 工具。tools/list 是 JSON Schema,默认不鉴权;tools/call 仍是 JSON-RPC。先核规格再开 mcp: true。

先给结论:Gateway 替你当了 MCP Server,发现合同仍是一份 JSON。2026 年 9 月 24 日,Google 开发者博客宣布:Cloud API Gateway 进入 Public Preview,可以把已部署的 OpenAPI 3.x 操作暴露成远程 MCP 工具,不必再自建、自托管一层 MCP Server。文档侧更早:9 月 11 日的 release notes 已经写上 Enable MCP。网关在 /mcp 收标准 JSON-RPC,把 tools/call 转成原来的 REST,JWT、API Key、配额、日志走同一条策略。Agent 看见的不是「REST 变魔法」,而是 tools/list 吐出来的工具名和 input schema——还是 JSON。

这篇按 2026 年 9 月 30 日写,依据当天仍有效的开发者博文与 API Gateway 文档。本站已有《MCP 是什么》《Skill 上了 MCP,发现文件为什么还是 JSON》《恶意 JSON 与 Tool Calling》。本文只回答:OpenAPI 收进网关之后,哪一层 JSON 要先核,哪一层默认裸奔。

网关当 MCP Server,发了什么

官方说法很短:企业能力大多在 REST 后面,Agent 看不见。以前要给 Agent 调用,团队通常再立一个 MCP Server,把路由、鉴权、配额再实现一遍。API Gateway 是 Google Cloud 网关产品线里偏轻的入口;Cloud Run 上的服务要在几分钟内管起来并暴露给 Agent,走这条。完整生命周期、复杂流量、变现走 Apigee。管 Agent 往外打的调用(含这类 MCP Server)走 Agent Gateway。出站模型路由是另一方向,和 MCP 不能写在同一份 API config。

支持的生命周期方法只有四条:initialize、notifications/initialized、tools/list、tools/call。其它方法(resources/*、prompts/*)回 JSON-RPC -32601。传输是 HTTP POST,没有 stdio。协议头示例写的是 MCP-Protocol-Version: 2025-11-25。规范本身在 2026-07-28 已经改过握手,网关预览钉的是 2025-11-25——连版本号都是 JSON 信封里要先对齐的字段。

这不是再写一个 MCP Server

转码后的 REST 请求和浏览器、SDK 打进来的请求走同一条策略。配额按操作计,MCP 和 REST 共用额度。后端不用为 Agent 再开一套接口。变的是发现面:以前人读 OpenAPI;现在模型读 tools/list 里的 JSON Schema。

层以前Gateway MCP 之后
人读的合同OpenAPI 2.0 / 3.x,常是 YAML必须先升到 OpenAPI 3.0.x 或 3.1.x
Agent 发现自建 MCP 的 tools/list网关从同一份 spec 生成 tools/list
调用REST 或自建 tools/callJSON-RPC tools/call → 原 REST
鉴权 / 配额网关策略 + 可能再写一遍仍是网关策略;发现面默认另算

所以「不用维护 MCP Server」不等于「不用维护 JSON 合同」。OpenAPI 里空描述、过深的对象、2.0 残留,都会在发现面或转码时露出来。原理见《MCP 是什么》。

合同从 OpenAPI 3.x 长出来

文档级打开 MCP:x-google-api-management.mcp。单个操作可用 x-google-mcp-tool 改名、改描述,或设 false 退出。每个要暴露的操作需要后端,以及非空 description。只收 GET / POST / PUT / PATCH / DELETE。工具名须匹配 [A-Za-z0-9_.-]{1,128},全网关唯一。

官方示例的最小形状(YAML 写,语义是 JSON 对象):

x-google-api-management:
  mcp: true
paths:
  /orders/{orderId}:
    get:
      operationId: getOrderStatus
      description: Returns the current status, carrier, and ETA for an order.
      x-google-mcp-tool:
        name: get_order_status
        description: "Look up the delivery status and ETA of a customer order."
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string

描述是模型决定「何时该调」的主信号。官方要求写 when / why,不要只写返回了什么。路径、查询、body、头上的 schema,会映射成工具 arguments。嵌套对象在 tools/list 里可能展不全——这是预览期写明的限制,不是你的校验器坏了。先在本地把 OpenAPI 摊平,再和网关吐出的 input schema 做 Diff。

tools/list 默认不鉴权

默认谁都能 POST /mcp 要一份工具清单:名字、描述、input schema。开发方便,生产等于把参数合同公开。官方建议给 tools/list 上 JWT。Public Preview 里API Key 保不了这个方法。写成对象形式也会全局打开 MCP;不想全暴露的操作,必须 x-google-mcp-tool: false。

x-google-api-management:
  mcp:
    tools-list:
      security:
        orderServiceJwt: []

tools/call 始终执行底层 REST 的鉴权,和发现面是否上锁无关。清单裸奔、调用上锁,是两回事。把工具名和 schema 当机密的团队,上线前先锁 tools/list。这和《恶意 JSON 指南》同一层:模型看见的合同越宽,注入面越大。

tools/call 仍是 JSON-RPC

线上形状官方写成:

{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"get_order_status","arguments":{"orderId":"A-1042"}}}

网关把 arguments 填回 path / query / body / header,过策略,再把后端响应包成 MCP result。调试时先分清两层:外层是 JSON-RPC 信封,内层是业务 JSON。哪一层 parse 失败,先看哪一层。ADK 示例用 Streamable HTTP 指到 …/mcp,请求头仍可带网关已有的凭据。

接入 API hub 后,开了 MCP 的网关会带 MCP 元数据出现,并进 Agent Registry。发现目录变了,字段合同没有变:还是你那份 OpenAPI 长出来的 schema。Skill 发现那条线见《SEP-2640 与 skill://index.json》——索引是另一份 JSON,不要和 tools/list 混成一张表。

Public Preview 先看清的限制

  • OpenAPI 2.0 不支持,先升 3.x。
  • 空响应体(如 HTTP 204)的操作不会暴露成工具。
  • 过深的对象 schema,tools/list 可能截断。
  • 单个网关最多约 1000 个工具。
  • 同一份 API config 不能同时开 MCP 和 model routing。
  • resources / prompts、响应流、Model Armor 检查还在路线图上。

这些不是「以后再补的体验问题」。204 接口从清单里消失,模型会改调别的工具。schema 被截断,strict 校验和真实后端会对不上。本站《MCP 2026 迁移指南》讲的是协议版本;这篇多出来的是:网关替你生成的那份 list,未必等于你仓库里的完整 OpenAPI。

上线前先核的四份 JSON

  1. 仓库里的 OpenAPI 3.x。2.0 先升。每个要暴露的操作有非空 description、后端、合法 tool 名。
  2. 网关返回的 tools/list。对照 input schema 是否被截断、是否多出不想公开的操作。
  3. 一条真实的 tools/call。arguments 是否填得回 REST;外层 jsonrpc 是否 2.0。
  4. 发现面的安全对象。生产不要让 tools/list 继续裸奔。JWT 方案名必须是 components.securitySchemes 里已有的那一个。

用本地 JSON 工具看规格

打开 MCP 开关之前,在浏览器里摊开三份文本:OpenAPI(YAML 先转 JSON)、一次 tools/list 响应、一条准备发给 tools/call 的 arguments。

  • JSON 校验 — 文法是否合法;有 Schema 就一起核必填和多余键。
  • JSON ↔ YAML — 多数 OpenAPI 以 YAML 入库,先转成 JSON 再和 list 对比。
  • JSON Diff — 对比「仓库里的 parameters schema」和「网关吐出的 inputSchema」。

数据不离开浏览器。合同看平了,再改网关开关。Gateway 会替你转码;你的字段名和 required 不应跟着预览期的截断一起松。

常见问题 FAQ

这是 GA 吗?还要不要自建 MCP Server?

截至 2026 年 9 月 30 日是 Public Preview。REST + OpenAPI 3.x、只要生命周期四条方法,可以让网关顶。需要 resources、prompts、流式、stdio,或超 1000 个工具,仍要自建。

tools/list 不鉴权,调用不是还有 API Key 吗?

调用走 REST 策略。清单默认公开工具名和 input schema。API Key 保不了 tools/list。生产用 JWT 锁发现面。

我的规格还是 OpenAPI 2.0 / Swagger,能开吗?

不能。先升到 3.0.x 或 3.1.x,再标 mcp 扩展。

和 9 月的 SEP-2640 Skill 发现是一回事吗?

不是。Skill 发现是 skill://index.json 或 skills/list。Gateway 这条是 REST 操作变成 tools/list。两份 JSON,两套字段。

为什么 tools/list 里的 schema 比 OpenAPI 浅?

预览期写明:过深的对象可能展不全。以网关实际返回为准,用 Diff 对着仓库里的 spec 看缺了哪些 required。

DELETE 返回 204 的接口去哪了?

空响应体的操作不会暴露成工具。模型清单里看不到它,不会按这个名字去 call。

总结

API Gateway 收走的是 MCP Server 进程,不是 JSON 合同。OpenAPI 3.x 长出 tools/list,tools/call 仍是 JSON-RPC,策略仍是原来的 REST。默认不鉴权的清单、被截断的嵌套 schema、204 接口消失,都是上线前的核对项,不是「开了预览就完事」。

先在本地把 OpenAPI、list 响应、call 样本看平,再打开 mcp: true。网关会替你转码;字段合同不应跟着预览限制一起松。