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 National Weather Service API, 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 National Weather Service API (weather.gov) because it's public, it's genuinely useful, 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 weather.gov that's https://api.weather.gov.
  • The spec. The NWS publishes OpenAPI 3.0 at https://api.weather.gov/openapi.json.
  • Credentials, if the API needs them. weather.gov doesn't require a key — it only asks that clients send a polite User-Agent header, and API2MCP sends one on every upstream call. Your real API almost certainly does need credentials — 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://api.weather.gov/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 the list of endpoints it found — alerts_active, alerts_active_zone, glossary, and a few dozen more — each already mapped to an operation with its HTTP method and parameters.

One detail worth pausing on: the weather.gov spec declares security schemes (userAgent and apiKeyAuth) even though the API answers anonymously. Specs do this more often than you'd think, and the importer takes the spec at its word and preselects an authentication type. If the API you're importing actually works without credentials — like this one — set Authentication Type to none on the review screen. If you leave an auth method selected but never supply credentials, tool calls will fail later with an auth error, which is confusing precisely because the API itself never wanted auth in the first place.

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, weather.gov 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 NWS's alerts_active_zone operation. In the OpenAPI spec it looks like this, roughly:

{
  "get": {
    "operationId": "alerts_active_zone",
    "description": "Returns active alerts for the given NWS public zone or county",
    "parameters": [
      {
        "name": "zoneId",
        "in": "path",
        "required": true,
        "description": "NWS public zone/county identifier",
        "schema": { "type": "string" }
      }
    ]
  }
}

After wrapping, the model sees a tool that carries the same information in MCP's shape:

{
  "name": "alerts_active_zone",
  "description": "Returns active alerts for the given NWS public zone or county",
  "inputSchema": {
    "type": "object",
    "properties": {
      "zoneId": {
        "type": "string",
        "description": "NWS public zone/county identifier"
      }
    },
    "required": ["zoneId"]
  }
}

The operationId became the tool name. The description became the text 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": {
    "weather": {
      "url": "https://api.api2mcp.io/mcp/<your-server-id>",
      "headers": {
        "Authorization": "Bearer <your-access-token>"
      }
    }
  }
}

Restart Claude, and ask it something a weather.gov endpoint can answer: "Are there any active weather alerts in Colorado right now?" The model recognizes alerts_active fits, calls it with area: CO, the server proxies the real HTTP request to weather.gov, and live alert data 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

weather.gov 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.

weather.gov is a public playground, 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.