# Agent sign-up

An AI agent with no browser and no credentials can sign itself up for Quivvo. It gets a code to show its owner, and nothing exists until the owner approves. For the whole setup, including MCP and a verifying run, follow [the setup runbook](https://tryquivvo.com/setup.md).

```bash
command -v quivvo >/dev/null || npm i -g quivvo@latest
quivvo login --agent --no-wait --json
```

That never blocks, so it's safe in a tool call with a short timeout. The first run prints one JSON document and exits 0:

```json
{
  "status": "pending",
  "user_code": "ABCD-EFGH",
  "verification_url_complete": "https://tryquivvo.com/device?code=ABCD-EFGH",
  "expires_in": 86400,
  "message_for_owner": "Please approve my access to Quivvo: open ... and confirm the code ABCD-EFGH. ...",
  "next_command": "quivvo login --agent --no-wait --json"
}
```

Send the owner `message_for_owner` and end your turn. Don't sleep or poll: they may be gone for hours, and the code lasts 24 hours. Run the same command again later. It checks once and exits:

| Exit | Meaning | What to do |
| --- | --- | --- |
| `0` | `status: "approved"`: the key is saved | Carry on |
| `75` | Still pending; the document repeats the code | End your turn and try later |
| `76` | The code expired | Run it again for a new code |
| `77` | The owner denied it | Ask them before trying again |

New accounts wait in a queue for now. Run `quivvo whoami --json`: if `queue.waiting` is true, tell your owner `queue.position` and `queue.invite_url`, and stop.

Add `--name` to label the key, which is `agent@<hostname>` by default, and `--scope` to ask for fewer scopes.

Without `--no-wait`, `quivvo login --agent` prints the same message and waits for approval, which only suits something that can sit still for a long time.

## How does the owner approve it?

The owner opens the link while signed in, checks that the code matches, unticks any scopes they don't want, and approves. From a terminal where they already use Quivvo, they can run:

```bash
quivvo claim ABCD-EFGH
```

That takes a key with `keys:write`. A CLI signs in without it unless they tick it when approving, so the link is the surer way.

The agent then holds an ordinary API key of the owner's workspace, saved in `~/.config/quivvo/credentials.json`.

## What can an agent's key do?

| Scope | Allows |
| --- | --- |
| `machines:read` | Listing and reading machines, history, jobs, files and usage. It reads every ordinary file on a machine, but not `/proc`, `/sys`, `/dev`, `/run` or the daemon's own state |
| `machines:write` | Creating machines, running commands as root, writing files, lifecycle, ports, snapshots |
| `machines:delete` | Deleting machines and snapshots, and setting a deadline for deleting a machine that already exists |

Agent keys can never manage API keys or billing. `quivvo whoami` shows what a key may do. When the answer is that only the owner can do something, the error carries `owner_action` to pass on. The owner can see agent keys under API keys in the dashboard and revoke them at any time. An agent that's finished can revoke its own with `quivvo logout --revoke`.

## How do I do this over HTTP?

1. `POST https://tryquivvo.com/api/v1/auth/device` with `{"kind":"agent","name":"agent@host"}` returns `device_code`, `user_code`, `verification_url_complete`, `expires_in` and `interval`.
2. Show the owner `verification_url_complete` and `user_code`, and keep `device_code` somewhere that survives your turn.
3. Later, `POST https://tryquivvo.com/api/v1/auth/device/token` with `{"device_code":"..."}`, at most every `interval` seconds. You get `authorization_pending` until the owner decides, then `api_key`, or `access_denied` or `expired_token`.

If the answer holding `api_key` got lost, ask again within 10 minutes. You get a new key, and the lost one is revoked. That stops working once the key has been used, or once the owner has revoked it.

## Is there a skill I can install?

Yes. [`/skill.md`](https://tryquivvo.com/skill.md) teaches an agent how to use Quivvo. `quivvo init` installs it, along with the MCP server, for the AI tools it finds on this computer. It shows a checklist first, and changes nothing without `--yes` or a confirmation at a terminal.

```bash
quivvo init --yes --client claude
```
