OpenAPI to MCP
Convert REST APIs into MCP tools using OpenAPI specifications. This allows LLMs to interact with your existing APIs without writing custom MCP servers.
What you’ll build
In this tutorial, you’ll:
- Create a simple Pet Store API specification (OpenAPI format)
- Set up a mock API server to handle requests
- Configure Agent Gateway to expose the API as MCP tools
- Test the generated tools using curl commands
Prerequisites
- Node.js installed (for the mock API server)
Step 1: Install Agent Gateway
Download and install Agent Gateway:
curl -sL https://raw.githubusercontent.com/agentgateway/agentgateway/refs/heads/main/common/scripts/get-agentgateway | bashStep 2: Create an OpenAPI specification
First, create a new directory for this tutorial and navigate to it:
mkdir openapi-tutorial && cd openapi-tutorialNow create a file called openapi.json. This file describes your REST API in OpenAPI format:
cat > openapi.json << 'EOF'
{
"openapi": "3.0.0",
"info": {
"title": "Pet Store API",
"version": "1.0.0"
},
"servers": [
{
"url": "/"
}
],
"paths": {
"/pets": {
"get": {
"operationId": "listPets",
"summary": "List all pets",
"responses": {
"200": {
"description": "A list of pets"
}
}
},
"post": {
"operationId": "createPet",
"summary": "Create a new pet",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"species": { "type": "string" }
}
}
}
}
},
"responses": {
"201": {
"description": "Pet created"
}
}
}
},
"/pets/{id}": {
"get": {
"operationId": "getPet",
"summary": "Get a pet by ID",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": { "type": "string" }
}
],
"responses": {
"200": {
"description": "A pet"
}
}
}
}
}
}
EOFThis OpenAPI spec defines a simple Pet Store API with three endpoints:
GET /pets- List all petsPOST /pets- Create a new petGET /pets/{id}- Get a specific pet by ID
Step 3: Create the Agent Gateway config
Create a configuration file that tells Agent Gateway to expose your OpenAPI spec as MCP tools:
cat > config.yaml << 'EOF'
binds:
- port: 3000
listeners:
- routes:
- policies:
cors:
allowOrigins: ["*"]
allowHeaders: ["*"]
exposeHeaders: ["Mcp-Session-Id"]
backends:
- mcp:
targets:
- name: petstore
openapi:
schema:
file: ./openapi.json
host: localhost:8080
EOFThis config:
- Listens on port 3000 for MCP connections
- Loads the OpenAPI spec from
openapi.json - Forwards API requests to
localhost:8080(where our mock server will run)
Step 4: Create a mock API server
For this tutorial, we’ll create a simple Node.js server that simulates the Pet Store API. Create a file called server.js:
cat > server.js << 'EOF'
const http = require('http');
const pets = [
{ id: "1", name: "Buddy", species: "dog" },
{ id: "2", name: "Whiskers", species: "cat" }
];
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'application/json');
if (req.method === 'GET' && req.url === '/pets') {
res.end(JSON.stringify(pets));
} else if (req.method === 'GET' && req.url.startsWith('/pets/')) {
const id = req.url.split('/')[2];
const pet = pets.find(p => p.id === id);
if (pet) {
res.end(JSON.stringify(pet));
} else {
res.statusCode = 404;
res.end(JSON.stringify({ error: "Pet not found" }));
}
} else if (req.method === 'POST' && req.url === '/pets') {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
const newPet = JSON.parse(body);
newPet.id = String(pets.length + 1);
pets.push(newPet);
res.statusCode = 201;
res.end(JSON.stringify(newPet));
});
} else {
res.statusCode = 404;
res.end(JSON.stringify({ error: "Not found" }));
}
});
server.listen(8080, () => console.log('Mock API running on http://localhost:8080'));
EOFNow start the mock server:
node server.jsYou should see:
Mock API running on http://localhost:8080Keep this terminal running. The mock server needs to stay active for the tutorial.
Step 5: Start Agent Gateway
Open a new terminal window and navigate to your tutorial directory:
cd openapi-tutorialStart Agent Gateway:
agentgateway -f config.yamlYou should see output similar to:
INFO agentgateway: Listening on 0.0.0.0:3000
INFO agentgateway: Admin UI available at http://localhost:15000/ui/Keep this terminal running as well. You now have two terminals:
- Terminal 1: Running the mock API server (port 8080)
- Terminal 2: Running Agent Gateway (port 3000)
Step 6: Test the generated tools
Open a third terminal to run the test commands.
Initialize an MCP session
MCP requires a session to be initialized first. Run this command:
curl -s -i http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'Look for the mcp-session-id header in the response. It will look something like:
mcp-session-id: abc123-def456-ghi789Copy this session ID value - you’ll need it for the next commands.
List available tools
Replace YOUR_SESSION_ID with the session ID you copied, then run:
curl -s http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":2}'You should see three tools that were automatically generated from your OpenAPI spec:
"listPets"
"createPet"
"getPet"Step 7: Call a tool
Now let’s call the listPets tool to verify everything works end-to-end. Replace YOUR_SESSION_ID with your session ID:
curl -s http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: YOUR_SESSION_ID" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"listPets","arguments":{}},"id":3}'You should see the mock pets returned from your API server:
[{"id":"1","name":"Buddy","species":"dog"},{"id":"2","name":"Whiskers","species":"cat"}]Congratulations! You’ve successfully exposed a REST API as MCP tools using Agent Gateway.
Cleanup
When you’re done, stop the running processes:
- Press
Ctrl+Cin the terminal running Agent Gateway - Press
Ctrl+Cin the terminal running the mock server
How it works
Agent Gateway automatically:
- Parses the OpenAPI spec - Reads your API definition and understands the available endpoints
- Generates MCP tools - Each API operation (like
GET /pets) becomes a callable MCP tool - Handles requests - When a tool is called, Agent Gateway translates it to an HTTP request
- Returns responses - API responses are converted back to MCP format for the client
Tool naming
Tools are named using the operationId field from your OpenAPI spec:
| OpenAPI operationId | MCP Tool Name |
|---|---|
listPets |
listPets |
createPet |
createPet |
getPet |
getPet |
Using with real APIs
In production, you would point Agent Gateway to your actual API server instead of the mock server. Simply update the host field in the config:
targets:
- name: petstore
openapi:
schema:
file: ./openapi.json
host: api.yourcompany.com:443Remote OpenAPI specs
You can also load OpenAPI specs directly from a URL instead of a local file:
targets:
- name: api
openapi:
schema:
url: https://api.example.com/openapi.json
host: api.example.com