Compose in your editor
$EDITOR opens with markdown and YAML frontmatter. Your keybindings, your plugins, your muscle memory. mxr handles parsing, markdown-to-multipart conversion, and sending.
brew tap planetaryescape/mxrbrew install mxrcargo install mxrIf you want current main instead of the latest release:
git clone https://github.com/planetaryescape/mxrcd mxrcargo install --path . --lockedWorks with Gmail, IMAP, and SMTP out of the box. One local database, one CLI, all your accounts.
Tools like gog and Google Workspace CLI give you a CLI for email — but only if you use Google. What if you’re on Fastmail? Or your company’s Exchange server? Or you have a Gmail personal account and an IMAP work account? There’s nothing that works across providers with the same power.
mxr is that tool. One binary that syncs Gmail, IMAP, and SMTP into one local database. One CLI that can search, compose, reply, label, archive, snooze, unsubscribe, and export across all your accounts. One interface your scripts and agents can talk to, regardless of what provider sits behind it.
Not a wrapper around provider APIs. Not a DSL you have to learn. A real CLI with --format json, --dry-run, --search for batch operations, and every output piped through stdout. Hack it with Python, Bash, Go, TypeScript — whatever you already use.
Gmail / IMAP / SMTP | v daemon / \ SQLite Tantivy / | \CLI TUI agentsYour coding agent can already write code, run tests, and commit to git. Now it can manage your email too. Install the mxr skill and ask:
This works because mxr isn’t a GUI with an API bolted on. The CLI is the interface. Every operation supports structured JSON output, safe dry-runs, and batch operations via search queries. Your agent doesn’t need screen scraping, browser automation, or a provider-specific SDK — just mxr.
Today, agents use mxr through the CLI and the skill guide. A first-party MCP server is still on the roadmap.
mxr syncs your email to a local SQLite database and indexes it with Tantivy — the same engine behind Quickwit. Opening a message is a local read, not a network call. Search uses BM25 ranking with field-level boosts, plus optional local semantic retrieval when you enable it. Works offline. Your data lives on your machine. No spinners. No loading states.
Compose in your editor
$EDITOR opens with markdown and YAML frontmatter. Your keybindings, your plugins, your muscle memory. mxr handles parsing, markdown-to-multipart conversion, and sending.
Real search engine
Tantivy gives you BM25-ranked, sub-second full-text search across your entire mailbox. You can keep it lexical or opt into local hybrid/semantic retrieval. Saved searches live in the sidebar as programmable lenses. Search is navigation, not a bolt-on filter.
Daemon-backed
The daemon is the system. The TUI is just a thin client. Sync, indexing, rules, and snooze run in the background. Close the TUI — nothing stops.
Provider-agnostic
Gmail, IMAP, SMTP — all normalize into one internal model. Mix providers freely. Add new ones with a clean Rust trait. The conformance suite validates your adapter.
Distraction-free
Reader mode strips tracking pixels, banners, signatures, and quoted text. You see what the email says, not what it’s selling you. One key to unsubscribe.
Build your own client
The daemon speaks JSON over a Unix socket. The TUI is just one client. Build a web dashboard, a mobile bridge, a Raycast extension — anything that can open a socket.
mxr grows out of work that earlier tools already proved mattered. mutt and neomutt showed how good keyboard mail can feel. aerc pushed the terminal UI forward. himalaya made the CLI feel cleaner. notmuch made local indexing hard to ignore. gog and gws made Gmail scripting practical.
| gog / gwc | notmuch | mutt | aerc | himalaya | meli | mxr | |
|---|---|---|---|---|---|---|---|
| Works beyond Google | no | yes | yes | yes | yes | yes | yes |
| Full CLI for every action | partial | search only | no | no | yes | no | yes |
| JSON output for scripting | yes | yes | no | no | partial | no | yes |
| Compose and send from CLI | partial | no | no | no | yes | no | yes |
| Batch operations via search | no | tag only | no | no | no | no | yes |
| Daemon architecture | no | no | no | no | no | no | yes |
| Local database | no | Xapian | no | no | no | optional | SQLite |
| Full-text search engine | no | yes | no | no | no | optional | yes |
| Compose in $EDITOR | no | via Emacs | partial | partial | yes | no | yes |
| Markdown to multipart | no | no | no | no | no | no | yes |
| One-key unsubscribe | no | no | no | no | no | no | yes |
| Rules with dry-run | no | no | procmail | no | no | no | yes |
| Pluggable provider adapters | no | no | no | partial | partial | no | yes |
| Custom client support | no | yes | no | no | no | no | yes |
More detail, including capability matrices, lives on Why mxr.
mxr is MIT / Apache-2.0 dual-licensed. The entire codebase is open. Built with Rust — one binary, no runtime, runs on every platform. No telemetry, no analytics, no “phone home.”
The architecture is designed for contribution: clean crate boundaries, compile-time checked SQL, a conformance test suite for provider adapters, and thorough documentation. Whether it’s a bug fix, a new provider adapter, a CLI improvement, or an idea — we want to hear from you.