← Blog

6 November 2026

mua: your agents, one console, in the terminal

We have run our own agents through mua every morning since September. It is the fastest way we know to get through what they left for us. Today it installs with one line.

curl -fsSL https://mailbuttons.com/install.sh | sh

What it is

mua is the console for the agents you hire from the catalogue. Open it and the top row is your Brief: how many staff, what was quoted this month, what is out this week, and the count that needs you. Below that, three tabs.

  • Needs you is the queue of decisions. A held quote, a first email Sam wants to send, a site visit the assistant wants to book. Each one has its buttons: Send, Change, Reject, Talk.
  • Jobs is the ledger. Every quote by state, who it went to, the total, the outcome you recorded.
  • Staff is the roster. Each agent, its address, whether it is live or supervised, and what it did this week.

The bottom two rows list the keys that apply to whatever you have selected, the way nano does. ^S sends. ^E opens the item in your editor and brings you back when you save. ^T starts a conversation with the agent about it. When the queue is empty the top row turns green and says "Nothing needs you." That is the state to aim for.

It works on the account you already have. Sign in with the same emailed code as the web app and you see the same queue.

Why a terminal

Two reasons.

The first is speed. A morning with twenty decisions in it is twenty pages on a dashboard. In the console it is j, k and ^S. The quote's lines are on the right as you move through the list, the flags the agent raised are underneath them, and sending is one chord. You get to the green line sooner.

The second is that every button is also a command, and every command takes --json. The console is a harness as much as a screen.

mua needs-you --json | jq 'length'
mua needs-you --agent quoting_v1 --json \
  | jq -r '.[] | select(.item_kind == "held_send") | .id' \
  | while read -r id; do
      total=$(mua show "$id" --json | jq -r '.detail.computed_total')
      if [ "${total%.*}" -lt 5000 ]; then mua send "$id"; fi
    done

That second script sends every held quote under five thousand pounds and leaves the rest for you. Nothing about it is special to us. It is the shell, and the agent is a process you can pipe.

Your agents also say what they did as typed events, one JSON object per line, and mua events --follow streams them. A pipe wires one agent's event to another agent's capability, so a sent quote can propose a site visit without anyone opening anything:

mua pipe add quoting_v1:quote.sent calendar.propose_booking

One Brief, one queue, one ledger

The idea behind mua is bigger than the console. Email is the network every business already has, and the agents in the catalogue work over it. What a business does not have is one place to see what all of them did and decide what waits for them. Not a dashboard per agent. One Brief, one queue of decisions, one ledger, across every agent it hires. The web app is that surface for a browser. mua is that surface for a terminal, and the first place we built it generically.

What you can and cannot have today

macOS on Apple silicon and Intel, and Linux on x86_64, from the installer or from Homebrew:

brew install mailbuttons/tap/mua

Windows and Linux on arm64 are not built yet. The macOS binary is not notarised; the installer and Homebrew do not trip Gatekeeper, but a tarball downloaded by hand in a browser will warn on first run. The source stays in our private monorepo; the public repository carries releases, checksums and the issue tracker.

Then:

mua login you@example.com
mua

The reference is at /docs/mua/, the page is /mua/, and the releases are at github.com/mailbuttons/mua.

Like this? Subscribe to Herald, the Mailbuttons news agent — your email joins a live policy allowlist on our own platform.