Expose a REST API as MCP Tools
An MCP server registry entry can be backed by a plain REST API instead of an upstream MCP server. Register the API's OpenAPI 3.x document with type set to openapi, and AISIX generates one MCP tool per operation. A tools/call executes as an HTTP request against the API's base URL, with the gateway-held credential attached — the MCP caller never receives it, and the API needs no MCP server of its own.
This turns existing internal services — an ERP, an inventory system, a payroll API — into agent-callable tools with the same governance as every other MCP tool: server review, tool access control, access policies, traffic controls, guardrails, and observability all apply unchanged.
How Tools Are Generated
AISIX walks the document's paths and generates one tool per operation for the get, post, put, delete, and patch methods:
- Tool name: the operation's
operationId, lowercased, with any character outsidea-z,0-9,_, and-replaced by_, capped at 128 characters. An operation without anoperationIdis named<method>_<path>under the same rules. Tools are exposed to callers as<server-name>__<tool-name>, like every MCP tool. - Input schema: each
pathandqueryparameter becomes a property (with its type, description,enumvalues, andrequiredflag). A JSON request body becomes a singlebodyobject property, marked required when the spec says so. Local$refs — including referenced component schemas inside the body — are resolved so the agent sees the real shape. Header and cookie parameters are not exposed: upstream headers belong to the gateway, not the caller. - Skipped operations: an operation whose request body has no
application/jsonvariant (for example amultipart/form-datafile upload) is skipped rather than generating a tool that cannot succeed.
Registration validates the document and fails with the reason: a document that cannot be parsed, a Swagger 2.0 document (convert it to OpenAPI 3.x), a document with no tool-generatable operations, or operationIds that collide after tool-name normalization (for example foo/list and foo.list both map to foo_list) are all rejected. The generated tool names are returned in the server's tool_names field, so you can verify the surface before granting access.
Register a REST API
Provide the document in one of two ways:
spec_content— the document itself, as JSON or YAML text. Use this when the control plane cannot reach the API's network.spec_url— a URL the control plane fetches once, at registration time. The fetched document is validated, normalized, and stored; the data plane never re-fetches it, so the tool set only changes when you update the registry entry. URLs that resolve to non-public addresses are refused on AISIX Cloud; On-Premises deployments can allow them by settingAISIX_CLOUD_MCP_SPEC_ALLOW_PRIVATE_URLS=trueon the control plane, or simply paste the document instead.
Documents are capped at 1 MiB.
url is the REST API's base URL — generated tool calls are issued against <url><path>.
curl -sS -X POST "$AISIX_CLOUD_URL/api/mcp_servers" \
-H "Authorization: Bearer $AISIX_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "erp",
"type": "openapi",
"url": "https://erp.internal/api/v1",
"spec_url": "https://erp.internal/api/v1/openapi.json",
"auth_type": "bearer",
"secret": "erp-service-token",
"allowed_environments": ["'$AISIX_ENV_ID'"]
}'
The response includes the generated tool_names:
{
"mcp_server": {
"name": "erp",
"type": "openapi",
"url": "https://erp.internal/api/v1",
"tool_names": ["getitem", "createorder"],
"approval_status": "approved"
}
}
A caller whose API key allows them can now discover and call erp__getitem and erp__createorder through /mcp, exactly like tools from a real upstream MCP server.
In the dashboard, choose REST API (OpenAPI) when registering an MCP server, then supply the document in whichever way suits you: paste it, give its URL, or pick a local .json / .yaml file with Choose file…. A picked file is read into the editor, so you can review and adjust it before saving.
Review the Generated Tools
Each registered server's card lists the first few generated tool names and links to a tools page for that server, which lists every tool with:
- its
<server>__<tool>name — the form to copy into an API key's tool allowlist or an access policy pattern; - the HTTP operation it calls, such as
GET /items/{id}; - its description.
The same listing is available from the API:
curl -sS "$AISIX_CLOUD_URL/api/mcp_servers/$MCP_SERVER_ID/tools" \
-H "Authorization: Bearer $AISIX_ADMIN_TOKEN"
{
"data": [
{
"name": "getitem",
"namespaced_name": "erp__getitem",
"method": "GET",
"path": "/items/{id}",
"description": "Fetch one item"
}
]
}
The listing is derived from the stored document, so it always matches the tools the gateway serves. It applies to type: openapi servers only — an upstream MCP server's tools live on the upstream, and the endpoint returns 400 for one.
Authenticate to the REST API
The upstream authentication modes apply as-is; the credential is attached to every generated tool call:
bearer—Authorization: Bearer <secret>.api_key— the key fromsecret, sent as thex-api-keyheader by default. REST APIs often expect a custom header: setapi_key_header(for exampleX-ERP-Key) to override the header name. This field exists only onopenapiservers withauth_type: api_key.oauth2— AISIX mints an access token from the configured client credentials and sends it as a bearer, with the same token caching as MCP upstreams.
Redirects are never followed on generated tool calls, so the credential cannot be re-sent to a host you did not configure.
Call Results and Errors
A successful response's body is returned as the tool result text. A non-2xx response returns a tool-level error result (isError: true) carrying HTTP <status> and the response body, so the agent can see and react to the failure. An argument mistake — a missing required path parameter, or a path parameter containing / or .. (rejected to keep the request on the configured path) — is reported the same readable way.
Update the Document
Replacing the document re-runs validation and regenerates the tool list. Provide spec_content or spec_url on an update call, or use the Replace OpenAPI document editor in the dashboard. The new tool surface is published as soon as the call returns. The caller holds the permission that approves servers, so the replacement counts as its review: reviewed_by and reviewed_at move to them, per the server review workflow. A role holding only write on mcp_server_submissions stages the replacement instead, and the current tools keep serving until a reviewer approves it. Changing api_key_header works the same way. Re-uploading a document that normalizes to the identical stored version is not treated as a change at all.
The server's type is fixed at creation: to switch between an MCP upstream and an OpenAPI backing, delete the entry and register a new one.