Skip to content

planetaryescape/mxr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

116 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

mxr

Local-first email infrastructure.

mxr syncs Gmail and IMAP into SQLite on your machine. You read mail in the TUI, script it from the CLI, and hand it to an agent when that helps. Same local data. Same daemon. Same commands.

Today, the shipped surfaces are the CLI, TUI, daemon socket, and agent skill. A first-party MCP server is still on the roadmap.

Install

# Homebrew
brew tap planetaryescape/mxr && brew install mxr

# Pre-built binaries
# https://github.com/planetaryescape/mxr/releases/latest

Cargo install is temporarily unavailable while the crates.io publish path is being fixed. For now, use Homebrew, a release tarball, or build from source:

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

Current release shape:

  • macOS and Linux
  • Gmail sync/send
  • IMAP sync
  • SMTP send
  • lexical + hybrid + semantic search
  • CLI, TUI, daemon socket, agent skill

Why this feels different

mxr connects to your provider directly, syncs mail into a local SQLite database, and indexes it with Tantivy. No hosted relay. No extra control plane in the middle. Your scripts, your terminal, and your agent all talk to the same local runtime.

That makes it a different tool from a classic terminal client and a different tool from a hosted connector layer. mutt, aerc, himalaya, notmuch, gog, and gws each got an important part of this right. Hosted tools like Nylas CLI, Composio, Zapier MCP, and EmailEngine solve a different problem. mxr sits in the middle: local mail runtime, broad CLI surface, daemon-backed state, and structured output.

Operating rules:

  • CLI first. The TUI is built on the same daemon surface and should not be the only way to do something.
  • Mutations should be previewable before commit.
  • JSON is for piping, scripting, and agents, not just debugging.
  • Unix composition beats framework lock-in.
  • Daemon healing is event-driven: stale sockets are cleaned up, mismatched daemon builds are restarted, and bad indexes are repaired or rebuilt. No timed restarts. No self-updates.

Use it from a shell or an agent

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

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

That same surface is what the agent skill uses. A coding agent can search, read, draft, export, and batch-mutate mail through the CLI that already exists.

Example prompt:

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

That works because the CLI is the canonical surface: machine-readable when you need it, interactive when you want it.

Local-first, in practice

  • Search stays local after sync.
  • Opening a message is a SQLite read, not a network round trip.
  • Reader mode keeps HTML-heavy mail readable in the terminal.
  • When you need the original rendering, open it in the browser and keep going.
  • Provider adapters go through a conformance suite instead of one-off glue.

Read ARCHITECTURE.md for the design principles behind the daemon, store, provider model, and trust boundary.

Where mxr fits

The short version:

  • Use mxr if you want local mail state, a broad CLI, a daemon, and one surface that works for both people and agents.
  • Use a classic terminal client if you mostly want an interactive mail UI and don't need a local mail runtime behind it.
  • Use a hosted connector layer if you want managed auth, remote workflows, or lots of SaaS tools behind one endpoint.

Direct mail tools

Tool Good fit when you want... Less central there
mutt / neomutt a long-established terminal workflow local daemon + structured CLI
aerc a modern terminal UI local database + agent-oriented CLI surface
himalaya a clean CLI-first mail client daemon-backed local runtime
notmuch local indexing and search over maildirs provider sync + broad mutation CLI
gog / gws Gmail scripting non-Google provider support
mxr one local runtime for CLI, TUI, scripts, and agents hosted connector workflows

Connector layers and nearby tools

Tool Good fit when you want... mxr difference
Nylas CLI managed provider access + CLI/MCP workflow mxr keeps the runtime local
Composio / Zapier MCP hosted auth + cross-app automation mxr is mail-first, local, and daemon-backed
EmailEngine self-hosted email API for backend systems mxr is for local human + agent workflows
Post a local mail daemon + CLI on macOS mxr aims for cross-provider Rust tooling
email-mcp local MCP access to IMAP/SMTP mxr is a broader mail platform than the bridge alone

Quick start

mxr daemon --foreground
mxr restart
mxr
mxr search "is:unread" --format json
mxr archive --search "older:30d label:notifications" --dry-run
mxr history --category mutation

Docs

Open source

mxr is MIT / Apache-2.0 dual-licensed. The codebase is open. There is no telemetry or phone-home service in the core architecture.

Contributions are welcome, especially around adapters, CLI ergonomics, docs, and tests. The adapter surface is meant to be readable and replaceable, not magical.

Built with

Rust, SQLite via sqlx, Tantivy, Ratatui, Tokio, Stalwart mail-parser, Lettre

License

MIT OR Apache-2.0

About

Local-first, keyboard-native terminal email client

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors