mcp-expose
Allows exposing existing AdonisJS routes as MCP tools using the route's .mcp() method, preserving middleware, auth, and validation.
Allows exposing existing Express routes as MCP tools via middleware, keeping the app's auth, validation, and middleware pipeline intact.
Allows exposing existing Fastify routes as MCP tools using route configuration, reusing the route's schema and running through Fastify's full hook and plugin pipeline.
Allows exposing existing Hono routes as MCP tools via middleware, dispatching in-process across supported runtimes.
Allows exposing existing Koa routes as MCP tools via middleware, preserving the existing middleware stack and request handling.
Allows exposing existing NestJS HTTP routes as MCP tools using a decorator, preserving auth guards, DTO validation, rate limits, and logging.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-exposefetch order 123 from my API"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-expose
Make your existing Node.js API agent-ready in minutes.
mcp-expose turns selected HTTP routes of your NestJS, Express, Fastify, Koa, Hono or AdonisJS app into
Model Context Protocol (MCP) tools, so AI agents such as Claude, Cursor,
VS Code Copilot and ChatGPT can call them. Your existing auth guards, DTO validation, rate limits and
logging keep working because every tool call runs through your app's normal request pipeline.
// NestJS
@Get(':id')
@McpTool({ description: 'Get an order by id' })
findOne(@Param('id') id: string) { ... }
// Express / Koa / Hono
app.get('/orders/:id', mcpTool({ description: 'Get an order by id' }), auth, getOrder);
// Fastify
app.get('/orders/:id', { schema, config: { mcp: { description: 'Get an order by id' } } }, getOrder);
// AdonisJS
router.get('/orders/:id', [OrdersController, 'show']).use(middleware.auth()).mcp({ description: 'Get an order by id' });One decorator or marker per route, then add the module/plugin. No wrapper code to write.
Zero runtime dependencies. Dual ESM/CJS. Node.js 20, 22 and 24, plus Bun, Deno and Workers for Hono.
Supports the current and the two previous major versions of every framework, verified end to end.
Speaks MCP Streamable HTTP (protocol
2024-11-05→2025-11-25), stateless, so it scales horizontally and runs serverless.
Table of contents
Related MCP server: openapi-mcp-bridge
Why this library?
Many companies now want their APIs to be "agent-ready". The usual approach is a separate, hand-written MCP server that re-implements each endpoint as a tool:
Hand-written MCP wrapper |
|
Duplicates every endpoint's input schema, auth and error handling | Reuses the route that already exists. The route is the tool. |
Needs its own auth. The easy path is often one over-privileged API key | Forwards the caller's |
Validation logic drifts from the real API | Your |
Rate limits and audit logs are bypassed or re-implemented | Every tool call is a real request through your middleware |
A second service to deploy, version and monitor | Mounted at |
Tied to one framework | Same concepts for NestJS, Express, Fastify, Koa and Hono |
Benefits for developers
Minutes, not days. Add
@McpTool()to the endpoints you want to expose and import one module.Single source of truth. Schemas come from your DTOs, Fastify JSON schemas, zod or OpenAPI. Change the endpoint and the tool changes with it.
Secure by default. Routes are opt-in. The app's own auth applies to each tool call.
Originchecks protect against DNS rebinding.Agent-friendly errors. Your API's 400/401/404 responses are returned to the model as tool errors, so it can correct itself (for example "quantity must not be greater than 10").
Framework-agnostic core. Moving from Express to Fastify, or to a NestJS monolith, keeps the same tool model.
How it works
AI client (Claude, Cursor, …)
│ POST /mcp {"method":"tools/call","params":{"name":"create_order","arguments":{…}}}
│ Authorization: Bearer <user token>
▼
┌──────────────────────── your app ────────────────────────┐
│ /mcp endpoint (mcp-expose) │
│ 1. finds the route behind "create_order" │
│ 2. maps arguments → path params / query / JSON body │
│ 3. forwards Authorization, Cookie, X-Api-Key, IP │
│ 4. dispatches: POST /orders ────────────┐ │
│ ▼ │
│ middleware → auth guard → rate limit → validation → handler
│ │ │
│ 5. HTTP response → MCP tool result ◄──────┘ │
│ (2xx → content + structuredContent, 4xx/5xx → isError)
└───────────────────────────────────────────────────────────┘Dispatch uses the fastest option each framework supports safely:
Fastify uses
fastify.inject(), in process, with every hook, schema and plugin applied.Hono uses
app.request(), in process, and runs on any runtime.Express, Koa, NestJS and AdonisJS use a loopback HTTP request to the port the MCP call arrived on, so the full stack runs, including anything outside the framework such as a reverse proxy module.
Tools are discovered lazily on the first MCP request, so the order you register routes and the MCP endpoint rarely matters (Fastify is the exception, see its guide).
Supported frameworks
Framework | Import | How you mark a route | Schema source | Dispatch |
NestJS (Express or Fastify) |
|
| class-validator DTOs (+ | loopback |
Express |
|
| options (JSON Schema / zod) | loopback |
Fastify |
|
| the route's own |
|
Koa + @koa/router (or koa-router) |
|
| options | loopback |
Hono |
|
| options |
|
AdonisJS |
|
| options, or a VineJS validator | loopback |
Any HTTP API (any language) |
| OpenAPI | OpenAPI document |
|
Version compatibility
mcp-expose supports the current major version of each framework and the two before it. Every row
below runs in CI as a real project (see e2e/): the packed library is installed from its
tarball and the app is driven by the official MCP SDK client, on Node.js 20, 22 and 24.
Framework | Supported majors | Notes |
NestJS | 12, 11, 10 | Express and Fastify platforms; CommonJS and ESM projects; classic and v11 |
Express | 5, 4, 3 | Express 3 has been unmaintained since 2015 (upgrade recommended) |
Fastify | 5, 4, 3 | Fastify 3 is end-of-life upstream |
Koa | 3, 2, 1 | Koa 1 (generator middleware) uses |
Hono | 4, 3, 2 | Hono 2 and 3 are end-of-life upstream |
AdonisJS | 7, 6 | AdonisJS 7 needs Node.js 24. AdonisJS 5 is not supported (see below) |
AdonisJS 5 (last release November 2022) is the only exception. It uses a different architecture:
IoC-container imports such as @ioc:Adonis/Core/Route, and CommonJS builds. Supporting it would need a
separate adapter. Please open an issue if you need it.
Installation
npm install mcp-expose
# or: pnpm add mcp-expose / yarn add mcp-expose / bun add mcp-exposeFramework packages are optional peer dependencies. Use the ones you already have.
For NestJS DTO → schema generation, class-validator should be installed. Most Nest apps already have it.
Framework guides
Each guide follows the same three steps: 1) install, 2) mark routes, 3) mount the endpoint. Then connect a client.
NestJS
Step 1: import the module (once, in your root module):
// app.module.ts
import { Module } from '@nestjs/common';
import { McpModule } from 'mcp-expose/nestjs';
@Module({
imports: [
McpModule.forRoot({
name: 'orders-api', // shown to the AI client
version: '1.0.0',
instructions: 'Tools for looking up and placing orders.',
// path: 'mcp', // default endpoint: /mcp
// guards: [JwtAuthGuard], // protect the MCP endpoint itself (tools/list too)
}),
OrdersModule,
],
})
export class AppModule {}Step 2: decorate the endpoints you want to expose:
// orders.controller.ts
import { McpTool } from 'mcp-expose/nestjs';
export class CreateOrderDto {
@IsString() sku!: string;
@IsInt() @Min(1) @Max(10) quantity!: number;
@IsString() @IsOptional() note?: string;
}
@Controller('orders')
@UseGuards(JwtAuthGuard) // ← still enforced for every tool call
export class OrdersController {
@Get(':id')
@McpTool({ description: 'Get one order by its id.' })
findOne(@Param('id', ParseIntPipe) id: number) { … }
@Post()
@McpTool({ name: 'create_order', description: 'Create an order. quantity must be 1-10.' })
create(@Body() dto: CreateOrderDto) { … } // ← input schema generated from the DTO
@Post(':id/refund') // ← no @McpTool: invisible to agents
refund(@Param('id') id: string) { … }
}The generated tool input for create_order:
{
"type": "object",
"properties": {
"sku": { "type": "string" },
"quantity": { "type": "integer", "minimum": 1, "maximum": 10 },
"note": { "type": "string" }
},
"required": ["sku", "quantity"]
}Loading options from configuration: use forRootAsync. path and guards are passed directly,
because they define the MCP controller:
McpModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({ name: config.get('APP_NAME'), version: config.get('APP_VERSION') }),
guards: [JwtAuthGuard],
});Step 3: bootstrap as usual:
// main.ts
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api', { exclude: ['mcp'] }); // optional: keep MCP at /mcp
app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }));
await app.listen(3000); // MCP: http://localhost:3000/mcpNotes
Default tool names are
<controller>_<method>in snake_case, for exampleorders_find_one. Setnameto override.The global prefix (
/api) and URI versioning (/v1) are detected automatically. The MCP endpoint is version-neutral.Works with
@nestjs/platform-expressand@nestjs/platform-fastify.Inject
McpServiceto add tools at runtime:mcpService.server.addTool(defineTool({...})).Global guards also apply to
/mcp. If you use a global JWT guard, MCP clients must send a token, which is usually what you want. Mark the endpoint public with your own decorator mechanism if not.
Express
import express from 'express';
import { z } from 'zod';
import { mcpTool, mountMcp } from 'mcp-expose/express';
const app = express();
app.use(express.json());
app.set('trust proxy', 'loopback'); // req.ip = real agent IP for tool calls (rate limiting)
// Step 1: add mcpTool() as the FIRST handler of the routes to expose
app.get(
'/products',
mcpTool({
name: 'search_products',
description: 'Search the product catalog by name.',
query: { type: 'object', properties: { q: { type: 'string' } } },
}),
searchProducts,
);
app.post(
'/orders',
mcpTool({
name: 'create_order',
description: 'Place an order.',
body: z.object({ productId: z.string(), quantity: z.number().int().min(1) }), // zod works too
}),
requireAuth,
rateLimit,
createOrder,
);
// Step 2: mount the endpoint (before or after the routes)
mountMcp(app, { name: 'shop-api', version: '1.0.0' });
app.listen(3000); // MCP: http://localhost:3000/mcpRouters mounted with a path: Express 5 does not record mount paths, so pass them explicitly. Express 4 detects them automatically.
const api = express.Router();
api.get('/orders', mcpTool({ description: 'List orders' }), listOrders);
app.use('/api', api);
mountMcp(app, { name: 'shop-api', routers: { '/api': api } });No-touch mode: expose routes without editing them:
mountMcp(app, {
name: 'shop-api',
routes: [{ method: 'GET', path: '/orders/:id', description: 'Get an order' }],
});Fastify
import Fastify from 'fastify';
import { fastifyMcp } from 'mcp-expose/fastify';
const app = Fastify();
// Step 1: register the plugin BEFORE your routes (it listens to onRoute)
await app.register(fastifyMcp, { name: 'todo-api', version: '1.0.0' });
// Step 2: add `config.mcp` to routes. Their JSON `schema` becomes the tool schema.
app.post(
'/todos',
{
schema: {
body: {
type: 'object',
properties: { title: { type: 'string', minLength: 1, description: 'What needs doing' } },
required: ['title'],
},
},
config: { mcp: { name: 'add_todo', description: 'Add a todo item.' } }, // or `mcp: true`
},
addTodo,
);
await app.listen({ port: 3000 }); // MCP: http://localhost:3000/mcpProtect the MCP endpoint itself with Fastify hooks: register(fastifyMcp, { name, routeOptions: { onRequest: app.authenticate } }).
The server is available as app.mcpServer.
Koa
import Koa from 'koa';
import Router from '@koa/router';
import { mcpTool, mountMcp } from 'mcp-expose/koa';
const app = new Koa();
const router = new Router({ prefix: '/api' });
// Step 1: mark routes
router.get('/weather/:city', mcpTool({ description: 'Current weather for a city.' }), getWeather);
// Step 2: mount the endpoint (before your routers) and list the routers to scan
mountMcp(app, { name: 'weather-api', routers: [router] });
app.use(router.routes());
app.listen(3000); // MCP: http://localhost:3000/mcpkoaMcp(options) returns the same endpoint as a plain middleware, for use with koa-mount or koa-compose.
Set app.proxy = true if your rate limiter keys on ctx.ip, so the forwarded agent IP is used.
Koa 1 (generator middleware, koa-router 5): use the legacy helpers.
const { koaMcpLegacy, mcpToolLegacy } = require('mcp-expose/koa');
router.get('/weather/:city', mcpToolLegacy({ description: 'Current weather for a city.' }), getWeather);
app.use(koaMcpLegacy({ name: 'weather-api', routers: [router] }));
app.use(router.routes());Hono
Works on Node, Bun, Deno, Cloudflare Workers and Vercel Edge. Tool calls use app.request(), so no network hop is involved.
import { Hono } from 'hono';
import { z } from 'zod';
import { mcpTool, mountMcp } from 'mcp-expose/hono';
const app = new Hono();
app.post(
'/notes',
mcpTool({ name: 'create_note', description: 'Save a note.', body: z.object({ text: z.string() }) }),
bearerAuth({ token }),
async (c) => c.json(await saveNote(await c.req.json()), 201),
);
mountMcp(app, { name: 'notes-api' });
export default app; // MCP: https://<your-worker>/mcpAdonisJS
Works with AdonisJS 6 and 7. Import mcp-expose/adonisjs in start/routes.ts. That adds a .mcp() method to
routes, next to .as() and .use():
// start/routes.ts
import router from '@adonisjs/core/services/router';
import { mountMcp } from 'mcp-expose/adonisjs';
import { middleware } from '#start/kernel';
import { createOrderValidator } from '#validators/order';
const OrdersController = () => import('#controllers/orders_controller');
router
.group(() => {
// Step 1: mark routes. Group prefixes and middleware (auth, throttle) all apply.
router.get('orders/:id', [OrdersController, 'show']).mcp({ description: 'Get an order by id' });
// A VineJS 4 validator (AdonisJS 7) can be passed as the schema directly
router
.post('orders', [OrdersController, 'store'])
.mcp({ name: 'create_order', description: 'Place an order', body: createOrderValidator });
})
.prefix('/api/v1')
.use(middleware.auth());
// Step 2: mount the endpoint
mountMcp(router, { name: 'shop-api' });
// MCP: http://localhost:3333/mcpNotes
Validation errors from
request.validateUsing()(HTTP 422) are returned to the agent so it can correct itself.VineJS 3 (AdonisJS 6) cannot export JSON Schema, so pass
bodyas a JSON Schema object there.Protect the MCP endpoint itself with
configureRoute:mountMcp(router, { name, configureRoute: (route) => route.use(middleware.auth()) }).Resource routes: mark individual actions with
router.resource('posts', PostsController).tap('show', (route) => route.mcp({ ... })).If you use the web starter kit, exclude the MCP path from CSRF protection (
config/shield.ts,csrf.exceptRoutes).
Any API via OpenAPI (standalone gateway)
Put an MCP gateway in front of any HTTP API, whatever language it is written in, using its OpenAPI 3 document.
By default only operations marked x-mcp: true are exposed. You can also pass an include filter.
import express from 'express';
import { createFetchDispatcher, toolsFromOpenApi } from 'mcp-expose';
import { mountMcp } from 'mcp-expose/express';
const spec = await fetch('https://api.example.com/openapi.json').then((r) => r.json());
const tools = toolsFromOpenApi(spec, createFetchDispatcher({ baseUrl: 'https://api.example.com' }), {
include: ({ method }) => method === 'get', // e.g. only read-only operations
});
const app = express();
mountMcp(app, { name: 'example-gateway', tools });
app.listen(3000);This also works with @nestjs/swagger, @fastify/swagger, tsoa and hono-openapi documents. Pass a dereferenced document, because $refs are not resolved.
Connect an AI client
Start your app, then point a client at http://localhost:3000/mcp. Pass the same credentials a normal API
client would use. They are forwarded to your routes.
Claude Code
claude mcp add --transport http shop-api http://localhost:3000/mcp \
--header "Authorization: Bearer <token>"Cursor (~/.cursor/mcp.json or .cursor/mcp.json)
{
"mcpServers": {
"shop-api": {
"url": "http://localhost:3000/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}VS Code (Copilot agent mode) (.vscode/mcp.json)
{
"servers": {
"shop-api": {
"type": "http",
"url": "http://localhost:3000/mcp",
"headers": { "Authorization": "Bearer ${input:token}" }
}
},
"inputs": [{ "id": "token", "type": "promptString", "description": "API token", "password": true }]
}Claude Desktop. For a deployed server, add it under Settings → Connectors using its public URL.
For a local server, bridge it with mcp-remote in claude_desktop_config.json:
{
"mcpServers": {
"shop-api": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:3000/mcp", "--header", "Authorization: Bearer ${API_TOKEN}"],
"env": { "API_TOKEN": "<token>" }
}
}
}Debug with MCP Inspector
npx @modelcontextprotocol/inspector
# Transport: Streamable HTTP, URL: http://localhost:3000/mcpcurl smoke test
curl -s localhost:3000/mcp -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Defining tool inputs (schemas)
The agent sees one flat object of arguments. mcp-expose maps each argument back to the right place:
Argument | Sent as |
name matches a path placeholder ( | path segment (URL-encoded) |
declared in | query string |
declared in | JSON body property |
undeclared, route is | query string |
undeclared, route is | JSON body property |
| the whole body, under the |
Every schema option accepts:
a plain JSON Schema object,
a zod 4 schema (
z.object({...})),any Standard Schema library with JSON Schema export (valibot, arktype, …). These are also validated before the request is sent.
Sources, from highest to lowest precedence:
inputin the tool options: the full schema, used as is.params/query/bodyin the tool options.Framework metadata: NestJS DTOs and
@Param/@Querytypes, or Fastify routeschema.Path placeholders, as string parameters.
Your app's own validation always runs as well. The schema tells the agent what to send, and your API decides what it accepts.
Configuration reference
Server options (all adapters)
Option | Type | Default | Description |
|
| required | Server name shown to clients. |
|
|
| Server version. |
|
| none | Guidance for the model on how to use the tools together. |
|
|
| Endpoint path. |
|
|
| Browser origins allowed to call the endpoint. Requests without |
|
|
| Headers copied from the MCP request to the internal API call. |
|
|
| Longer API responses are truncated before reaching the model. |
|
|
| Extra hand-written tools. |
|
| loopback | Express/Koa/Nest/Adonis. Where internal calls go. Set it for HTTPS with self-signed certs, unix sockets, or a separate API host. |
|
|
| Express/Koa/Hono. Expose routes without editing them. |
| see guide | none | Express: |
|
|
| Express. Middleware in front of |
|
|
| NestJS. Guards on the MCP controller. |
|
| none | NestJS. Extra prefix for tool routes. Global prefix and URI versioning are automatic. |
|
| none | Fastify. Extra route options for |
|
| none | AdonisJS. Configure the MCP route, e.g. add middleware. |
Tool options (@McpTool(), mcpTool(), config.mcp, .mcp())
Option | Description |
| Tool name ( |
| The most important field. Tells the model what the tool does and when to use it. |
| Human-friendly display name. |
| Schemas, see above. |
| MCP hints: |
| Static headers added to the internal request. |
Each internal request also carries X-Mcp-Tool: <tool name>, so you can log or meter agent traffic separately.
Custom (non-HTTP) tools
Not everything needs a route:
import { defineTool } from 'mcp-expose';
import { z } from 'zod';
const convert = defineTool({
name: 'convert_currency',
description: "Convert an amount between currencies using today's rate.",
input: z.object({ amount: z.number(), from: z.string().length(3), to: z.string().length(3) }),
handler: async ({ amount, from, to }, ctx) => ({ result: await fx.convert(amount, from, to) }),
});
mountMcp(app, { name: 'shop-api', tools: [convert] });Handlers can return a string, any JSON value, or a full MCP ToolResult. ctx.headers holds the MCP request's headers, so you can authenticate there too.
Security checklist
Opt-in only. Nothing is exposed unless you mark it. Review marked routes the way you review a public API, because an LLM can call them with any arguments.
Use per-user credentials. Clients send their own token, the token is forwarded, and your guards authorise the call. Avoid one shared super-token.
Protect discovery too if tool names are sensitive (
guards,middleware,routeOptions).Rate limits and IPs: the agent IP is sent as
X-Forwarded-For. For loopback adapters, trust loopback only: Expressapp.set('trust proxy', 'loopback'), Koaapp.proxy = truebehind a proxy that overwrites the header, Nest (Express)app.set('trust proxy', 'loopback'). Fastifyinject()sets the IP directly.Browser access: keep
allowedOriginsempty unless a browser app must call/mcpdirectly.Annotations are hints, not security. A
readOnlyHintnever prevents a call. Enforce permissions in your API.Destructive actions: clients may use
destructiveHintto decide when to ask the user for confirmation. Keep it accurate, and require stronger auth for dangerous routes.Response size: tune
maxResponseChars, and prefer endpoints that paginate.
Writing tools agents use well
Describe when to use the tool, not only what it does: "Search products by name. Use this before
create_orderto find a validproductId."Document units, formats and limits in schema
descriptions ("price in cents","ISO 8601 date").Prefer a few task-shaped tools (
search_orders) over many CRUD primitives.Return clear 4xx messages. They go straight to the model, which uses them to retry correctly.
Use
instructionson the server for cross-tool workflow hints.
Limitations and roadmap
Current scope (1.x):
Stateless Streamable HTTP with JSON responses. No server-initiated SSE stream or sessions. The spec allows this, and it keeps the server horizontally scalable.
Tools only.
resources/listandprompts/listreturn empty lists.NestJS: URI versioning is detected. Header and media-type versioning need
headerson the tool.Express 5 routers mounted with a path must be listed in
routers.Path parameters cannot be empty,
.or... These are rejected so an agent cannot reach routes that were not exposed.
Planned (non-breaking, 1.x minor releases):
OAuth 2.1 protected-resource metadata (RFC 9728) helpers for remote MCP auth, and per-user tool lists
Next.js route handlers, Hapi and Elysia adapters
Structured output schemas, and binary/file responses
Streaming long-running responses over SSE
CLI to preview generated tools (
npx mcp-expose inspect)Resources from GET routes, and prompts
Contributions are welcome. See Development.
Development
npm install
npm test # vitest: core + all six adapters (real servers, real HTTP)
npm run test:e2e # pack → install into 18 fresh framework projects → official MCP SDK client
npm run typecheck
npm run build # ESM + CJS + .d.ts into dist/
# run an example (after npm run build)
npm run example:express # or example:fastify / example:koa / example:hono / example:nestjsProject layout:
src/
core/ framework-agnostic: MCP JSON-RPC server, route→tool mapping, schemas, dispatchers
express/ mcpTool() + mountMcp()
nestjs/ @McpTool() + McpModule + DTO → JSON Schema
fastify/ fastifyMcp plugin (config.mcp)
koa/ mcpTool() + mountMcp() / koaMcp() (+ Koa 1 legacy helpers)
hono/ mcpTool() + mountMcp()
adonisjs/ .mcp() route macro + mountMcp()
examples/ runnable apps for every framework + an OpenAPI gateway
e2e/ developer-style end-to-end tests (one project per framework/version)
test/ one shared behavioural contract, verified against every adapterAdding an adapter: find the marked routes, then call createRouteTool(route, options, dispatcher) and
server.handleHttp(). Reuse test/helpers.ts#assertAdapterContract to test it.
Versioning and support
mcp-expose follows Semantic Versioning. Older major versions keep receiving fixes on
maintenance branches, published under latest-<major> dist-tags (for example npm i mcp-expose@latest-3),
so a fix to an old major never changes what npm i mcp-expose installs. See the
support policy and RELEASING.md.
Contributing
Contributions are welcome. Please read CONTRIBUTING.md and the Code of Conduct. Report security issues privately as described in SECURITY.md. Release notes are in CHANGELOG.md.
License
MIT © Nitin Kachhadiya
This server cannot be deployed
Maintenance
Related MCP Connectors
The OpenRouter for tools. One MCP connection gives any AI agent 254 hosted tools, pay per call.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Discover and call 10,000+ production APIs from one MCP server. Pay-per-call billing for AI agents.
One MCP endpoint for Claude, GPT & Gemini: 100+ tools + no-code connectors + agent workers.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceConverts any REST API into MCP-compatible tools instantly by providing an OpenAPI/Swagger spec, enabling seamless integration with AI agents.MIT
- AlicenseNot gradedqualityBmaintenanceTurns any OpenAPI/Swagger API into MCP tools, enabling AI assistants to call REST API endpoints directly.2MIT
- FlicenseNot gradedqualityDmaintenanceConverts any REST API endpoints into MCP tools, enabling AI clients like Cursor and Claude Desktop to call internal services directly.-
- FlicenseNot gradedqualityDmaintenanceDynamically exposes any OpenAPI/Swagger API as tools for AI assistants, automatically generating MCP tools from OpenAPI specs with authentication support.-