Turn an Existing REST API into an MCP Server Without Writing a Single Wrapper A developer outlined a method for turning an existing OpenAPI-described REST API into an MCP server through generation rather than hand-written wrappers, so each API operation becomes a discoverable agent tool that calls the existing service instead of reimplementing its logic. The approach keeps the HTTP API as the system of record, letting OpenAPI changes regenerate both human-facing docs and agent-facing tools from one contract. The writeup recommends exposing read operations first and gating writes behind explicit user confirmation, least-privilege scopes and audit logging, noting that a discoverable tool does not mean the caller is authorized to execute it. You already have working endpoints: order lookup, inventory, shipment tracking. Now the business wants an AI assistant — "give it an order number and it summarizes the order and where it is in transit." The API is done. The to-do list, somehow, is not: One interface, two sources of truth, guaranteed to drift. If your API is already described in OpenAPI, every one of those definitions already exists. You should not be re-declaring it for agents. Here is the wrapper people end up writing by hand for a single endpoint: // hand-maintained, and now it must track the OpenAPI doc forever server.tool "get order", { orderId: z.string }, async { orderId } = { const res = await fetch ${BASE}/orders/${encodeURIComponent orderId } , { headers: { Authorization: Bearer ${token} }, } ; return res.json ; } ; Multiply that by forty endpoints, add the inventory and logistics services, and then keep the parameter names, nullable fields, enums and error codes in sync with the HTTP API by hand. The moment the backend renames warehouseId or adds a status, the agent tool lies. This is pure transcription. The operation ID, the path parameters, the request and response schemas, the auth scheme — OpenAPI already carries all of it. OpenAPI-to-MCP generation turns each operation into a discoverable tool and reuses the contract you already maintain: security requirements carry over. Conceptually, GET /orders/{orderId} becomes a tool the agent can discover: { "name": "getOrder", "description": "Fetch one order by id, including status and line items.", "inputSchema": { "type": "object", "properties": { "orderId": { "type": "string" } }, "required": "orderId" } } The generated server calls your existing service . It doesn't reimplement order logic, hold a copy of the data, or stand up a new backend. Your API stays the system of record; MCP is just another entry point to it. Change a field in OpenAPI, regenerate, and the human-facing docs and the agent-facing tools move together because they are built from the same file. Resist the urge to expose everything on day one. For the customer-support assistant, open the read operations first — order lookup and shipment tracking — and let the agent answer real questions: "Has this order shipped?" → call getOrder , then getShipment , answer from the actual responses. This sequencing is practical, not cautious theater. It lets you verify the things that actually break first: Writes — cancel order, issue refund, adjust inventory — are a different risk class. Gate them behind explicit user confirmation, least-privilege scopes, and audit logging, and expose them only after the read path is proven. This is the single most important security note in this whole setup: a tool being discoverable does not mean the caller is allowed to execute it. MCP A useful mental model: the OpenAPI-to-MCP layer is a typed, discoverable proxy in front of endpoints that keep enforcing every rule they enforce today. The same generated server fits two deployment shapes: | Need | Shape | When you use it | |---|---|---| | Local agent / dev machine | stdio or local HTTP MCP server | You're wiring an agent to services on your own machine | | Remote agents and partners | Hosted MCP endpoint over HTTP | External agents or teammates need stable access without your laptop | | Humans, in parallel | Published API docs from the same spec | A developer wants to read, not call through an agent | Hosting can also carry the documentation, so a partner gets a readable spec and a callable MCP endpoint from one published version. Publish a versioned snapshot rather than your working draft: internal, half-built operations Teams hit confusion here because "MCP for APIs" shows up in two distinct moments, and they answer different questions: | | Development-time MCP | Runtime MCP this article | |---|---|---| | Who calls it | Your AI coding assistant | An end-user-facing AI agent | | What it does | Reads the contract, mocks and tests while you build | Calls the running API to get work done | | Answers | "How should this endpoint be implemented and checked?" | "Call this endpoint and return the result" | | Feeds on | The evolving local spec | A published, authenticated service | You can use both against the same OpenAPI file; they just sit on opposite sides of "the API exists." You don't need an agent framework rewrite to start: The consumers of an API used to be front ends, mobile apps and other services. Agents are now on that list — and they need the same contract, not a parallel, hand-written shadow of it. You can generate an MCP server from an OpenAPI spec and run it locally or host it alongside your docs in the free web app at powerduck.com/app https://www.powerduck.com/app . If you've already hand-rolled agent wrappers around a REST API: how did you keep the tool schemas from drifting from the real endpoints? I'd love to hear the approach and the war stories in the comments.