MCP tool gateway for agents
Agents do their riskiest work when they call tools. The MCP gateway puts Zynth Auth's
authorization engine between your agent and every MCP tool
server: each tools/call is individually authorized, budgeted, and logged before it leaves.
Availability: the gateway is enabled per installation. While it is off, its endpoints —
/api/v1/mcp/serversand/api/v1/mcp/call/*— return 404.Not to be confused with the other two MCP surfaces. Three different things share the
mcpname:
Surface Path What it is This gateway /api/v1/mcp/servers,/api/v1/mcp/call/*Zynth authorizing your agents' outbound calls to your MCP tool servers. Feature-flagged. Zynth's own MCP server POST /api/v1/mcpAn agent operating Zynth Auth itself over MCP. Always on; agent tokens only. Zynth as your MCP authorization server /api/v1/oauth/*Minting audience-bound tokens your MCP server verifies. Probing
POST /api/v1/mcptherefore tells you nothing about this gateway — that path is the first-party MCP server and answers whatever the flag is set to.
Setup (admin)
Everything in this section can also be done from the console's MCP registry page (register a server, set the per-agent call caps, retire a server) — the API calls below are what that page uses.
-
Register the tool server (requires
mcp:servers:manage):curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"name": "github", "upstream_url": "https://mcp.example.com/rpc", "max_calls_per_minute": 30, "max_calls_per_day": 500}' \ https://auth.example.com/api/v1/mcp/serversThe upstream host must also be permitted by the deployment's egress allowlist — two independent chokepoints, both admin-controlled.
-
Allowlist each tool with a reviewed risk score (1–20). Tools not on the list cannot be called — or even seen — by agents:
curl -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"tool_name": "search", "risk_score": 3}' \ https://auth.example.com/api/v1/mcp/servers/$SERVER_ID/tools -
Delegate
mcp:callto the agent, optionally scoped to specific servers/tools with glob patterns:curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"delegate_id": "'$AGENT_ID'", "delegate_type": "agent", "permissions": ["mcp:call"], "oversight_mode": "AUTONOMOUS", "scope": {"mcp_servers": ["github"], "mcp_tools": ["search", "read_*"]}}' \ https://auth.example.com/api/v1/authz/delegations
Calling tools (agent)
The agent sends ordinary JSON-RPC 2.0 to the gateway with its agent token — never to the tool server directly:
curl -X POST -H "Authorization: Bearer $AGENT_TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": "search", "arguments": {"q": "zynth"}}}' \
https://auth.example.com/api/v1/mcp/call/github
Supported methods: initialize, tools/list (filtered to the allowlist), and tools/call.
Every tools/call is checked, in order: tool on the allowlist → delegation scope covers
this server+tool → the agent's rate/budget caps → the full authorization engine (kill switch,
risk ceiling vs. the tool's score, ABAC policies — and, for supervised agents, a
human approval bound to these exact arguments). A denial is a
403 with the reason (or the pending approval_request_id); an unreachable tool server is a
structured 502 — the gateway never fails open.
What you get
- Kill switch that actually stops tool use — engaged mid-session, the agent's very next call is denied.
- No scope escalation across chained calls — authority is evaluated fresh per call from delegation scope; there is no session-wide tool grant.
- Budgets — per-agent, per-server call caps deny (never queue) when exceeded.
- A complete decision log — every allowed and denied call lands in the tamper-evident audit trail with the argument fingerprint, and streams live in the Command Center.