Skip to main content
Glama

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.

Related MCP server: Contex

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 Authorization inputs 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.

  • --http refuses to start without auth.http configured — 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

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/adamgalmor/yamcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server