How to Turn an OpenAPI Spec into an MCP Server (No Code)
A start-to-finish walkthrough that turns a real OpenAPI spec into a working MCP server your AI agent can call — using the Swagger Petstore, no server code written.
You already have an OpenAPI spec. Maybe your team maintains it by hand, maybe your framework generates it, maybe it's just sitting at /swagger.json because the tooling put it there. Either way, that file is a complete, machine-readable description of your API — every path, every parameter, every response shape. It turns out that's almost exactly what an AI agent needs to call your API through the Model Context Protocol.
So let's use it. In this post I'll take a real, public OpenAPI spec and turn it into a working MCP server with no server code — the kind of server Claude or Cursor can connect to and start calling. I'll use the Swagger Petstore because it's public, it's small, and you can follow along without exposing anything of your own. The steps are identical for your actual API.
If you're fuzzy on what MCP even is, I'd start with the plain-English guide and come back. Everyone else, let's go.
What you need before you start
Three things:
- A base URL. For the Petstore that's
https://petstore3.swagger.io/api/v3. - The spec. The Petstore publishes OpenAPI 3.0 at
https://petstore3.swagger.io/api/v3/openapi.json. - Credentials, if the API needs them. The Petstore's read endpoints don't, which keeps this demo clean. Your real API almost certainly does — hold that thought, we'll get to it.
That's the whole shopping list. Notice what's not on it: no MCP SDK, no server framework, no place to deploy a Node process. That's the point of doing this through API2MCP instead of hand-writing a server.
Step 1: Register the API as a provider
In API2MCP, the thing you register first is a provider — your term for "an upstream REST API I want to expose." You give it a name, a base URL, and point it at the spec.
Paste https://petstore3.swagger.io/api/v3/openapi.json into the spec field and let it import. Behind the scenes the platform fetches the document, validates it, and reads the paths object. When it's done you'll see a list of endpoints it found — getPetById, findPetsByStatus, placeOrder, and the rest — each already mapped to an operation with its HTTP method and parameters.
This is the part that would otherwise be a morning of boilerplate: reading the spec, writing a handler per endpoint, wiring up parameter validation. The spec already encodes all of it, so there's nothing to write.
A note from experience: not every API hands you a clean spec URL. Some bury it, some serve it as YAML, some don't publish one at all. API2MCP also imports from Swagger 2.0, Postman collections, HAR captures, and raw JSON, and if there's genuinely no spec to be found, AI Spec Discovery can reconstruct one. For today, though, the Petstore makes it easy.
Step 2: Wrap the provider as an MCP server
Registering the provider doesn't expose anything yet — it just teaches the platform about your API. The next action is Wrap to MCP. This is the step that produces the actual server.
When you wrap it, two things get created:
- a server URL — the endpoint your AI client will connect to, something like
https://api.api2mcp.io/mcp/<id> - an access token — a bearer token that authorizes clients to use this MCP server
Leave "auto-discover tools" on. That tells the platform to translate each endpoint from the spec into an MCP tool definition automatically, which is what makes the next step interesting.
One thing worth doing here: turn on authentication for the server itself, so a random person who guesses your server URL can't use it. The token you get is shown once — copy it somewhere safe. (If you lose it, you regenerate, and any connected client gets updated. No data is exposed either way.)
Step 3: Look at what the model actually sees
Here's where it clicks. Take the Petstore's getPetById operation. In the OpenAPI spec it looks like this, roughly:
{
"get": {
"operationId": "getPetById",
"summary": "Find pet by ID",
"parameters": [
{
"name": "petId",
"in": "path",
"required": true,
"schema": { "type": "integer", "format": "int64" }
}
]
}
}
After wrapping, the model sees a tool that carries the same information in MCP's shape:
{
"name": "getPetById",
"description": "Find pet by ID",
"inputSchema": {
"type": "object",
"properties": {
"petId": {
"type": "integer",
"description": "ID of pet to return"
}
},
"required": ["petId"]
}
}
The operationId became the tool name. The summary became the description the model reads to decide whether to use it. The path parameter became a typed input the model has to fill. Nothing was invented — it was translated. This is why the quality of your spec matters: a good summary and clear parameter descriptions are what let the model pick the right tool and call it correctly. If your spec's descriptions are thin, that's the highest-leverage thing you can improve before wrapping.
Step 4: Connect an AI client and try it
Add the server to your client. For Claude Desktop, that's a few lines in claude_desktop_config.json:
{
"mcpServers": {
"petstore": {
"url": "https://api.api2mcp.io/mcp/<your-server-id>",
"headers": {
"Authorization": "Bearer <your-access-token>"
}
}
}
}
Restart Claude, and ask it something a Petstore endpoint can answer: "Look up pet number 1 in the store." The model recognizes getPetById fits, calls it with petId: 1, the server proxies the real HTTP request to the Petstore, and the response comes back for the model to summarize.
The full walkthrough for Claude Desktop covers the config file's location on each OS and the gotchas; Cursor is a similar story with its own settings panel.
About those credentials
The Petstore let us skip auth, but your API won't, so let's be honest about the part that actually matters in production: where your API key lives.
It lives on the server. When you register the provider, you give API2MCP the upstream credential — the key or token your API expects. It's encrypted at rest (stored with an ENC: marker so the system knows it's protected) and injected into the outbound request at call time. The AI client authenticates to the MCP server with the access token from Step 2; the MCP server authenticates to your API with the real credential. The two never meet. The model calls a tool and gets a result — it has no idea what your API key is, because it never receives it.
That separation is the whole reason to route through a server instead of handing a model your keys, and it's worth understanding in detail before you wrap anything with real credentials.
That's it
No server written, no process deployed, no glue. You pointed a platform at a spec, wrapped it, pasted two lines into a config, and your API is now something an AI agent can use directly.
The Petstore is a toy, but the shape is exactly the same for the API you actually care about — swap the base URL, add your credential, and the endpoints you already document become tools your customers' AI assistants can call. If you want to try it against your own spec, the free tier gives you enough room to wrap a couple of servers and see how your API reads to a model.