Spawn a sub-agent in any of today's multi-agent frameworks and look at what
it inherits: your API keys. All of them, at full scope, with no expiry and
no way to take them back short of rotating the key everywhere at once. The
research assistant you spun up to summarize three PDFs holds the same
authority as the orchestrator that spawned it. Nobody designed this; it's
just what falls out when "give the child a credential" means "copy the
parent's."

`grantor-mcp` is the missing layer, shaped as five MCP tools any
MCP-speaking framework can call:

```
npx -y @grantor/mcp serve
```

- **`grant(tools, max_uses, ttl_secs)`** — mint a bounded capability for a
  child identity the broker holds: *these named tools, this many uses, this
  long, nothing else.*
- **`delegate(parent, …)`** — hand a narrowed slice onward. Asking for a
  tool the parent doesn't hold is refused at signing; asking for more uses
  or a longer expiry silently clamps to the parent's bound. A child can
  only ever attenuate — never widen.
- **`check(child_id, tool)`** — the enforcement point, one call per action:
  a real on-chain read (is the root key still enrolled? was the cohort
  revoked? is the tenant's billing live?) plus a local use meter. Returns
  `allow` or a named denial.
- **`revoke(child_id)`** — in your own tenant, a real on-chain revocation
  epoch bump. Every capability in that cohort dies at the next check,
  cryptographically, not by convention.
- **`status()`** — live standing, straight from the chain.

The part that usually takes a paragraph of disclaimers: there is **no
authorization server**. Authority is anchored to a public smart-contract
registry on Base — the delegation chain is signed locally, verified
locally, and the only network dependency is an `eth_call` any RPC can
serve. Nothing to run, nothing to trust, nothing to subpoena.

## Try the whole story in two minutes

The bundled sandbox points at a live shared tenant on the production
registry, so the first run needs no wallet, no account, no config:

```
grant  {tools: ["search","fetch"], max_uses: 3}   → child_id
check  {child_id, tool: "search"}                 → allow, 2 uses left
check  {child_id, tool: "write"}                  → DENIED (CapabilityDenied)
delegate {parent, tools: ["search"], max_uses: 1} → narrower child
revoke {child_id}                                 → done
```

The denial in the middle is the product: an escalation attempt refused by
the capability grammar, not by a prompt asking the model nicely.

Honesty notes, because this page is read by people who check: the sandbox's
signing key is published on purpose — it controls nothing outside the
shared demo tenant. The broker self-issues its anti-replay challenge in
sandbox mode (it is holder and verifier in one process). Use metering is
broker-local, because deed verification is a chain *read* and reads are
unobservable — the chain anchors identity, enrollment, revocation, and
billing. And the whole stack is an unaudited developer preview; the
cryptography it composes is the boring, published kind, but treat it
accordingly.

Production use is one tenant away: a contract call and USDC on Base, no
signup, no server — the [guide](/docs/guide/mcp-broker) walks the whole
path, and your agents can read the
[machine manifest](/.well-known/grantor-onboard.json) themselves.

MCP handles tools. A2A handles agents talking to each other. Grantor
handles what they're *allowed to do*.