.mcp.json with N tokens, the org manages upstreams centrally and hands out one endpoint per use case.
Concepts
Upstreams
The auth flags are mutually exclusive — see Connector identity for which to pick and how per-user accounts work.
In the dashboard, the gateway page has a Quick connect grid of branded cards that pre-fills the registration form so you only supply credentials. Some presets — including Microsoft 365 — are platform-hosted servers you point at with your own OAuth app.
Scope-aware tool exposure
On an OAuth upstream, an attachment that selects all tools exposes only the tools covered by the scopes you configured — a 320-tool upstream narrowed to the handful your scopes actually permit. Tools needing scopes you didn’t request are hidden rather than surfaced only to fail at call time. Explicit tool selections are always exposed, even beyond the configured scopes.- Credentials are encrypted at rest and never returned by the API.
- The tool catalog is synced on add, every 5 minutes, on demand (
sync), and when the upstream signals a tool-list change. The cached catalog keeps serving even when the upstream is down. - When a previously synced tool’s description or schema changes, the gateway records a catalog-change audit event — a defense against tool-poisoning (“rug pull”) attacks.
rm --forceremoves an upstream even when virtual servers still reference it.
Virtual servers
--upstreamis repeatable:"name"selects all of that upstream’s tools,"name:tool1,tool2"selects a subset. Tool allowlists are the composition — build a read-only variant by selecting only read tools.--descriptionis served as the MCPinstructionsfor connecting clients.--bound-grant <upstream>=<type>:<id>pins one pre-consented account for every caller on a per-user OAuth upstream. By default each caller acts as their own account — see Connector identity.- Tool names pass through unmodified unless two upstreams collide, in which case they are prefixed
{upstream}_{tool}. getshows the endpoint, the exposed tool mapping, and any problems.
Connecting clients
claude-code, claude-api, cursor, vscode, windsurf, goose, openai, openapi, custom-gpt. Authentication is your ZWRM API key as a bearer token; any member of the org can connect to any of the org’s virtual servers.
REST / OpenAPI face
Every virtual server is also a plain REST API — same URL space, auth, curation, and audit as the MCP endpoint. This makes gateway tools usable from anything that speaks OpenAPI but not MCP: n8n, LangChain OpenAPI toolkits, generated SDKs, GPT Actions.- Tool input/output schemas embed verbatim in the OpenAPI document — MCP tool schemas are JSON Schema 2020-12, OpenAPI 3.1’s native dialect.
- Results are flattened for REST consumers: text content that parses as JSON is returned as JSON, binary content becomes a
data:URI, a single content item is unwrapped. Add?envelope=fullfor the raw MCPCallToolResult. - A tool that runs and reports an error returns
422— an outcome the caller can act on, not a gateway failure. - Argument bodies are capped at 1 MiB.
zwrm mcp install <server> --client custom-gpt): fetch the OpenAPI schema with curl and paste it into the GPT editor’s Actions configuration, with Bearer auth. The schema importer can’t send headers — the ?token=<key> URL form exists for import-by-URL, but it embeds your API key in the URL, so prefer curl-and-paste or use a key you can revoke.
Agents and the gateway
Agents consume virtual servers as connectors. The key property: upstream credentials never enter the agent VM — the VM holds only a short-lived, revocable gateway token, and the gateway injects the real credentials upstream. Which identity those calls carry is the connector identity policy.Security model
- Two strictly separated credential planes: client → gateway (ZWRM API keys) and gateway → upstream (org-managed credentials or vaulted per-principal grants). Tokens are never passed through in either direction.
- Upstream URLs are validated against private/internal address ranges (SSRF protection), with DNS re-resolution at dial time. The
--allow-privateescape hatch is host-admin only. - Every proxied tool call is audited with tool, upstream, duration, and caller.
The zwrm mcp stdio server
Separate from the gateway, zwrm mcp with no subcommand runs a local stdio MCP server that exposes your autonomous agent runs as tools (get_agent_run, list_agent_runs, cancel_agent_run) — useful for letting a local coding agent watch over your ZWRM runs: