yamcp
Convert any OpenAPI spec into a secure MCP server with scoped auth, per-tool allow/deny policies, rate limiting, and a redacted audit trail.
README
yamcp
Serve any OpenAPI spec as a secure MCP server — scoped auth, per-tool allow/deny policies, rate limiting, and a redacted audit trail. One command.
npx yamcp serve --config yamcp.config.json
The problem
Your customers' AI agents (Claude, ChatGPT, coding assistants) want to call your API — but exposing an API to an autonomous agent is not the same as exposing it to a developer:
- Every MCP server you find on GitHub skips security. No caller auth, no audit trail, no way to say "agents may read, never delete."
- Enterprises block agent access outright because there is no scoped access, no logging, and no rate control between the model and the API.
- Building it yourself means learning the MCP protocol, mapping your OpenAPI operations to tools by hand, and maintaining it as both evolve.
yamcp closes that gap: point it at the OpenAPI spec you already have, and it serves a policy-enforced MCP server in front of your API.
How it works
Every tool call flows through a fixed pipeline — there is no way around it:
MCP client ──▶ inbound auth ──▶ allow/deny policy ──▶ rate limit ──▶ schema validation ──▶ upstream API
│
audit log (JSONL, secrets redacted) ◀──────────┘
- Operations → tools, automatically. Each OpenAPI operation becomes an MCP tool with a JSON Schema derived from its parameters and request body. Arguments are validated before anything touches your API.
- Credentials never reach the model. Upstream API keys are referenced by environment-variable name and injected server-side. Config files contain no secrets, and
Authorizationinputs are stripped from tool schemas. - Deny means invisible. Tools removed by policy or scope are not listed to the client at all — an agent cannot ask for what it cannot see.
- Everything is on the record. Every call — allowed, denied, rate-limited, or failed — is one JSONL line with caller, decision, latency, and redacted arguments.
Quickstart (30 seconds)
# 1. Generate a config from your spec (lists every derived tool in an allowlist)
npx yamcp init --spec ./openapi.yaml
# 2. Trim the allowlist, set your upstream base URL, then check the result
npx yamcp list --config yamcp.config.json
# 3. Serve
export UPSTREAM_TOKEN=... # if your API needs auth
npx yamcp serve --config yamcp.config.json
Use it from Claude Code / Claude Desktop
claude mcp add my-api -- npx yamcp serve --config /path/to/yamcp.config.json
or in claude_desktop_config.json:
{
"mcpServers": {
"my-api": {
"command": "npx",
"args": ["yamcp", "serve", "--config", "/path/to/yamcp.config.json"],
"env": { "UPSTREAM_TOKEN": "..." }
}
}
}
Configuration
{
"spec": "./openapi.yaml",
"upstream": {
"baseUrl": "https://api.example.com",
// Secrets are env-var references — never literals in this file.
"auth": { "type": "bearer", "tokenEnv": "UPSTREAM_TOKEN" },
},
"policy": {
"mode": "allowlist", // or "denylist"
"allow": ["get*", "list*"], // "*" wildcards
"deny": ["deleteUser"], // deny always wins
"readOnly": false, // true = GET/HEAD operations only
},
"rateLimit": {
"global": { "rps": 10 },
"perTool": { "createOrder": { "rps": 1, "burst": 2 } },
},
"auth": {
// Inbound auth for --http mode (stdio inherits the host process's trust).
"http": {
"tokens": [
{ "tokenEnv": "YAMCP_READ_TOKEN", "scopes": ["read"] },
{ "tokenEnv": "YAMCP_ADMIN_TOKEN", "scopes": ["read", "write"] },
],
"scopeMap": {
"read": ["get*", "list*"],
"write": ["create*", "update*"],
},
},
},
"audit": {
"destination": "./audit.jsonl", // or "stderr"
"redactFields": ["ssn", "card_number"], // merged with built-in defaults
},
}
Remote mode (Streamable HTTP)
npx yamcp serve --config yamcp.config.json --http --port 3000
- Callers authenticate with bearer tokens; each token's scopes control which tools it can see and call. Two callers get two different tool lists.
--httprefuses to start withoutauth.httpconfigured — secure by default.- Token comparison is constant-time; tokens themselves live in environment variables.
CLI
| Command | What it does |
|---|---|
yamcp init --spec <path> |
Generate a config scaffold with every derived tool in an allowlist |
yamcp validate --config <path> |
Validate config + spec without starting a server |
yamcp list --config <path> |
Show every tool and its effective policy decision |
yamcp serve --config <path> [--http] [--port N] |
Start the MCP server (stdio by default) |
Example
A runnable petstore example lives in examples/petstore/ — the audit log below is what one session against it looks like:
{"ts":"2026-07-15T07:25:27.680Z","tool":"getPet","caller":"stdio","decision":"ok","args":{"petId":"42"},"upstreamStatus":200,"latencyMs":99}
{"ts":"2026-07-15T07:25:27.697Z","tool":"deletePet","caller":"stdio","decision":"denied"}
Current limitations
- Request bodies must be
application/json(operations with form/multipart bodies are skipped with a warning at startup). - Rate limits are in-memory and per-process — the right shape for MCP's process-per-client model, not for a fleet behind a load balancer.
- Upstream auth is static bearer/API-key via env vars; OAuth flows to the upstream are on the roadmap.
Security model
See SECURITY.md for the threat model and design decisions.
Development
npm install
npm run build
npm test # 55 tests: unit + end-to-end over in-memory and HTTP transports
MIT © yamcp contributors
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.