Use your OpenAPI specification to expose your API's endpoints as strongly typed tools.
Basic example for https://petstore3.swagger.io/ 🎉
{
"mcpServers": {
"petstore": {
"command": "openapi-to-mcp",
"args": [
"https://petstore3.swagger.io/api/v3/openapi.json"
]
}
}
}
More complex example, using Github's API:
{
"mcpServers": {
"github": {
"command": "openapi-to-mcp",
"args": [
"https://raw.githubusercontent.com/github/rest-api-description/refs/heads/main/descriptions/api.github.com/api.github.com.yaml",
"--bearer-token",
"github_pat_xxxxxx",
"--tool-naming-strategy",
"verbandpath"
]
}
}
}
This example use the bearer token auth (with a Github Personal Access Token) and force the tool naming strategy to "verb and path", as Github's operation ids are not valid tool names.
As a Nuget tool: openapi-to-mcp
dotnet tool install --global openapi-to-mcp
Or download the executables from the releases
Usage:
openapi-to-mcp <open-api> [options]
Arguments:
<open-api> You OpenAPI specification (URL or file) [required]
Options:
-t, --tool-naming-strategy <extension|extension_or_operationid_or_verbandpath|operationid|verbandpath> How the tool name should be computed [default: extension_or_operationid_or_verbandpath]
-h, --host-override Host override
-b, --bearer-token Bearer token
-o2, --oauth-2-grant-type <client_credentials|password|refresh_token> OAuth2 flow to be used
-o2_tu, --oauth-2-token-url OAuth2 token endpoint URL (override the one defined in your OpenAPI for your chosen OAuth2 flow)
-o2_ci, --oauth-2-client-id OAuth2 client id (for the client_credentials grant_type)
-o2_cs, --oauth-2-client-secret OAuth2 client secret (for the client_credentials grant_type)
-o2_rt, --oauth-2-refresh-token OAuth2 refresh token (for the refresh_token grant_type)
-o2_un, --oauth-2-username OAuth2 username (for the password grant_type)
-o2_pw, --oauth-2-password OAuth2 password (for the password grant_type)
-i, --instructions MCP instruction to be advertised by the server
--verbose Log more info (in sdterr) [default: False]
-?, -h, --help Show help and usage information
--version Show version information
- Currently, OpenAPI 2.0 and 3.0 are supported.
- 3.1 is not (at least not until microsoft/OpenAPI.NET supports it)
- Specifications can be JSON/YAML and local (file) or remote (URL)
- Only local $refs are supported
A set of custom extensions is available to customize how your API should be exposed:
info.x-mcp-instructions
(string): Textual instructions exposed by the MCP server during the initialize handshakeoperation.x-mcp-tool-name
(string): Custom tool nameoperation.x-mcp-tool-description
(string): Custom tool descriptionoperation.x-mcp-tool-enabled
(boolean): Enabled/disabled a specific operation (enabled by default)
Only STDIO transport is currently supported.
Operations ("endpoints") from your OpenAPI specification are translated to MCP tools
- All path/query/JSON body parameters are exposed (using their JSON schema)
- Response is returned as-is
- By default, the tool name is computed using first the
operation.x-mcp-tool-name
extension, then the operation.operationId and then{httpMethod}_{escaped_path}
- The tool naming strategy can be defined via the
--tool-naming-strategy
option. ⚠️ Tools are discarded if their name don't match^[a-zA-Z0-9_-]{1,64}$
- The tool naming strategy can be defined via the
- Tools description are extracted as follows:
operation.x-mcp-tool-description
??operation.description
??path.description
When a tool is called, the MCP server will call the underlying endpoint. To determine which host to call a combination of parameters are used:
- the
--host-override
option - your specification first server's URL if it's an absolute URL
- the host of the remote OpenAPI provided
- otherwise, an error is thrown
For example running openapi-to-mcp https://petstore3.swagger.io/api/v3/openapi.json
:
- https://petstore3.swagger.io/api/v3/openapi.json defines a server, but its URL is relative (/api/v3)
- so the host of the specification's own URL is used: https://petstore3.swagger.io and the relative path of the server is appended to it
A token can be provided as option --bearer-token
. It'll be provided to all calls as the Authorization: Bearer {token}
header.
It'll also be provided when fetching a remote specification.
ClientCredentials, RefreshToken, Password are supported.
If your OpenAPI specification declare securitySchemes for those flows, the corresponding tokenUrl
will be used.
Create a new tag/release 🤷