MCP Auth
MCP (Model Context Protocol) gives AI agents a standard way to call tools. But the protocol has no built-in answer to two questions:
- Who is calling this tool? There is no agent identity in the MCP spec. Any client connected to an MCP server can call any tool.
- What are they allowed to do? There is no delegation or scope mechanism. If you can connect, you can call everything.
MCP Auth solves both problems with self-contained cryptographic proofs attached to every tool call.
The problem
Consider a multi-agent system where a root orchestrator delegates work to sub-agents:
Root Orchestrator
-> Manager Agent (can resolve, search, merge)
-> Worker Agent (can only resolve)Without MCP Auth, the MCP server sees every call the same way - an anonymous JSON-RPC request. It cannot distinguish the root from the worker, cannot enforce that the worker only resolves, and cannot audit who did what.
The solution
Each agent gets an Ed25519 keypair and a did:agent: identity. Authority flows through signed delegation chains:
- The root grants the manager a delegation scoped to
[resolve, search, merge] - The manager narrows and grants the worker a delegation scoped to
[resolve] - When the worker calls an MCP tool, it attaches a proof - the signed invocation plus the full delegation chain
The MCP server extracts the proof, verifies every signature back to the root, checks every caveat, and either allows or rejects the call. No database lookups. No external key resolver. Everything needed for verification is inside the proof.
// Server-side: 5 lines to add auth
import { McpProof, verifyMcpCall } from "@kanoniv/agent-auth";
function handleToolCall(args: Record<string, unknown>) {
const { proof, cleanArgs } = McpProof.extract(args);
if (proof) {
const result = verifyMcpCall(proof, rootIdentity);
console.log(`Verified: ${result.invoker_did} (depth: ${result.depth})`);
}
// use cleanArgs for your tool logic
}How proofs travel
Proofs are attached as a _proof field in the tool arguments. This works today with every MCP transport (stdio, HTTP, SSE) because it uses the existing arguments object - no protocol extension required.
{
"method": "tools/call",
"params": {
"name": "resolve",
"arguments": {
"source": "crm",
"external_id": "123",
"_proof": {
"invocation": { "..." : "..." },
"invoker_public_key": "a1b2c3..."
}
}
}
}The server calls McpProof.extract(args) which returns the proof separately and a clean copy of the arguments with _proof removed. Your tool handler never sees the proof field.
Future: _meta.auth
The _proof field in arguments is a polyfill. The proposed MCP spec extension places proofs in _meta.auth on the request envelope, keeping arguments entirely clean. Both locations will be supported - the library checks _meta.auth first, then falls back to arguments._proof.
How it complements OAuth
OAuth and MCP Auth solve different problems at different layers:
| OAuth 2.0 | MCP Auth | |
|---|---|---|
| Who | Human user -> Server | Agent -> Agent (or Agent -> Server) |
| Trust model | Centralized token issuer | Decentralized delegation chains |
| Transport | HTTP headers (Bearer token) | Embedded in tool arguments |
| Scope | Static scopes on token | Per-call caveats (action, cost, expiry, resource) |
| Offline verification | No (requires token introspection) | Yes (self-contained proofs) |
Use OAuth to authenticate the human user who owns the system. Use MCP Auth to authenticate and authorize the agents operating within it. They compose naturally - an OAuth-authenticated session creates the root keypair, and agents receive delegations from that root.
Transport-agnostic
MCP Auth works identically across all MCP transports:
- stdio - Proofs travel inside the JSON-RPC arguments object
- HTTP + SSE - Same arguments object, same proof field
- Streamable HTTP - Same arguments object, same proof field
The proof format is pure JSON with hex-encoded keys and signatures. No binary encoding, no transport-specific headers. Any language that can parse JSON can extract and verify a proof.
Installation
npm install @kanoniv/agent-authcargo add kanoniv-agent-authpip install kanoniv-agent-authNext steps
- Add Auth to Your MCP Server - Step-by-step integration guide
- Proof Format - McpProof structure and JSON serialization
- Auth Modes - Required, Optional, and Disabled enforcement levels
- Examples - Full working examples with delegation chains
