Skip to content

A local mail runtime for you and your agents

Put your whole mail history to work.

mxr keeps a synced mailbox on your computer. Search your history, analyse it with a script, or let your agent work with it. You, your tools and mxr's own clients all use the same local mailbox.
$brew install planetaryescape/mxr/mxrOther install methods available
syncGmail · Outlook / Microsoft 365 · any IMAP server
sendGmail · Outlook / Microsoft 365 · any SMTP server
real mxr commands · demo inbox

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.

Use mxr from the TUI, CLI, or your agent. Subscription counts use current READ flags, not tracked opens. See examples →

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.

Install mxr, then start the isolated demo mailbox. It uses synthetic mail and a separate profile.

Terminal window
# start the isolated synthetic mailbox
mxr demo
# inspect subscription candidates from the local demo mailbox
mxr subscriptions --rank --format json

The 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.

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.

~ $ mxr
● read a message already synced locally
● searched the local index
↑ saved a draft locally
◈ provider connection available
✓ sync new mail or send a reviewed draft

Illustrative sequence, not observed command output.

$mxr search "from:supplier@example.com subject:contract has:attachment after:2019"

Synthetic illustration; not a captured search result.

2024-08-12Supplier Co.Contract revision v3, sign by FridayPDF
2023-03-04Supplier Co.2023 framework agreement (signed PDF)PDF
2019-11-22contracts@supplierContract terms · initial draftPDF
2019-09-08Supplier Co.Onboarding contract for reviewPDF

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.

Terminal window
mxr storage --by label --limit 20
mxr stale --mine --older-than-days 14
mxr wrapped
mxr search "subject:invoice" --format json | jq -r '.results[].from' | sort -u

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.

Work through your day, or compare the five modes.

Terminal window
# see what needs you
mxr now
# inspect the modes holding a conversation
mxr modes why MESSAGE_ID
# preview a correction, then move this email to Reading
mxr reclassify MESSAGE_ID reading --dry-run
mxr reclassify MESSAGE_ID reading

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.

◈ prompt
Find the latest thread with Sarah. Look at how I normally write to her, then draft a short reply in the same tone. Do not send it.
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"
Relationship context and recent threads loaded ◈reply suggestion returned; save it as a draft for review in another client.
◈ prompt
Find every CI failure email from last week. Cross-reference with my recent commits and archive the ones whose tests have since been fixed.
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-run
Review the matching messages before deciding what to archive.

The 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 →

◈ example search output shape
Terminal window
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
}

Use mxr with agents → · Run the MCP server →

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.

◈ in your other client
  • → read a thread in Gmail web on your phone
  • → apply a label in Apple Mail
  • → archive a newsletter from your watch
Gmail History API
↕
Outlook OAuth2
+ IMAP / SMTP
↕
IMAP CONDSTORE
+ IDLE
◈ in mxr after sync
  • ← 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.

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.

TUI
◈ default

Vim-native keys, Gmail-style chords, full-mailbox search, account setup, rules, and analytics. Compose in $EDITOR.

mxr
CLI
◈ scriptable

Search, 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.
HTTP
◈ browser-friendly

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": [...]}
MCP / agent
◈ typed tools

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 serve
Compose in $EDITOR. Write Markdown with your own keybindings and plugins. mxr builds and sends the multipart message.
Reader mode. Remove tracking pixels, banners, signatures, and quoted text from the terminal view.
The desk. See replies you owe, promises coming due and threads waiting on others, remind yourself when someone has not replied, and schedule sends.
Mailbox analytics. Inspect response times, stale relationships, subscription activity, and storage by sender or attachment type.
Mail rules. Preview and run rules that label, archive, star, mark, or route matching mail.
Saved searches. Keep useful mailbox queries in the TUI sidebar and rerun them without rebuilding the filter.

install

three methods

Homebrew

Terminal window
brew install planetaryescape/mxr/mxr

Cargo

Terminal window
cargo install --git \
https://github.com/planetaryescape/mxr \
--locked mxr

Binaries

macOS Apple Silicon · Linux x86_64

Download a release asset →

◈mxr demoopen a seeded two-account inbox
◈mxr accounts add gmailuse outlook or imap for another provider
◈mxropen your local inbox

mxr 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.

open source ◈ MIT / Apache-2.0

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.