simple-mcp
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., "@simple-mcpset up petstore from simple-mcp.example.yaml"
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.
simple-mcp
Turn any API into a curated MCP server from a single config file.
Point it at an API description, and it exposes that API to any MCP client (Claude Desktop, MCP Inspector, IDEs) as a set of tools. Unlike a 1:1 endpoint dump, simple-mcp curates: it filters to the operations you want, writes structured tool descriptions, and — for large APIs — switches to on-demand tool discovery so it doesn't flood the model's context.
Status: MVP. REST (OpenAPI 3.0/3.1) is fully supported. GraphQL and gRPC are architected for but not yet implemented (the adapter seam exists; the adapters throw "not yet implemented"). LLM-generated descriptions are stubbed — see Describe modes.
Why curation matters
Naively turning every API endpoint into an MCP tool breaks down fast: LLM tool-selection degrades once a few dozen tools are in context, and every tool definition costs tokens on every turn. simple-mcp addresses this directly:
Filter to an intentional surface (default: nothing is exposed unless you include it).
Describe tools with a structured template (Purpose / Guidelines / Limitations / Parameters).
Expose them
statically for small APIs, ordynamically (a singlesearch_toolsmeta-tool that loads real tools on demand) for large ones — chosen automatically.
Related MCP server: mcp-api-gateway
Quick start
npm install
npm run build
# Run against the bundled petstore example (no auth needed):
node dist/index.js simple-mcp.example.yaml
# or, once published: npx simple-mcp simple-mcp.example.yamlThe server speaks MCP over stdio by default. To try it interactively, point the MCP Inspector at that command.
Use it from Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"petstore": {
"command": "node",
"args": ["/absolute/path/to/simple-mcp/dist/index.js", "/absolute/path/to/simple-mcp.example.yaml"]
}
}
}Configuration
A single YAML file describes the whole server. Full example (simple-mcp.example.yaml):
server:
name: petstore-mcp
transport: [stdio] # stdio and/or http
source:
protocol: rest # rest (GraphQL/gRPC not yet implemented)
spec: https://petstore3.swagger.io/api/v3/openapi.json # URL or local path
baseUrl: https://petstore3.swagger.io/api/v3 # overrides the spec's server URL
auth:
type: none # none | bearer | apiKey | basic | oauth2
curation:
defaultInclude: false # if false, only `include`d operations are exposed
include:
- "getPetById" # match operationId (glob supported: "get*", "pets.*")
- "findPetsByStatus"
exclude: []
describe:
mode: deterministic # deterministic | llm
exposure: auto # auto | static | dynamic
tools: [] # optional task-oriented consolidation (see below)server
Key | Meaning |
| Server name advertised to the MCP client. |
| Array of |
source
Key | Meaning |
|
|
| OpenAPI document — remote URL or local file path. |
| Base URL for live calls. Recommended — overrides the spec's |
auth
Secrets come from environment variables via ${VAR} interpolation — never hardcode them in the file.
| Fields | Sent as |
| — | — |
|
|
|
|
| header or query param |
|
|
|
|
|
|
auth:
type: bearer
token: ${ACME_TOKEN} # read from the environment at startupUnset ${VAR} in the auth block is a hard error (so a missing secret fails loudly rather than sending unauthenticated requests). Elsewhere, an unresolved ${...} is left as a literal.
curation
Key | Meaning |
|
|
| Glob patterns matched against operationId, tags, and path. |
|
|
|
|
| Task-oriented consolidation: expose one named tool backed by an ordered sequence of operations. |
Exposure strategies
static — every curated tool is registered up front. Best for small, focused APIs.
dynamic — only a
search_toolstool is registered; the client searches by keyword, and matching tools are registered on demand. Keeps context small for large APIs.auto — picks
dynamicabove 30 tools,staticotherwise.
Describe modes
deterministic (default) — builds a structured description (Purpose, Guidelines, Limitations, Parameters, …) from the spec's own metadata. No API key needed.
llm — *stubbed._ Intended to synthesize richer descriptions via Claude, cached to disk. Currently, if selected without
@anthropic-ai/sdk+ANTHROPIC_API_KEY, it prints a warning and falls back to deterministic.
Task-oriented tools
Instead of exposing findAvailability and createEvent separately, expose one intent-shaped tool:
curation:
tools:
- name: schedule_event
steps: [findAvailability, createEvent]Verified against real APIs
The REST adapter is validated end-to-end against public specs (scripts/validate-realworld.ts):
API | Operations | Exposure (auto) | Introspect |
19 | static | ~1.5s | |
1,194 | dynamic | ~1.5s | |
587 | dynamic | ~2.7s |
All three introspect cleanly, and a live findPetsByStatus call against the petstore server round-trips end-to-end (the relative servers: [{url: /api/v3}] in its spec is resolved to an absolute URL automatically). Large APIs like GitHub and Stripe cross the 30-tool threshold and switch to dynamic exposure, so the client sees a single search_tools entry instead of ~1,000 tool definitions.
Re-run it yourself: node --import tsx scripts/validate-realworld.ts.
Security
HTTP transport is local-by-default and optional token auth protects networked MCP access. Outbound calls are restricted to public destinations unless you opt in.
Env var | Default | Meaning |
|
| Bind address for |
| (unset) | When set, require |
|
| Max inbound HTTP request body size (over → 413). |
|
| Upstream |
|
| Max upstream response body size. |
| (unset) | Set to |
Additional hardening: sensitive client-supplied header parameters are dropped; operator auth is not sent to non-approved origins; OpenAPI x-mcp: { enabled: false } disables operations; secrets from auth are redacted from tool error text.
Development
npm run build # tsc → dist/
npm test # node:test suite (unit + integration round-trips)
npx tsc --noEmit # type-check onlyTests use Node's built-in node:test (no framework). The integration suite drives a real MCP client↔server round trip against a mock upstream, covering static and dynamic exposure, path params, and request bodies.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
MCP server for OpenAI API (chat completions, image generation, embeddings) via AceDataCloud
Host any HTTP API as a standard MCP server; auto-distribute to 12+ mainstream agent platforms.
Create guides as MCP servers to instruct coding agents to use your software (library, API, etc).
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceTurns any OpenAPI specification into a fully working MCP server with a single command, enabling AI agents to call APIs without writing any glue code.2 npmMIT
- AlicenseAqualityDmaintenanceA universal MCP server that integrates any API with Claude Desktop by pointing it at a Swagger/OpenAPI spec, automatically generating tools for interaction.344MIT
- AlicenseNot gradedqualityDmaintenanceTurns any CLI tool or REST API into an MCP server for Claude, enabling Claude to use git, databases, or any API through natural language.MIT
- AlicenseNot gradedqualityDmaintenanceConverts any OpenAPI/Swagger spec into an MCP server, exposing REST API endpoints as tools for Claude.MIT