Skip to content

Security & Privacy

mxr is local-first by design.

Mail syncs from the provider into SQLite on your machine. Search runs against the local index. The daemon, TUI, CLI, and agent workflows all operate on that local state. There is no hosted mxr relay in the middle.

  • SQLite is the canonical store
  • Tantivy index is local and rebuildable
  • The daemon runs on your machine
  • The TUI and CLI talk to the daemon over a local Unix socket
  • Sync
  • Send
  • Provider-side mutations like archive, trash, labels, and spam
  • Browser handoff for HTML or unsubscribe pages when needed

That is the intended boundary. The network is for talking to your provider, not to a hosted mxr service.

  • --dry-run on risky mutation commands (including mxr send and mxr unsnooze --all)
  • Interactive confirmation for destructive and batch mutation flows unless --yes is set
  • Undoable mutations: archive, trash, spam, read, read-archive print a mutation_id you can pass to mxr undo for ~60s
  • Persisted mutation history through mxr history
  • Event and log views through diagnostics and CLI commands
  • Plain-text-first reader mode, with browser escape hatch for original HTML

All account credentials are stored in your OS-native secret store, not in plaintext on disk:

  • macOS: Keychain (Keychain Access)
  • Linux: Secret Service (e.g. GNOME Keyring, KWallet)

That includes Gmail OAuth refresh tokens, IMAP passwords, SMTP passwords, and Outlook OAuth tokens. mxr accounts repair NAME re-prompts for the credential and overwrites the keychain entry. The on-disk config.toml only references credentials by password_ref; it never stores the secret itself.

If you previously ran a version older than the keychain migration, your old ~/.local/share/mxr/tokens/*.json files are migrated into the keychain on first startup of the new daemon and then deleted.

  • First-party MCP server
  • Read-only mode for agents
  • Draft-only mode for agents
  • Account-scoped agent permissions
  • Explicit send approval flow
  • Config-based blocking of risky commands

Those are real gaps. The current model is “broad CLI with dry-run and history,” not “fully permissioned agent mail sandbox.”

  • Use --dry-run before any batch mutation.
  • Use app passwords or provider-specific credentials where your provider recommends them.
  • Keep your system keyring clean and scoped to the accounts you use.
  • If an agent is involved, prefer workflows that search, read, export, and draft before workflows that mutate.