Skip to main content
The CLI treats agents as first-class users. Where the MCP server gives an agent tools over a protocol, the CLI gives any harness that can run shell commands the same reach: composable, pipeable, and cheap on context.

The Contract

  • JSON without asking. When stdout is not a terminal (which is every agent), commands print the exact API response as one JSON line. Errors are JSON envelopes on stderr with stable code fields and a requestId.
  • Semantic exit codes. 0 success, 1 API or runtime error, 2 usage error, 3 authentication error, 4 confirmation required, 130 / 143 interrupted by SIGINT / SIGTERM. Unknown commands fail hard with no fuzzy “did you mean” to misread.
  • Never hangs. Nothing waits on stdin unless it is a real terminal, and missing input is an immediate exit 2 with the fix in the message. Every request is bounded, response body included: --timeout <duration> (90s, 1500ms, 5m) caps the whole command, retries and pages included, so it fits a tool-call budget. Long-running commands such as emails generate default to their own budget. SIGINT or SIGTERM stops the request in flight.
  • Stable surface. Commands and flags are additive across releases, and the manifest describes the installed build exactly.

Replaying an Unknown Outcome

The API keeps working after the CLI disconnects. So a write that ends in CLI_TIMEOUT, CLI_CONNECTION, CLI_INTERRUPTED or a 5xx may still complete. Its error envelope carries the idempotencyKey it was sent with and a retryCommand that re-runs it with that key, so the API returns the first attempt’s result instead of doing the work twice:
Run retryCommand; never re-run the original command with a fresh key. A 409 IDEMPOTENCY_IN_PROGRESS means the first attempt is still running (the API holds its key for up to 15 minutes): wait, then run retryCommand again. A read that fails this way changed nothing and simply re-runs. The replay needs the API’s idempotency store. While it is degraded, a send refuses with a retryable 503 rather than risk sending twice, but other writes run without the guarantee. So for a write that must not happen twice (creating a brand, say), pass --max-retries 0, and check whether it landed before you run retryCommand.

The Confirmation Protocol

Irreversible commands (campaign sends, deletes, trigger fires, cancels) do not execute in a non-interactive session. They exit with code 4 and print an envelope:
The intended flow: show the summary to your human, and only run the confirmCommand after they approve. Passing --yes yourself is reserved for actions the user already asked for explicitly. Test sends (emails send --test --to you@example.com) are the safe lane and skip the gate.

Discovery for Agents

Prints a JSON manifest of every command: path, summary, flags, safety class, whether it needs confirmation, and the API route behind it. Pair it with brew-cli docs api (the live GET /v1/help catalog) and the served agent guide at https://brew.new/api/v1/llms.txt. The repo also ships a ready-made skill at skills/brew-cli/SKILL.md that teaches Claude Code and compatible harnesses this whole contract in about fifty lines.

A Typical Agent Session

Reads flow freely, generation is metered by credits, and the one real send in the session was a test delivery to your own inbox.

Need Help?

Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:

Search Documentation

Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.

ChatGPT/Claude Integration

Click “Open in ChatGPT” at the top right of any page to explore it further with ChatGPT or Claude.