OpenAPI to MCP: Turn Any REST API into an MCP Server
If your API has an OpenAPI or Swagger document, you are one link away from an MCP server. Here is how the conversion works, what to import, how authentication is handled and the mistakes that make AI clients pick the wrong tool.
Most companies that want an MCP server already have the hard part: a REST API that does the real work. And most of those APIs come with an OpenAPI (formerly Swagger) document that describes every endpoint, parameter and authentication scheme in a machine-readable way.
That document contains almost everything an MCP server needs. Converting it is mostly a matter of choosing what to expose and how. This guide explains how OpenAPI maps to MCP, walks through a real import and covers the decisions that decide whether an AI client will actually use your tools well.
How OpenAPI Maps to MCP
An MCP tool has a name, a description, typed parameters and logic. An OpenAPI operation has all of the same pieces under different names:
| MCP tool | Comes from in OpenAPI |
|---|---|
| Name | operationId in snake_case, for example getPetById becomes get_pet_by_id |
| Description | The operation summary, then description |
| Parameters | Path, query and header parameters, plus the top-level fields of a JSON body |
| Required flags | The required flags in the document; path parameters are always required |
| Logic | An HTTP request to the endpoint, with authentication added |
The result is one MCP tool per endpoint. When an AI calls get_pet_by_id with petId: 7, the tool sends GET /pets/7 to your API and returns the JSON response.
Converting an API, Step by Step
On MCPCore the importer is part of tool creation: Create New Tool, then Import from OpenAPI.
1. Load the document
Paste the URL of an OpenAPI 3.x or Swagger 2.0 document in JSON or YAML, or upload the file if it is not public. Documents up to 2 MB are supported. References inside the document, such as #/components/schemas/Pet, are resolved automatically. If your spec is split across several files, bundle it first, for example with npx @redocly/cli bundle.
2. Check the base URL and authentication
The importer takes the base URL from the first servers entry (or host and basePath in Swagger 2.0). Check it, because many documents still point at a staging server.
Then it reads the security scheme and asks for your key once:
| Scheme in the document | What the tools do |
|---|---|
| HTTP bearer | Send Authorization: Bearer with your secret |
| API key in a header | Send that header, such as X-API-Key |
| API key in the query string | Add the parameter, such as api_key |
| OAuth 2.0, OpenID Connect, HTTP Basic | Not imported; add the header to each request manually |
The key is stored once as an encrypted secret and shared by every tool. The header or query parameter that carries it is never exposed as a tool parameter, so the AI never sees or sends your key.
3. Pick the endpoints
This is the most important step, and the one most often rushed. Read-only GET endpoints are selected by default. Endpoints that write data (POST, PUT, PATCH) are labelled Writes data and DELETE endpoints Destructive; both stay off until you add them on purpose.
For endpoints with a documented JSON response, you can also pick which response fields the tool returns. Keeping only id, name and status instead of a 40-field object makes answers faster, cheaper and less likely to leak data the AI does not need.
4. Create
Each selected endpoint becomes a workflow tool: an HTTP Request step with the URL, method, auth and body already filled in, an optional Transform for the fields you picked, and a Return. Every tool starts with a version labelled Imported from OpenAPI, and each one gets a behavior hint (read-only, changes data or destructive) that AI clients use to decide when to ask for confirmation.
A Worked Example
Take a small pet store document with three operations: listPets (GET /pets with optional status and limit), getPetById (GET /pets/{petId}) and deletePet (DELETE /pets/{petId}), protected by an X-API-Key header.
After the import you have:
| Tool | Parameters | Request |
|---|---|---|
list_pets | status (optional), limit (optional) | GET /pets with query parameters and the X-API-Key header |
get_pet_by_id | petId (number, required) | GET /pets/{{params.petId}} |
delete_pet was left out deliberately. Now ask Claude "Which pets are available?" It calls list_pets with status: "available", and the tool requests /pets?status=available. The empty limit is left out of the URL instead of being sent as limit=.
Five Mistakes That Make AI Clients Pick the Wrong Tool
An imported server is only as good as the tools a model can tell apart. These are the problems we see most often.
1. Importing everything. A 120-endpoint API does not need 120 tools. The longer the tool list, the harder it is for a model to pick the right one, which is why the importer warns you once you select more than 15. Import the endpoints that answer real questions, and leave admin and bulk endpoints out.
2. Empty summaries. If an operation has no summary or description, the tool's description is just GET /v2/acct/{id}. Fix the spec, or edit the description after import, so it says when to use the tool: "Returns the billing account for a customer id. Use it for questions about invoices or plans."
3. Cryptic operation ids. get_v2_acct_by_id is hard for a model to choose. Rename tools to what they do, such as get_billing_account.
4. Exposing writes too early. Start read-only. Add write and delete endpoints once you have seen in the logs how the model uses the read tools.
5. Returning huge responses. Large payloads cost tokens and bury the answer. Use the response field picker, or add a Transform step later.
Testing the Result
Before you share the server, try it with a real model. MCPCore's Playground lets you chat with Claude or an OpenAI model using your own key and shows each tool call with its parameters and result. If the model calls list_pets when it should call get_pet_by_id, improve the descriptions rather than the logic.
Every call made by any client also shows up in the traffic logs and in analytics broken down by AI client, which tells you which tools are used, by whom and how often they fail.
Keeping Tools in Sync With Your API
APIs change. When you import the same document again, endpoints that match an existing tool are labelled Updates existing tool. Importing them saves a new version of that tool, and the previous version stays in its history, so you can compare the two or restore the old one. The importer never deletes tools, so remove tools for retired endpoints yourself.
OpenAPI to MCP vs Writing a Server by Hand
| OpenAPI import | Hand-written server | |
|---|---|---|
| Time to first tool | Minutes | Hours to days |
| Code to maintain | None | A server, a deploy pipeline and dependencies |
| Custom logic | Add steps in the workflow builder | Unlimited |
| Hosting, auth, logs | Included | Build or buy each one |
Import is the right default for exposing an existing API. Write code only for the tools that need logic the steps cannot express. Both kinds of tool can live on the same MCP server.
FAQ
Can I convert a Swagger 2.0 document, or only OpenAPI 3?
Both. OpenAPI 3.x and Swagger 2.0 documents in JSON or YAML are supported.
Does my API key end up in the AI's context?
No. The key is stored as an encrypted secret and added to requests by the server. It is never a tool parameter, so the model never sees it.
What about endpoints with file uploads or form data?
Request bodies that are not JSON are flagged during import and need to be edited by hand after the tool is created.
Can I import an API that uses OAuth?
The tools are created, but OAuth, OpenID Connect and HTTP Basic credentials are not filled in automatically. Add the required header to each HTTP Request step.
How many endpoints should I import?
As few as answer real questions. A short list of well-described tools beats a long list of vague ones.
Ready to convert your API? Create a free MCPCore account, or read the OpenAPI import reference in the docs.