Skip to main content

Version: latest

Expose REST APIs as MCP Tools for AI Agents

This guide explains how to use the openapi-to-mcp plugin to expose existing REST APIs as MCP tools. API7 Gateway reads your OpenAPI definition, starts a local MCP server, and maps each API operation to a tool that AI agents can discover and invoke.

Overview

MCP (Model Context Protocol) is an open protocol for connecting AI agents to external tools. Without MCP, agent integrations with REST APIs are usually custom and fragile. The openapi-to-mcp plugin solves this by converting OpenAPI 3.x operations into MCP tool definitions at the gateway layer.

With this approach:

  • Existing REST APIs stay unchanged.
  • AI agents discover tools dynamically through MCP.
  • Tool invocations are translated into normal upstream HTTP requests through API7 Gateway.

How MCP Gateway Works

The request path is:

AI Agent → MCP Client → API7 Gateway (MCP Server) → Upstream REST APIs

At runtime, the plugin starts a local MCP server and exposes two transport modes:

  • sse (default):
    • GET /.api7_mcp/sse for the event stream
    • POST messages on the MCP message endpoint
  • streamable_http:
    • Stateless POST /.api7_mcp/mcp_stateless

In streamable_http (stateless) mode, the openapi_url and base_url from the plugin config are not automatically passed as context per request. Each MCP request must include these headers:

HeaderPurposeExample
x-openapi2mcp-base-urlBase URL for REST callshttps://petstore3.swagger.io
x-openapi2mcp-openapi-specURL of the OpenAPI spechttps://petstore3.swagger.io/api/v3/openapi.json
AcceptMust include SSE supportapplication/json, text/event-stream

Prerequisites

Before you begin, make sure you have:

  • API7 Enterprise Gateway running (openapi-to-mcp is Enterprise-only).
  • An upstream service that exposes a valid OpenAPI 3.x specification.
  • An MCP client (for example, Claude Desktop or another MCP-compatible client) for validation.

Configure the MCP Gateway

Configure a route with the openapi-to-mcp plugin. The following example uses the required baseline configuration:

{
"openapi_url": "http://upstream/openapi.json",
"base_url": "http://upstream:8080",
"transport_mode": "sse",
"headers": {},
"flatten_parameters": false
}
curl "http://127.0.0.1:7080/apisix/admin/routes?gateway_group_id=default" -X PUT \
-H "X-API-KEY: $ADMIN_API_KEY" \
-d '{
"id": "openapi-to-mcp-route",
"service_id": "$SERVICE_ID",
"paths": ["/.api7_mcp/*"],
"plugins": {
"openapi-to-mcp": {
"openapi_url": "http://upstream/openapi.json",
"base_url": "http://upstream:8080",
"transport_mode": "sse",
"headers": {
"Authorization": "Bearer $ctx.var.upstream_token"
},
"flatten_parameters": false
}
}
}'

openapi_url points to your OpenAPI 3.x document. The plugin parses this spec and builds MCP tools from its operations.

base_url is the upstream REST API base address used when a tool is invoked.

transport_mode selects the MCP transport. Use sse (default) or streamable_http.

headers adds upstream request headers for tool invocations. Header values support ctx.var variable resolution.

flatten_parameters controls whether nested parameters are flattened when generating tool input schemas.

Validate with an MCP Client

Step 1 — Connect and Discover Tools

SSE mode

Connect the MCP client to the SSE endpoint:

curl -N "http://127.0.0.1:9080/.api7_mcp/sse"

A successful connection returns an event stream with the session endpoint:

event: endpoint
data: /.api7_mcp/*?sessionId=abc123xyz

Streamable HTTP mode

Send a tools/list request to discover available tools:

curl -s "http://127.0.0.1:9080/.api7_mcp/mcp_stateless" \
-X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "x-openapi2mcp-base-url: https://petstore3.swagger.io" \
-H "x-openapi2mcp-openapi-spec: https://petstore3.swagger.io/api/v3/openapi.json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'

Response (HTTP 200) — 19 tools discovered:

event: message
data: {
"result": {
"tools": [
{"name": "updatePet", "description": "Update an existing pet by Id"},
{"name": "addPet", "description": "Add a new pet to the store"},
{"name": "findPetsByStatus", "description": "Multiple status values can be provided with comma separated strings"},
{"name": "findPetsByTags", "description": "Multiple tags can be provided with comma separated strings"},
{"name": "getPetById", "description": "Returns a single pet"},
{"name": "updatePetWithForm", "description": "Updates a pet in the store with form data"},
{"name": "deletePet", "description": "Deletes a pet"},
{"name": "uploadFile", "description": "Uploads a file"},
{"name": "getInventory", "description": "Returns a map of status codes to quantities"},
{"name": "placeOrder", "description": "Place a new order in the store"},
{"name": "getOrderById", "description": "For valid response try integer IDs with value <= 5 or > 10"},
{"name": "deleteOrder", "description": "For valid response try integer IDs with positive integer value"},
{"name": "createUser", "description": "This can only be done by the logged in user"},
{"name": "createUsersWithListInput", "description": "Creates list of users with given input array"},
{"name": "loginUser", "description": "Logs user into the system"},
{"name": "logoutUser", "description": "Logs out current logged in user session"},
{"name": "getUserByName", "description": "Get user by user name"},
{"name": "updateUser", "description": "This can only be done by the logged in user"},
{"name": "deleteUser", "description": "This can only be done by the logged in user"}
]
},
"jsonrpc": "2.0",
"id": 2
}

Step 2 — Invoke a Tool

Call a tool to verify end-to-end REST forwarding. The following example calls getPetById, which requires a path parameter petId. This verifies the gateway correctly interpolates MCP arguments into the REST URL path.

curl -s "http://127.0.0.1:9080/.api7_mcp/mcp_stateless" \
-X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "x-openapi2mcp-base-url: https://petstore3.swagger.io" \
-H "x-openapi2mcp-openapi-spec: https://petstore3.swagger.io/api/v3/openapi.json" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "getPetById",
"arguments": {"petId": 1}
}
}'

Response (HTTP 200):

event: message
data: {
"result": {
"content": [
{
"type": "text",
"text": "{\"id\":1,\"name\":\"Cat 1\",\"photoUrls\":[],\"tags\":[],\"status\":\"available\"}"
}
]
},
"jsonrpc": "2.0",
"id": 4
}

Security Considerations

When exposing APIs as MCP tools, apply the same controls as production API traffic:

  • Authentication: enforce gateway auth (API key, JWT, mTLS) before MCP tool calls reach upstream services.
  • Authorization: restrict which routes and operations an agent identity can access.
  • Rate limiting: apply request or token-based limits to prevent abusive or runaway agent traffic.

Next Steps

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation