A local mail runtime for you and your agents
Put your whole mail history to work.
A terminal session using a seeded synthetic mailbox. mxr searches mail, pipes JSON through jq, and lists subscription candidates whose counts use messages currently marked READ, not tracked opens.
A keyboard-driven inbox filling the terminal, with a mailbox sidebar, a search across the whole index, and the rules and accounts screens.
An AI agent works the same inbox. It writes mxr search and jq pipelines to find the senders behind phishing attempts, then says which ones to be careful with.
A connector may be all you need to use Gmail inside your agent. Choose mxr when you also want the synced mailbox on your computer, available to your own tools and to clients you can use yourself.
The daemon handles sync, local storage, search and mail operations. A new client can reuse that work instead of rebuilding the mail engine. The web app, TUI, CLI and agent interfaces use the same local mailbox.
try it with synthetic mail
Section titled “try it with synthetic mail”Install mxr, then start the isolated demo mailbox. It uses synthetic mail and a separate profile.
# start the isolated synthetic mailboxmxr demo
# inspect subscription candidates from the local demo mailboxmxr subscriptions --rank --format jsonThe subscription result ranks a limited candidate set. Its opened_count is the number of messages currently marked READ, not a count of tracked opens. Follow the demo steps or use mxr from your agent.
work locally with synced mail
Section titled “work locally with synced mail”Your synced mail stays available.
Mail that has synced into mxr’s local store stays readable and searchable from this machine. Drafts save locally. Sync, sending, and provider-backed changes still need the provider connection; the initial sync can take time.
Attachment names, types, and sizes are part of the local record. mxr downloads attachment contents when you open them; only downloaded files are available locally. Archive can prefetch selected record PDFs under its configured budget.
search synced history on disk
Section titled “search synced history on disk”Synthetic illustration; not a captured search result.
Find a 2019 contract by the supplier’s name. Pull every receipt from a vendor. List the apology email you sent in March. mxr indexes subject, body, sender, and attachment filenames with Tantivy. Lexical search runs against the index on your disk, without a provider round trip or provider rate limit. Optional local embeddings add hybrid and semantic search.
The same local record supports mailbox summaries such as storage by sender or attachment type, response times, stale threads, READ-state subscription counts, and a year-in-review.
mxr storage --by label --limit 20mxr stale --mine --older-than-days 14mxr wrappedmxr search "subject:invoice" --format json | jq -r '.results[].from' | sort -usort mail by what you do with it
Section titled “sort mail by what you do with it”Start on Now for people waiting on you and tasks due soon. Open Messages to reply, To do to act, Updates to check what changed, Reading for newsletters, or Archive to find a receipt or booking reference.
Rules you can inspect do the sorting. Preview a correction before moving mail. Add your own personal categories to group messages without changing their workflow or provider labels.
# see what needs youmxr now
# inspect the modes holding a conversationmxr modes why MESSAGE_ID
# preview a correction, then move this email to Readingmxr reclassify MESSAGE_ID reading --dry-runmxr reclassify MESSAGE_ID readinglet your agent use the same inbox
Section titled “let your agent use the same inbox”Local search and cached-mail reads use state on your computer. Sync, sends, provider-backed changes, uncached attachment downloads, remote articles, and configured model endpoints can still use the network. An external agent supplies its own model; mxr-native model features and the built-in assistant use separate settings. Returned mail sent to a hosted agent model leaves through that service. Agents can use the CLI or first-party MCP server, whose available operations and daemon authority differ.
Illustrative prompts and outcomes, not an observed agent run.
mxr search "from:sarah@example.com OR to:sarah@example.com" --format jsonmxr sender sarah@example.com --format jsonmxr draft-assist <thread-id> "short reply in my usual tone"mxr search "from:ci@github.com after:2026-04-30" --format json | jq -r '.results[] | [.message_id, .subject] | @tsv'git log --since=1.week --pretty='%H %s'mxr search "from:ci@github.com after:2026-04-30 subject:upload" --format ids | mxr archive --dry-runThe CLI, MCP server, web bridge, and TUI call the same daemon operations where supported. Read commands can return structured output; preview support varies by command. Identified MCP and agent requests use their configured profile gates. Ordinary CLI requests use CLI origin, including when a shell-capable agent runs them. See the automation contract →
mxr search "from:sarah@example.com after:2026-04-23" \ --mode lexical --sort relevance --format json | jq '.results[0]'{ "message_id": "MESSAGE_ID", "from": "sender@example.com", "subject": "Subject from the message", "date": "TIMESTAMP_FROM_THE_MESSAGE", "read": false, "starred": false}changes stay in sync
Section titled “changes stay in sync”mxr keeps a local copy and syncs changes in both directions. Read, label, and archive in another client; mxr picks up those changes. Make the same changes in mxr; your provider receives them.
- → read a thread in Gmail web on your phone
- → apply a label in Apple Mail
- → archive a newsletter from your watch
+ IMAP / SMTP
+ IDLE
- ← mxr sees the read state
- ← the label appears in mxr’s sidebar
- ← the newsletter leaves the inbox
Gmail, Outlook, and your IMAP server remain upstream. The synced local archive stays readable on your computer when the provider or network is unavailable.
one mailbox, several interfaces
Section titled “one mailbox, several interfaces”The daemon owns sync, storage, search, rules, and provider connections. The TUI, CLI, web app, MCP server, and agent skill can use the same daemon-backed mail state. Client paths differ in which operations they expose and what authority they receive.
Vim-native keys, Gmail-style chords, full-mailbox search, account setup, rules, and analytics. Compose in $EDITOR.
mxrSearch, read, draft, send, and manage mail from scripts or one-off commands. Pipe JSON through jq, xargs, or anything else in your shell.
mxr archive --search "from:noreply@example.com older_than:30d" --dry-run
would archive 142 messages.mxr web opens the browser app on the desk, through the local HTTP and WebSocket bridge. The same bridge publishes OpenAPI and can support another client.
curl -H "Authorization: Bearer $TOKEN" \
"http://mxr.localhost:42829/api/v1/mail/search?q=is:unread"
{"results": [...]}Run mxr mcp serve for typed MCP tools, or give a shell-capable agent the mxr skill. Identified MCP requests can use an MCP profile; CLI requests use the CLI origin and do not inherit an agent profile just because an agent runs them.
mxr mcp servedaily mail tools
Section titled “daily mail tools”install
three methodsHomebrew
brew install planetaryescape/mxr/mxrCargo
cargo install --git \ https://github.com/planetaryescape/mxr \ --locked mxrmxr demo uses a separate config, database, and daemon. It seeds 50,000 messages across two accounts and warms search and analytics before opening the TUI.
documentation
Section titled “documentation”Built in Rust as one binary for the supported macOS and Linux release targets. There is no telemetry and no mxr-operated server between you and your mail provider. If you use mxr and like it, star the repo so more people can find it. Contributions are welcome across provider adapters, clients, CLI commands, documentation, and tests.