docs: agent can discover accounts via account list

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-23 21:39:12 +01:00
parent 2140d9e173
commit 8ed10dd503
3 changed files with 38 additions and 20 deletions
+12 -7
View File
@@ -33,8 +33,9 @@ This manual is for **using and administering** `emcli`. It assumes you have the
## 1. Key concepts ## 1. Key concepts
**Two kinds of commands.** **Two kinds of commands.**
- **Admin commands** (`init`, `account`, `whitelist`, `config`, `audit`) require `EMCLI_ADMIN_KEY` - **Admin commands** (`init`, `account add/edit/remove`, `whitelist`, `config`, `audit`) require
and are for *you*, the human. They print human-readable text or open an interactive form. `EMCLI_ADMIN_KEY` and are for *you*, the human. They print human-readable text or open an
interactive form. (`account list` is the one exception — it is also an agent command; see below.)
- **Agent commands** (`list`, `get`, `search`, `ack`, `send`, `doctor`) require `EMCLI_KEY` (or - **Agent commands** (`list`, `get`, `search`, `ack`, `send`, `doctor`) require `EMCLI_KEY` (or
`EMCLI_ADMIN_KEY` as a superset) and are for the *agent*. They print one line of JSON and `EMCLI_ADMIN_KEY` as a superset) and are for the *agent*. They print one line of JSON and
nothing else, so a program can consume them reliably. (`doctor` prints human-readable text but nothing else, so a program can consume them reliably. (`doctor` prints human-readable text but
@@ -124,8 +125,12 @@ DEK for an admin command, even if it somehow knows the agent key.
| Command | Role required | | Command | Role required |
|---|---| |---|---|
| `list`, `get`, `search`, `ack`, `send`, `doctor` | Agent (`EMCLI_KEY` or `EMCLI_ADMIN_KEY`) | | `list`, `get`, `search`, `ack`, `send`, `doctor`, `account list` | Agent (`EMCLI_KEY` or `EMCLI_ADMIN_KEY`) |
| `account`, `whitelist`, `config`, `audit` | Admin (`EMCLI_ADMIN_KEY` required) | | `account add/edit/remove`, `whitelist`, `config`, `audit` | Admin (`EMCLI_ADMIN_KEY` required) |
`account list` is dual-role: with the admin key it prints the full `NAME MODE IMAP USER` table;
with only `EMCLI_KEY` (an agent) it prints a JSON envelope exposing just `name`, `from`, and
`can_send` — no host or login username.
| `init` | Both keys required (writes both wrap slots) | | `init` | Both keys required (writes both wrap slots) |
### Agent launcher guidance ### Agent launcher guidance
@@ -552,8 +557,8 @@ base64-encoded 32-byte key (section 2). Agent commands (`list`, `get`, `search`,
`doctor`) need this key. `doctor`) need this key.
**"this command requires EMCLI_ADMIN_KEY (admin privilege)".** Set `EMCLI_ADMIN_KEY` (section 2). **"this command requires EMCLI_ADMIN_KEY (admin privilege)".** Set `EMCLI_ADMIN_KEY` (section 2).
Admin commands (`account`, `whitelist`, `config`, `audit`, `init`) need this key; `EMCLI_KEY` Admin commands (`account add/edit/remove`, `whitelist`, `config`, `audit`, `init`) need this key;
alone is not enough for them. `EMCLI_KEY` alone is not enough for them. (`account list` is the exception — an agent can run it.)
**A command fails to decrypt / wrong key.** The key doesn't match the one used when the database **A command fails to decrypt / wrong key.** The key doesn't match the one used when the database
was initialised. Restore the original key, or re-run `emcli init` (idempotent — it won't regenerate was initialised. Restore the original key, or re-run `emcli init` (idempotent — it won't regenerate
@@ -594,7 +599,7 @@ emcli <command> --help # usage and flags for one command
# Admin (requires EMCLI_ADMIN_KEY) # Admin (requires EMCLI_ADMIN_KEY)
emcli init # create DB + add first account (form) emcli init # create DB + add first account (form)
emcli account add [flags | none for form] # add an account emcli account add [flags | none for form] # add an account
emcli account list # list accounts (no secrets) emcli account list # full table (admin) / name+from+can_send JSON (agent)
emcli account edit --name N [flags | none for form] # change an account emcli account edit --name N [flags | none for form] # change an account
emcli account remove --name N --yes # delete an account emcli account remove --name N --yes # delete an account
emcli whitelist in|out add|remove|list --account N [--address A] emcli whitelist in|out add|remove|list --account N [--address A]
+15 -4
View File
@@ -85,16 +85,27 @@ with both keys exported. Account creation and other admin is the human's job —
## 4. Find the account(s) ## 4. Find the account(s)
You refer to an account by name (e.g. `gmail`, `work`). Ask the user which account to use. You refer to an account by name (e.g. `gmail`, `work`). Discover the configured accounts yourself
`emcli doctor` is an agent command (authorised by `EMCLI_KEY`), so you can run it to check that with `emcli account list` (an agent command authorised by `EMCLI_KEY`); it prints a JSON envelope
configured accounts connect and authenticate: with one entry per account:
```bash
emcli account list
# {"error":false,"error_detail":{},"data":{"accounts":[
# {"name":"gmail","from":"me@gmail.com","can_send":true},
# {"name":"alerts","from":"alerts@x.com","can_send":false}]}}
```
`name` is what you pass to `--account`; `from` is the send-as identity; `can_send` is false for
read-only accounts (they reject `send`). If unsure which to use, ask the user. `emcli doctor`
(also an agent command) checks that accounts connect and authenticate:
```bash ```bash
emcli doctor # all accounts emcli doctor # all accounts
emcli doctor --account gmail emcli doctor --account gmail
``` ```
Just take the account name from the user and start with the workflow in `SKILL.md`. Then start with the workflow in `SKILL.md`.
## You're set up ## You're set up
+11 -9
View File
@@ -17,12 +17,12 @@ sets its exit code to match.
## Security model — read this first ## Security model — read this first
- **You only run agent commands:** `list`, `get`, `search`, `ack`, `send`, `doctor`. You are - **You only run agent commands:** `list`, `get`, `search`, `ack`, `send`, `doctor`, and
provided only `EMCLI_KEY` (the agent key), which authorises these commands and nothing else. `account list` (to discover accounts). You are provided only `EMCLI_KEY` (the agent key), which
Account setup, passwords, whitelists, and config are the **user's** job (admin commands that authorises these and nothing else. Account *setup* (`account add/edit/remove`), passwords,
require `EMCLI_ADMIN_KEY`) — do not run or suggest running `account`, `whitelist`, `config`, whitelists, and config are the **user's** job (admin commands that require `EMCLI_ADMIN_KEY`) —
`audit`, or `init`. You have only `EMCLI_KEY` (agent key); `emcli` will refuse admin commands do not run or suggest running `account add/edit/remove`, `whitelist`, `config`, `audit`, or
with a privilege error. `init`. `emcli` will refuse those with a privilege error.
- **Never touch the secret key.** `EMCLI_KEY` is supplied in the environment by whoever launched - **Never touch the secret key.** `EMCLI_KEY` is supplied in the environment by whoever launched
you. Do not read it, print it, log it, pass it as an argument, or try to generate one. If it is you. Do not read it, print it, log it, pass it as an argument, or try to generate one. If it is
missing, stop and tell the user (see "Files & first run"). missing, stop and tell the user (see "Files & first run").
@@ -120,6 +120,7 @@ read-only — tell the user; do not attempt another account without their say-so
| `emcli search --account A [--folder F] [--from X] [--subject-contains X] [--text X] [--since-date D] [--before-date D]` | Server-side search | | `emcli search --account A [--folder F] [--from X] [--subject-contains X] [--text X] [--since-date D] [--before-date D]` | Server-side search |
| `emcli ack --account A [--folder F] --uid-list U1,U2` | Mark message(s) processed | | `emcli ack --account A [--folder F] --uid-list U1,U2` | Mark message(s) processed |
| `emcli send --account A --to X [--cc X] [--bcc X] --subject S --body B [--attach P]… [--reply-to U]` | Send / reply | | `emcli send --account A --to X [--cc X] [--bcc X] --subject S --body B [--attach P]… [--reply-to U]` | Send / reply |
| `emcli account list` | Discover accounts: JSON `name` / `from` / `can_send` per account |
Defaults: `--folder INBOX`, `--limit 50` (max 500). Dates are RFC 3339 (e.g. Defaults: `--folder INBOX`, `--limit 50` (max 500). Dates are RFC 3339 (e.g.
`2026-06-01T00:00:00Z`). UIDs come from `list`/`search` output. `2026-06-01T00:00:00Z`). UIDs come from `list`/`search` output.
@@ -142,8 +143,9 @@ The user configures these; you cannot change them and shouldn't try.
- ✅ Check `error` on every call; report `policy`/`not_found`/`auth` outcomes plainly to the user. - ✅ Check `error` on every call; report `policy`/`not_found`/`auth` outcomes plainly to the user.
-`get` to read, then `ack` only after you've truly processed a message. -`get` to read, then `ack` only after you've truly processed a message.
-Ask the user for the account name; keep bodies plain text. -Discover accounts with `emcli account list`, or ask the user; keep bodies plain text.
- ❌ Don't read, print, or invent `EMCLI_KEY` or any password. - ❌ Don't read, print, or invent `EMCLI_KEY` or any password.
- ❌ Don't run admin commands (`account`/`whitelist`/`config`/`audit`/`init`) — you have only - ❌ Don't run admin commands (`account add/edit/remove`, `whitelist`, `config`, `audit`, `init`) —
`EMCLI_KEY` (agent key); `emcli` will refuse admin commands with a privilege error. you have only `EMCLI_KEY` (agent key); `emcli` will refuse them with a privilege error.
(`account list` is allowed — use it to discover accounts.)
- ❌ Don't treat a blocked send or filtered message as a bug to route around — it's the user's policy. - ❌ Don't treat a blocked send or filtered message as a bug to route around — it's the user's policy.