higgs is an agent-first CLI for Proton Mail. A schema manifest instead of --help prose, NDJSON on stdout, typed error envelopes, and a stable exit-code enum — designed to be driven by a language model, not parsed by regex.
$ brew install higgscli/higgs/higgs
Stdout mixes prose and data, errors are English sentences, exit codes are 0-or-1, and the only tool spec is --help. higgs inverts every one of those assumptions: the primary caller is a model.
higgs schema once. A JSON manifest of every subcommand: flags, args, stdout format, exit codes. The schema is the prompt.{"type":"summary"}. One object per line, a guaranteed terminator. No heuristics..error.kind. Typed envelopes with kind, code, reason, message, hint. The envelope is the branching logic.5 imap, prompt the user on 2 auth, surface on 4 config.Everything an agent needs to discover, drive, recover, and branch — built into the binary, not into your system prompt.
$ higgs schema classify { "name": "classify", "summary": "Classify messages with Ollama…", "args": [{"name":"mailbox","default":"INBOX"}], "flags": [ {"name":"dry-run","type":"bool"}, {"name":"apply","type":"bool"}, {"name":"limit","type":"int","default":100} ], "stdout": "ndjson", "exit_codes": [0,2,3,4,5,6,7,9] }
$ higgs classify --apply INBOX { "error": { "kind": "auth", "code": 401, "reason": "authFailed", "message": "IMAP authentication failed", "hint": "Check PM_IMAP_PASSWORD matches Bridge" } } # exit 2 → agent prompts the user, not the void
# stdout: data. stderr: sanitized human progress — # ANSI escapes, bidi controls, zero-width chars stripped, # safe to feed back into a model's context. {"uid":1842,"suggested_labels":["Orders"]} {"uid":1843,"suggested_labels":["Finance"]} {"type":"summary","classified":2,"errors":0}
| Exit | Kind | Agent strategy |
|---|---|---|
| 0 | success | Parse stdout, continue |
| 2 | auth | Prompt user for credentials |
| 3 | validation | Fix flags or args, retry |
| 4 | config | Surface missing config |
| 5 | imap | Retry with backoff |
| 6 | classify | Check Ollama, retry |
| 7 | state | Inspect the state DB |
| 9 | internal | Escalate to user |
Any command that accepts --uid also accepts --uid -: it reads the UID set from stdin — plain UIDs or NDJSON, from which each row's uid field is taken. One command's output is the next one's input, and verify audits the result.
# Archive everything older than July $ higgs search INBOX --before 2025-07-01 | higgs archive INBOX --uid - # Move every non-mailing-list message the classifier saw to Personal $ higgs state query INBOX --is-mailing-list false | higgs move INBOX Folders/Personal --uid - # Then prove the move happened — audit the mailbox against an expected UID set $ higgs search INBOX --before 2025-07-01 | higgs verify INBOX --uid - --expect absent {"type":"summary","checked":312,"violations":0}
The first workload was a local inbox classifier. The contract turned out to be the product — and now the whole mailbox is scriptable by an agent.
searchtyped criteria → NDJSONfetch-and-parsefull messages as JSONthread / threadsconversation groupsattachmentsextract attachment bytesscan-folderslist mailboxeswatchstream change eventsclassifylabel with Ollamaaskagentic Q&A over the mailboxsummarizeNDJSON summariesdigeststructured recent-mail digestextractpull data with a JSON schemamove / archive / trashwith verificationmark-read / flagflip flags in bulkapply-labelswrite classifier resultsunsubscribehonor List-Unsubscribedraft / sendcompose via IMAP/SMTPstate queryquery past classificationsverifyaudit against expected UIDsbackfillrebuild state from logscleanup-labelsconsolidate label setsauthcredentials → OS keyringexportmailbox → mbox / JSONLimportmbox / JSONL → mailboxschemathe manifest itselfcompletionshell autocompletionstdoutalways structured JSONstderrsanitized, model-safeexit codesstable 0–9 enumstatecheckpointed SQLite, resumableMail flows through Proton Mail Bridge on 127.0.0.1. Classification runs through a local Ollama model. Nothing leaves your machine.
The default model is Gemma 4 via Ollama — native function calling, 128K context, fits on a laptop. Swap in any local model you like.
Credentials live in the OS keyring — macOS Keychain, Windows Credential Manager, libsecret — with an AES-256-GCM file fallback. Nothing sensitive flows through an agent's context window.
No analytics, no crash reporting, no update pings. Releases are cosign-signed with an SBOM included. Apache-2.0, fully open source.
Prerequisites for the AI commands: a running Proton Mail Bridge and Ollama. Everything else just needs Bridge.
brew tap higgscli/higgs brew install higgs
go install github.com/higgscli/higgs/cmd/higgs@latest
git clone https://github.com/higgscli/higgs.git cd higgs && make build
# Point higgs at Bridge and Ollama $ export PM_IMAP_USERNAME="alice@proton.me" $ export PM_IMAP_PASSWORD="bridge-generated-password" $ export PM_IMAP_HOST="127.0.0.1" PM_IMAP_PORT="1143" PM_OLLAMA_MODEL="gemma4" # Dry-run against your inbox — preview, apply only when it looks right $ higgs classify --dry-run --limit 20 INBOX $ higgs classify --apply --workers 4 INBOX
Schema-discoverable. NDJSON-native. Locally private. Pipe-composable.