MCP gateway
Govern an MCP server's tool calls with no changes to your agent's code.
Drop AxioRank between an MCP client and an MCP server. Every tools/call is
inspected by the same content-risk + policy engine as the SDK before it reaches
the upstream, and written to a redacted audit log. That is governance by changing one
config block.
Local (stdio) servers
For servers your client launches locally, wrap the command with the
@axiorank/mcp-gateway
shim.
- In the dashboard: Outbound → MCP Gateway → Add MCP Server, choose Local (stdio shim), pick the governing agent, and copy the slug.
- Wrap your server command in your client config (
claude_desktop_config.json, Cursormcp.json, …):
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@axiorank/mcp-gateway", "--", "npx", "-y", "@modelcontextprotocol/server-github"],
"env": {
"AXIORANK_KEY": "axr_live_xxxxxxxxxxxxxxxx",
"AXIORANK_SERVER": "github-mcp",
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
}
}
}
}Everything after -- is your upstream server command, launched and managed by
the shim. Only the (server-side redacted) call arguments ever leave your machine.
Environment
| Variable | Required | Default | Description |
|---|---|---|---|
AXIORANK_KEY | ✅ | - | The governing agent's API key. |
AXIORANK_SERVER | ✅ | - | The registered server slug (policy/audit attribution). |
AXIORANK_BASE_URL | https://app.axiorank.com | AxioRank base URL. | |
AXIORANK_FAIL | open | open = forward if AxioRank is unreachable; closed = block. |
Remote (Streamable HTTP) servers
You don't need the shim. Register the server in the dashboard and point your client's HTTP transport at the gateway URL AxioRank generates for it.
Client setup
The dashboard generates these for you (server row → Connect a client), with your server id and slug filled in. The config shape differs per client:
# Remote (HTTP)
claude mcp add --transport http github-mcp "https://app.axiorank.com/api/mcp/<server-id>?k=<url-token>"
# Local (stdio shim)
claude mcp add github-mcp \
--env AXIORANK_KEY=axr_live_... --env AXIORANK_SERVER=github-mcp \
-- npx -y @axiorank/mcp-gateway -- npx -y @modelcontextprotocol/server-githubclaude_desktop_config.json. Claude Desktop launches stdio servers
directly; reach a remote gateway URL through mcp-remote:
{
"mcpServers": {
"github-mcp": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://app.axiorank.com/api/mcp/<server-id>?k=<url-token>"]
}
}
}~/.cursor/mcp.json (or .cursor/mcp.json per project). Remote servers
use a url key; stdio servers use command/args/env:
{
"mcpServers": {
"github-mcp": { "url": "https://app.axiorank.com/api/mcp/<server-id>?k=<url-token>" }
}
}~/.codeium/windsurf/mcp_config.json. Remote servers use serverUrl:
{
"mcpServers": {
"github-mcp": { "serverUrl": "https://app.axiorank.com/api/mcp/<server-id>?k=<url-token>" }
}
}.vscode/mcp.json. Note the top-level key is servers and entries carry an
explicit type:
{
"servers": {
"github-mcp": { "type": "http", "url": "https://app.axiorank.com/api/mcp/<server-id>?k=<url-token>" }
}
}Enforce vs monitor
Each MCP server has a posture. Under monitor the verdict is logged but the
call always forwards; under enforce a denied tools/call is answered with
an isError result the model can read and never reaches the upstream. Roll out
in monitor first, then flip to enforce.
Rotate the URL token
The ?k= token in a remote server's gateway URL is shown once at registration.
If you lose it or it leaks, mint a replacement without changing the server id:
POST /api/mcp-servers/{id}/rotate-token → { "urlToken": "axr_live_…" }In the dashboard that is the server row's Rotate URL token action, which reopens the connect snippets with the new URL filled in. The previous URL stops working immediately (the whole URL is the credential, so there is no grace window), and every client pointed at the old one needs the new URL. The server id does not change, so nothing else about your config moves.
Troubleshooting a 401
The gateway answers every auth failure with the same opaque
401 {"error":"unauthorized"}, on purpose: a distinguishing response would reveal
whether a given server id exists. The precise cause is recorded in your server
logs instead. The usual ones, in rough order of likelihood:
| Cause | What it looks like |
|---|---|
| The key belongs to a different agent than the one governing this server | A valid axr_live_… that works elsewhere |
| The slug was pasted where the server id belongs | The URL segment is not a UUID |
The key is missing gateway:write | The key works for dashboard reads but not the gateway |
The ?k= token is wrong, or was rotated | A URL that used to work |
| The server was revoked | Everything was fine until someone removed it |
A failing header falls back to the URL token
If your client (or a corporate proxy) attaches an Authorization header of its
own, the gateway now still honours a valid ?k= token in the URL rather than
failing on the header alone.
Pin the tool list (rug-pull protection)
A trusted MCP server can quietly add or swap tools after you've wired it in, a "rug pull." Each server carries a tool allowlist that closes that gap:
- An empty allowlist allows every tool (the default).
- A non-empty allowlist is default-deny: only tools matching one of its
glob entries are allowed; anything else is denied, including a newly-appeared
tool. (
*matches one or more characters, like a policytoolPattern.)
The fastest way to lock in a known-good set is to let the server sync its tools through the gateway once, then pin the snapshot:
POST /api/mcp-servers/{id}/pin-tools → { "pinned": 42 }Pinning copies the currently-seen tool names into the allowlist. From then on a
new or renamed tool is denied until you add it explicitly (set toolAllowlist
at registration or via PATCH /api/mcp-servers/{id}). Allowlist denials respect
the server's posture: blocked under enforce, logged-only under monitor.
Resource attributes feed policies
A server's environment (production…) and resourceType (database…) set
here are what Policy v2 resource predicates match on, so "no
prod-database writes" becomes one rule.
Next steps
- Gateway API: the underlying verdict contract.
- Content-inspection engine: what each call is scored against.
- Secrets broker: inject upstream credentials the agent never sees.
- Policies: turn risk and resource attributes into verdicts.
- Shadow AI discovery: find MCP servers you do not govern yet and bring a discovered one under a tool-scoped policy in one click.