Skip to content

Local-first email infrastructure.

mxr syncs Gmail and IMAP into SQLite on your machine. Read mail in the TUI. Script it from the CLI. Let an agent use the same local runtime.

Local first, by default

mxr talks to Gmail or IMAP directly, stores mail in SQLite, and indexes it with Tantivy. No hosted relay. No extra control plane in the middle. Your terminal, your scripts, and your agent all work against the same local state.

Try this with an agent:

“Look through unread mail from the last day. Tell me what needs a reply, draft answers for the urgent threads, and leave the rest alone.”

Gmail / IMAP / SMTP
|
v
daemon
/ \
SQLite Tantivy
/ | \
CLI TUI agents

Install

Homebrew

Terminal window
brew tap planetaryescape/mxr
brew install mxr

Build from source

Terminal window
git clone https://github.com/planetaryescape/mxr
cd mxr
cargo install --path crates/daemon --locked

Pre-built binaries

macOS (Intel + Apple Silicon) and Linux x86_64.

Download latest release ->

Today, the shipped surfaces are the CLI, TUI, daemon socket, and agent skill. A first-party MCP server is still on the roadmap. cargo install mxr is temporarily unavailable while the crates.io publish path is being fixed.

Shell first. Agent-friendly.

No SDK. No custom DSL. If a tool can run a command and parse JSON, it can work with mxr.

Terminal window
mxr search "is:unread from:buildkite" --format json \
| jq -r '.[].message_id'

Today, agents use mxr through the CLI and the skill guide. That keeps the current story simple and honest. A first-party MCP server is not shipped yet.

Local mail stays fast

<50msSearch across 10k+ messages
0msOpen a synced message from SQLite
InstantStart a draft in your $EDITOR

Search happens through Tantivy. Reads come from SQLite. Reader mode keeps noisy HTML mail readable in the terminal, and when you need the original layout you can open it in the browser and move on.

What is here today

Compose in your editor

$EDITOR opens with markdown and YAML frontmatter. Your normal editing setup stays in charge.

Daemon-backed

The daemon is the system. The TUI, CLI, scripts, and future clients all talk to the same local runtime.

Provider adapters

Gmail, IMAP, SMTP, and fake adapters normalize into one internal model. The adapter surface is backed by a conformance suite.

Reader mode

Plain text first. Tracking junk, signatures, and quoted walls get stripped down. If the original HTML matters, open it in the browser.

Saved searches and batch ops

Search is not a side filter. It is the navigation model, and it also drives batch work in the CLI.

Build your own client

The daemon speaks JSON over a Unix socket. The TUI is one client, not the only client.

Where mxr fits

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.

Hosted connector layers such as Nylas CLI, Composio, Zapier MCP, and EmailEngine are useful when you want managed auth, remote workflows, or cross-app automation. Nearby local projects like Post and email-mcp are closer in spirit. mxr is for a different center of gravity: keep the mail runtime local, keep the CLI broad, keep the daemon as the shared system.

ToolGood fit when you want…mxr angle
mutt / neomutta long-established terminal workflowmxr puts a local daemon and structured CLI behind the workflow
aerca modern terminal UImxr leans harder into local state and scriptability
himalayaa clean CLI-first mail clientmxr adds the daemon/runtime layer
notmuchlocal indexing over local maildirsmxr also owns sync and mutations
Nylas CLI / Composio / Zapier MCPhosted connector workflowsmxr keeps the runtime on your machine
Post / email-mcplocal mail runtime or bridge workmxr aims for a broader local mail platform

More detail, including capability matrices, lives on Why mxr.

Open source

mxr is MIT / Apache-2.0 dual-licensed. The code is open. There is no telemetry in the core architecture. Provider adapters are meant to be readable and replaceable.

If you want the design logic behind the daemon, the local store, and the provider model, read Architecture.