The bounded agent
Your agent can’t exceed its budget. And you can prove it.
One command in front of any MCP server. Every tool call is checked against a scope, a budget, and an expiry — and leaves a receipt anyone can verify. Without trusting you, your platform, or your cloud.
# one command in front of any MCP server
$ npx @auths-dev/mcp wrap --budget '$20' --ttl 30m -- my-mcp-server
# the agent runs. every tool call is checked and gets a receipt.
✓ payments.charge $12.00 → allowed · spent $12.00 / $20.00 · rcpt_1a2b
✗ payments.charge $940.00 → usage-cap-exceeded · refused · rcpt_8f2a
# the receipt is signed — anyone can re-derive the spend, offline
$ auths-mcp-gateway verify-spend --log spend.jsonl …
✓ consistent — 2 call(s), $12.00 re-derived from signed costs
Don't trust us. Check.
A log is a claim the operator makes about themselves. A receipt is a claim you can check against them. Each tool call is signed by the agent's delegated key; the spend re-derives from those signatures, so a party who never ran the agent can confirm what it did — offline, with no account and no server to trust.
Tamper with one byte of a signed proof and the audit says so.
# re-derive the spend from the signed receipts alone
$ auths-mcp-gateway verify-spend --log spend.jsonl \
$ --registry ./registry --agent <agent> --root <root>
✓ consistent — 2 call(s), $12.00 re-derived from signed costs
# now flip one byte of a signed proof and re-run
"proof": "9f2c4aa7…e8"
$ auths-mcp-gateway verify-spend --log tampered.jsonl …
It bounds. It doesn't just watch.
AWS, Entra, and Okta can tell you who the agent is. None of them can stop it. The gate checks five things on every call and fails closed — the downstream tool is never invoked on a deny.
| Bound | Refusal | When |
|---|---|---|
| scope ⊆ parent | outside-agent-scope | a call for a capability the grant never gave |
| budget | usage-cap-exceeded | the reservation refuses before the rail is charged |
| expiry | agent-expired | the delegation has a TTL; past it, nothing signs |
| revocation | revoked | the root recorded a revocation; every verifier honors it |
| authenticity | proof-unauthentic | the signature does not verify against the agent’s key |
Scope is ⊆ parent: an agent can only ever narrow what it was delegated, never widen it.
# the agent asks payments.charge for $12.00
✓ payments.charge $12.00 → allowed · spent $12.00 / $20.00 · rcpt_2187
# under the cap — the call goes through, with a signed receipt.
Works with what you have.
No migration, no SDK, no rewrite. Prepend one command to any MCP server line in your client config. The agent keeps working — now bounded.
The gateway speaks MCP up to your agent and down to the wrapped server, proxying tools/list and tools/call and gating each one.
{"mcpServers": {"filesystem": {"command": "npx","args": ["@auths-dev/mcp", "wrap","--scope", "fs.read","--budget", "$5","--ttl", "30m","--","npx", "-y","@modelcontextprotocol/server-filesystem","/path/to/project"]}}}
Revoke, and it stops.
A shared key can't be pulled for one agent without breaking the rest. An Auths agent is a delegated identity of your root — revoke it once and every verifier refuses it on the next call. The other agents never notice.
One command. No key rotation across the fleet. No distribution to wait on.
# the deploy bot is compromised — cut it
$ auths id agent revoke --label deploy-bot
✓ revocation recorded at seq 7 — every verifier honors it
# its very next call, at the gate
$ payments.charge $4.00
✗ revoked — refused (the downstream tool was never called)
# every other agent keeps working
✓ report-bot · fs.read → allowed
How it works.
A device-bound key
The signing key is generated in the machine’s secure element and never transmits. There is no secret to leak, store, or rotate across your fleet.
A delegation, not a token
Each agent is a delegated identifier of your root identity, with its scope and budget fixed at issue time and anchored in a key event log — not a bearer token anyone who holds it can replay.
A signed receipt
Every gated call is canonicalized, signed, and recorded. The verdict and the running spend are re-derivable by anyone with the receipts — the operator’s word is never required.
Why the receipt survives a key rotation.
Other tools can verify offline too. The difference is narrower than “offline vs online,” and worth stating precisely: their offline check runs against a trust-root snapshot you refreshed at some point — so a key that rotated or was revoked since is one you cannot see.
An Auths key carries its own rotation history: the receipt verifies against the key that was valid at signing time, with no trust root to refresh. That matters most for long-lived agent and device keys — which is exactly what Auths issues.
Verified against the key that signed it. Nothing to refresh, nothing to phone home.
Bound your first agent.
Open source, offline-first, no account required.
# wrap any MCP server — the agent keeps working, now bounded
$ npx @auths-dev/mcp wrap --budget '$5' --ttl 30m -- my-mcp-server
# then, as anyone: re-derive the spend from the receipts
$ auths-mcp-gateway verify-spend --log spend.jsonl …
✓ consistent — re-derived from signed costs, offline