跳到正文
DEV Community· Jeff·· 3 小時前AI 評分51

OpenAPI 規格變更時,MCP 工具清單應同步更新

When the Spec Changes, the MCP Tool List Should Change With It

AI 導讀

作者的團隊改由閘道器根據 OpenAPI 規格產生 MCP 工具清單,取代手動維護的 tools.json,避免兩份 API 描述逐漸不一致。規格重新上載後,下一次用戶端刷新會反映更新的參數名稱、操作和類型;新操作預設關閉,團隊可逐項選擇是否開放。閘道器亦會顯示破壞性變更的差異,並根據同一份規格重新生成 Cursor、Claude 和 MCP Inspector 的程式碼片段。

正文

The first MCP server we stood up, someone on the team wrote out the tool list by hand. A JSON file with 22 entries, each describing one endpoint we wanted the agent to reach. Names, descriptions, input schemas, output schemas. It felt fine. We read it in code review. We shipped it.

Three weeks later, the billing team renamed a query parameter from customer_id to customerId. They updated the OpenAPI doc, they updated the dashboard, they updated the SDK. They did not update our hand-written MCP tools.json, because nobody on that team knew the file existed.

For another week, the agent kept calling the endpoint with customer_id. The server returned 400 unknown query parameter. The agent retried. It tried the parameter in the body. It tried guessing the camelCase version. It never realized the schema it was given was stale, because the schema looked right — it had been correct three weeks ago. We found the failure in logs.

The second artifact problem

OpenAPI-to-MCP conversion is supposed to eliminate a translation step. Instead, the common setup reintroduces one:

  1. Your service has an OpenAPI doc. That is the contract your server actually implements.
  2. Someone hand-writes an MCP tools/list response that describes a subset of that doc.
  3. The agent calls the tool list it was given, not the spec.

You now have two artifacts that both claim to describe the same API. They will drift. The only question is how loudly.

Drift shows up in three flavors:

Renamed or removed parameters. The server stopped accepting customer_id, the MCP tool still lists it. The agent sends the old name, gets a 400, and improvises.

New endpoints that never make it into the tool list. The team ships POST /invoices/{id}/refund in the spec. The hand-written tools.json was never updated. The agent cannot reach the new capability even though it is one operationId away.

Schemas that lie about types. A field moved from string to number in the spec. The MCP tool still says string. The agent sends a quoted number, the parser coerces it, and you spend an afternoon debugging a validation error that should not exist.

Every one of these is a version of the same bug: the agent is being given a stale description of the system it is allowed to call.

What actually works

We stopped hand-writing the tool list. The gateway now reads the OpenAPI doc, derives the tool surface from it, and serves that. When the spec changes, we re-upload the doc — the tool list on the next client refresh reflects the new parameter names, the new operations, the new types.

The hand-maintained tools.json does not exist anymore. There is one artifact of truth, and it lives in the repo the service team already owns.

A few specifics from that setup:

  • The gateway parses the spec on upload. It lists every operation by operationId, method, path, and tag. Per-operation exposure is a toggle, not a hand-written allowlist — so when a new operation ships, it is off by default and we choose whether to turn it on.
  • Parameter names, required/optional flags, and types come straight from the spec. We do not copy them into a second file.
  • When the spec changes in a breaking way (a parameter removed, a type changed), the gateway shows the diff between the last uploaded revision and this one. We see the drift before the agent does.
  • Client snippets for Cursor, Claude, and MCP Inspector are regenerated from the same parsed doc, so the example in the doc matches the tool list in the client.

The mental model

The OpenAPI spec is not a document you generate once and forget. It is the contract between your service and whatever code calls it — including agents. The MCP tool list should be a view of that contract, not a separate document you maintain.

Every hand-maintained description you ship next to the spec is a place for drift to hide. The agent trusts the description it was given. It cannot tell that the description is three weeks out of date. That gap is not a prompt-engineering problem. It is an artifact-hygiene problem.

If your MCP server has a tools.json that someone on your team edits by hand, ask one question: when was it last reconciled with the spec? If you cannot answer from memory, you already know the answer.

來源:DEV Community · dev.to