Skip to content

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:

  1. 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.
  2. 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:

  1. The root grants the manager a delegation scoped to [resolve, search, merge]
  2. The manager narrows and grants the worker a delegation scoped to [resolve]
  3. 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.

typescript
// 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.

json
{
  "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.0MCP Auth
WhoHuman user -> ServerAgent -> Agent (or Agent -> Server)
Trust modelCentralized token issuerDecentralized delegation chains
TransportHTTP headers (Bearer token)Embedded in tool arguments
ScopeStatic scopes on tokenPer-call caveats (action, cost, expiry, resource)
Offline verificationNo (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

bash
npm install @kanoniv/agent-auth
bash
cargo add kanoniv-agent-auth
bash
pip install kanoniv-agent-auth

Next steps

The identity and delegation layer for AI agents.