# Commands: REST & MCP

Every action in Payvy is a command in a single registry. The registry is served two ways, identically:

- **REST:** `POST /api/commands/{name}`
- **MCP:** `POST /mcp` (tools are generated from the registry)

There is no write path outside the registry: the web app is one more caller of the same commands, and a bypass would be invisible to agents — so it isn't allowed by design.

## Actors and keys

Create keys per actor:

```bash
cargo run -- key create --actor robert --kind person
```

- **Person keys** carry the rights of the person they name, including person-only commands.
- **Agent keys** can prepare work: read and enter bills, file documents, signal events, propose workflows and payees. Person-only commands (approve, reject, release, void, accept/decline) refuse agent keys, and agents don't see them in `tools/list`.

People can also sign in to the web app with an emailed link (no passwords); a signed-in person acts with the same rights as their person key.

## Confirmed commands

Anything that moves money or destroys state is **confirmed-tier**: call once to preview (the real command runs and rolls back), then commit with the single-use token returned, bound to exactly the input you previewed. Changing the amount or destination invalidates the token. See [Paying through your bank](https://docs.payvy.com/guide/payments/) for `bill.release` as the worked example.

## Idempotency and events

Payment attempts carry a deterministic idempotency key the bank honours, so retries can't pay twice. Every write returns the new state and appends an event in the same transaction; `bill.created` from an extraction, for example, records which fields a person corrected. Money is integer cents everywhere.

## Example commands

| Command | Actor | Purpose |
| --- | --- | --- |
| `document.list`, `document.get`, `document.extract` | agent or person | Inbox, inspection, model read |
| `bill.create`, `bill.release`, `bill.mark_paid` | create: any; release/mark_paid: person (confirmed) | Enter and pay bills |
| `email.new_address`, `email.address`, `email.list` | person creates | Inbound addresses |
| `bank.connect`, `bank.recipients` | person connects | Mercury setup |
| `vendor.propose_payee`, `vendor.accept_payee` | propose: any; accept: person | Who gets paid |
| `payment.list`, `payment.refresh` | any | Bank payment tracking |

:::note
A full generated command reference is planned alongside the API's stabilization. Until then, the registry in the source (`payvy-domain/src/commands.rs`) is the ground truth, and `tools/list` over MCP enumerates what your key may call.
:::