@delegus/agent-proxy
v0.2.0
Published
A local proxy that signs Delegus Grant and Proof headers for every MCP tools/call an agent makes, so an MCP client with static configuration (Claude Code, Claude Desktop, any IDE) can be the agent behind a Delegus-guarded MCP server. Holds the agent key a
Readme
@delegus/agent-proxy
The agent side of a Delegus-guarded MCP endpoint, for MCP clients that cannot
sign: Claude Code, Claude Desktop, IDE clients. Their MCP configuration carries
static headers; a Delegus Proof is per request (a nonce, the time, the exact
tool and arguments). This proxy sits on localhost between the client and the
guarded endpoint, holds the agent's key and the customer's Grant, and signs
Delegus-Grant and Delegus-Proof for every tools/call. Everything else
is forwarded unchanged.
agent client (Claude Code) ──► delegus-agent-proxy (localhost) ──► delegus-mcp-gateway ──► your MCP server
signs per call one call to Delegus per tools/callRun it
delegus-agent-proxy --endpoint https://tools.example.com/mcp \
--agent-key agent.jwk --grant grant.jwsThen point the client at http://127.0.0.1:8787/mcp. In Claude Code:
claude mcp add --transport http tools http://127.0.0.1:8787/mcp--endpoint: the guarded MCP address, the gateway's--endpoint. The proxy signs for exactly this address, so the two cannot disagree.--agent-key: the agent's private JWK fromdelegus agent create(mode 0600).--grant: the Grant the customer signed to that agent, as a file holding the compact JWS. Both come from files, never flags.- Optional:
--port(default 8787),--host(default 127.0.0.1; anything else prints a warning, because whoever reaches the port acts as the agent),--rp <did:web:…>(otherwise discovered),--forward-to <url>when the endpoint's public address is not reachable from this machine (a local gateway: the request goes there with the endpoint'sHost).
At startup the proxy checks that the Grant names the key it holds, learns the
relying party and the tool map from the endpoint (one credential-less
tools/call, refused there with MISSING_CREDENTIALS and no receipt), and
refuses to start, in words, when the endpoint does not answer as a
Delegus-guarded MCP endpoint or the Grant's audience excludes it. With a tool
map the arguments are bound into the Action as the map says; without one, the
tool is bound and its arguments are not (the gateway's documented limit).
Each tools/call is logged as one JSON line: the tool, the status, the
receipt id the endpoint returned, the decision. The proxy decides nothing:
the gateway asks Delegus and the client sees the same Delegus-Receipt-Id
header and the same 403 with the Delegus reason that any agent would.
First run on a new machine
Give the proxy an enrolment token and a name instead of a key: --agent-key
agent.jwk --enrol-token dk_enrol_… --name ops-agent. When agent.jwk doesn't
exist yet, the proxy makes the key (mode 0600), adds the agent to the company's
agent list, and stops. The agent waits there, pending, until an admin approves
it. Start the proxy again with a Grant once it is approved. --api-url points
at a Delegus API other than https://api.delegus.ai.
Limits
- One agent, one Grant per process. Run one proxy per customer Grant.
- The agent key on this machine is the agent. Treat the JWK like any credential; a leaked key plus Grant acts until the customer revokes.
- Streamable HTTP only, like the gateway.
