Concepts
MCP governance
More and more, an agent’s tools don’t live in its own process — they’re behind an MCP server it talks to over JSON-RPC. That server then goes and touches real systems on the agent’s behalf. Governing the agent’s own egress isn’t enough anymore; you have to govern what it asks an MCP server to do, one tool call at a time.
The token rides in the call, not a header
An MCP tool call is a JSON-RPC message, not an HTTP request with headers you can stamp. So auth51 puts the intent token where it belongs — inside the call, under _meta, keyed io.auth51/intent. That binds the token to the specific tool and arguments being invoked, and it travels with the message wherever the transport takes it.
Two hops, and why they differ
There are two links in this chain, and auth51 treats them differently on purpose.
Hop A is the agent asking the MCP server to do something. The token here is a delegation subject: it says “this agent wants this tool, for this reason.” The server receives and relays it, so it isn’t bound to the agent’s key.
Hop B is the MCP server making the real downstream call to satisfy the tool. That token is minted for the server and bound to the server’s own key (proof-of-possession), because the server is the one acting. The chain records who asked (the agent) and who acted (the server), and neither can widen what the other was allowed.
_meta on Hop A (a delegation subject, no cnf). The MCP server mints a fresh Hop-B token, bound to its own key, for the real downstream call.▶What’s in the _meta envelope
MCP reserves _meta on requests for implementation-defined data, namespaced by key. auth51 uses the key io.auth51/intent and places the intent token there, alongside the tool name and arguments already in the JSON-RPC params.
Because the token sits in the message body rather than a transport header, it survives every hop the message takes — stdio, HTTP+SSE, a relay — and it can be checked against the exact tool and arguments it authorizes, not just the connection it arrived on. A token minted for read_file can’t be reused to justify a delete_file in the same session.
The proxy: governance without changing the server
You usually don’t control the MCP servers your agents use. So auth51 ships a small, zero-dependency proxy that sits in front of one. It reads each tool call, applies your policy — allow or deny, per tool — and mints the intent token, all before the call reaches the server. The agent and the server are unchanged; the proxy is the enforcement point in between.
▶Why an inline proxy, not a library
A library would mean modifying every agent and trusting each one to call it. The proxy inverts that: it’s a mandatory chokepoint the tool call must pass through, so governance doesn’t depend on the agent’s cooperation — which matters precisely when a prompt-injected agent is trying to misbehave.
The proxy is where policy and mint happen together: it evaluates the tool and arguments against your grant, and only if the call is allowed does it produce the Hop-A intent token. A denied call never gets a token, so the MCP server never sees an authorized request for it.