Skip to main content
Glama

npm mcp-broker: 1.10.0 CI License

mcp-open-api

Turns an OpenAPI spec into a slot of an mcp-broker, validated by a human before it is published, then governed by the broker like any other provider.

binding + OpenAPI spec ──compile──> manifest (JSON, canonical) ──approve, sign──> mcp-open-api host ──provider──> broker slot
                                                                                   │                              │
                                                                                   └── one process per API:       └── authorize, audit,
                                                                                       its secrets, its targets       limits, traceparent

Converting OpenAPI to MCP is not new. A 300-operation spec does not make a good slot, though: operations have to be chosen, renamed, described for an LLM, narrowed with fixed parameters, and tied to a capability and a resource path. That design work is what this project is about, and what makes a REST API safe to hand to an agent.

How it works

  1. Design the manifest on the page. The design page is published on GitHub Pages: https://pandagaume.github.io/mcp-open-api/. It runs entirely in your browser, and nothing is sent to any server. You import a spec (a URL, a Swagger UI or ReDoc page included, a file, or pasted text), choose and tune the operations, check them, dry-run a call, approve each write tool, and sign with your Ed25519 key, which never leaves the page. Then you save <slot>.json, its <slot>.json.sig and the sources.

  2. Declare the slot, like an mcp-cache or an mcp-vault: directly, from a script of your own, or with a process, mcp-open-api serve. Either way the manifest's signature is checked, the manifest is interpreted without generating code, and every call goes through the broker's authorization, audit, limits and trace propagation. The API's credentials stay in your process. The broker knows nothing of manifests.

Related MCP server: TCPcore Governance Kernel

Use

Directly

import { readFileSync } from "node:fs";
import { DirectTransport } from "@cyanmycelium/mcp-broker-provider";
import { McpServerBuilder } from "@cyanmycelium/mcp-core";
import { BrokerAccessGuard } from "@cyanmycelium/mcp-uns";
import { HttpPool, ManifestBehavior, ManifestEngine, buildManifestDeclaration, verifyManifest } from "@cyanmycelium/mcp-open-api";

const manifest = verifyManifest(readFileSync("vannes.json", "utf8"), readFileSync("vannes.json.sig", "utf8"), [readFileSync("keys/ot-team.pub.pem", "utf8")]);

const transport = new DirectTransport("ws://localhost:3000/provider/vannes", { secret });
const engine = new ManifestEngine(manifest, {
    guard: new BrokerAccessGuard(transport.broker, { constraints: "return" }),
    secrets: { otGateway: process.env.OT_GATEWAY_TOKEN },
    allowedTargets: ["https://ot-gw.local"],
    pool: new HttpPool(),
});
const server = new McpServerBuilder().withName(manifest.slot).withTransport(transport).register(new ManifestBehavior(engine)).build();
await server.start();
await transport.broker.declare(buildManifestDeclaration(manifest));

Several manifests make several slots: one transport, engine and server each, sharing the HttpPool.

With a process

npx @cyanmycelium/mcp-open-api serve --config mcp-open-api.json
{
    "broker": { "url": "ws://localhost:3000/providers", "secretEnv": "MCP_OPEN_API_SECRET" },
    "manifests": ["vannes.json", "pompes.json"],
    "trustedKeys": ["keys/ot-team.pub.pem"],
    "allowedTargets": ["https://ot-gw.local"],
    "secrets": { "otGateway": { "env": "OT_GATEWAY_TOKEN" } }
}

The host opens one slot per manifest. manifests is a file, a directory of them, or a list of either. Without a config file, it reads mcp-open-api.json in the current directory.

On the broker

The provider is an entry of the broker's security file, with its own secret and the resources it may declare. Its slots then appear in the policy like any other:

{
    "providers": [{ "id": "mcp-open-api", "secretEnv": "MCP_OPEN_API_SECRET", "subjects": ["service:mcp-open-api"], "allowedResources": ["/site/nord/**"] }],
    "auth": { "slotResources": { "vannes": "/site/nord/vannes" } }
}

Without the page

The page and the CLI share the same compiler, so a binding kept in a repository compiles and signs the same way:

npx @cyanmycelium/mcp-open-api compile vannes.binding.json --out vannes.json
npx @cyanmycelium/mcp-open-api keygen --out keys/ot-team
npx @cyanmycelium/mcp-open-api sign vannes.json --key keys/ot-team.pem

To run the page locally, run npm run build && npm run demo:designer. It serves dist/ui/ with a fake valve API, its Swagger UI-like page, a host config and a key.

As a broker plugin

With mcp-broker 1.10.0 or later, install this package in the deployment's plugin directory and configure the module @cyanmycelium/mcp-open-api/plugin in plugins[]. It serves signed manifests in the broker process through loopback, without adding an OpenAPI dependency to the broker package. See plugin configuration, Docker deployment and verification.

Status

  • Implemented:

    • the binding format (binding-1);

    • the compiler, a pure function that also runs in the browser;

    • the engine: argument validation (RE2), the broker's decision and limits on every call, connection pooling, response cap and projection;

    • signed manifests, served directly or by mcp-open-api serve;

    • the design page, published on GitHub Pages.

  • Not yet: Overlay and Arazzo inputs, MCP resources, secrets read from mcp-vault, a real (not dry) trial from the page.

Design: docs/binding.md and docs/compiler.md.

Requirements

  • Node.js 22 or later for the host (a provider secret travels in a WebSocket handshake header); 20.11 for the compiler alone.

  • An mcp-broker, 1.7.0 or later for the standalone host; 1.10.0 or later for deployment through plugins[]. Development and integration tests use 1.10.0 or later.

  • For the page: a browser with Ed25519 in WebCrypto (current Chrome, Edge, Firefox, Safari).

Development

npm install
npm run build
npm test

License

Apache-2.0. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Turns OpenAPI specs into MCP tools with secure defaults, risk inspection, confirmation gates, response limits, audit logging, and secret redaction.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Compiles YAML adapters or OpenAPI specs into a minimal MCP tool surface that exposes only declared capabilities to agents, with risk-tiered execution, human approval queues, credential brokering, prompt-injection sanitising and NIST AU-3 audit logging. This lets operators put scoped identity, permissions and kill switches in front of any API so agents can call exactly the tools they need and nothing more.
    3
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to discover and call existing OpenAPI services through governed tools, enforcing policy, approval for destructive operations, and credential handling before requests execute.
    1
    Apache 2.0