Compose
Core model
Section titled “Core model”mxr writes drafts in your editor. The daemon handles parsing, validation, send, save-draft, and provider delivery.
This applies to:
- New compose
- Reply
- Reply-all
- Forward
- Draft editing
mxr composemxr compose --to alice@example.com --subject "hello"mxr reply MESSAGE_IDmxr reply-all MESSAGE_IDmxr forward MESSAGE_ID --to team@example.commxr draftsmxr send DRAFT_IDc: composer: replya: reply allf: forward
If you start from a thread view, reply actions target the focused message, not the latest message in the thread.
Draft format
Section titled “Draft format”Drafts use YAML frontmatter plus body text:
---to: - alice@example.comcc: []bcc: []subject: Example---
Hello from mxr.Reply context
Section titled “Reply context”Reply and forward drafts include message context. If the original message only had HTML, mxr uses the rendered reader output, not raw HTML tags.
Reply recipient
Section titled “Reply recipient”A reply targets the original message’s Reply-To: header when the sender set one, falling back to From: otherwise. This is what mailing lists and no-reply@ senders rely on — a reply to a list digest goes to the list, not the unmonitored sender address. reply-all adds the other original recipients as Cc on top of that target.
Send confirmation
Section titled “Send confirmation”After the editor closes, mxr shows a confirmation modal:
- Changed draft: send, save draft, edit again, discard
- Unchanged draft: edit again or discard
The modal also shows the pre-send safety verdict
(SAFE / WARN / BLOCKED) and any issues found. Blocker issues require a
fix or override token before the s (send) key is enabled.
Pre-send safety
Section titled “Pre-send safety”Every send runs through a six-check safety pipeline: wrong recipient, missing attachment, reply-all sanity, PII/secrets, tone mismatch, and answer-coverage. The pipeline runs in three places:
- The TUI send-confirm modal after
Ctrl-x(changed draft). - The CLI on
mxr send DRAFT_ID(gates the send) andmxr send DRAFT_ID --check(dry-run only). - The scheduled-send flusher when a scheduled send fires.
# Dry-run a stored draft (no provider call). Exit 2 on Blocker.mxr send DRAFT_ID --check --format json
# Same idea, but for a transient draft built from CLI args — no daemon# row created.mxr compose --to alice@example.com --body 'see attached' --check
# If --check turned up a Blocker you accept (e.g. you really do mean# to email competitor.com), it minted a single-use override token.mxr send DRAFT_ID --override-safety OVERRIDE_TOKEN_FROM_CHECKAccount selection
Section titled “Account selection”mxr compose --from work --to alice@example.com --subject "Follow-up"mxr reply MESSAGE_ID --account work --body "Thanks." --dry-runmxr forward MESSAGE_ID --account personal --to bob@example.com --dry-runWhat you get: a new draft from the selected sender, plus reply/forward previews that first confirm the original message belongs to that account.
New compose uses --from <account-or-address> to choose the sender.
Replies and forwards can also take --account <selector> to assert which
account owns the original message before drafting.
The sender address comes from the selected/default runtime account, not from a static status snapshot. This matters for multi-account setups.
mxr drafts --account work --format jsonAttachments
Section titled “Attachments”CLI compose supports:
mxr compose --attach ./invoice.pdf --attach ./notes.txtTUI message viewing supports attachment open/download. Compose-side attachment management is through the editor and CLI.
Snippets
Section titled “Snippets”mxr can store short stock replies for reuse in compose flows. Use
mxr snippets set thanks "Thanks for reaching out, will follow up shortly."
once, then browse or copy it when drafting. Built-in variables:
{first_name}, {date}, {thread_subject}.
mxr snippets listmxr snippets set decline "Thanks for the offer; can't take this on right now." --vars ""mxr snippets remove declineThe TUI exposes a read-only snippets browser via Ctrl-p → Snippets.
Recipes
Section titled “Recipes”# Send a quick reply from the command line, body via heredocmxr reply MESSAGE_ID --body-stdin <<'EOF'Confirmed for Friday at 14:00 GMT.EOF
# Compose with multiple attachments and dry-run before sendingmxr compose --to team@example.com --subject "Q1 numbers" \ --attach ~/work/q1-summary.pdf \ --attach ~/work/q1-charts.png \ --dry-run
# Reply to every flagged "reply later" item in a row, interactivelymxr replies --format ids | while read id; do mxr cat "$id" --view reader read -p "Reply? [y/N/q] " a < /dev/tty case "$a" in y) mxr reply "$id" ;; q) break ;; esacdoneCrash safety
Section titled “Crash safety”A draft you’re editing lives in SQLite. If the daemon dies mid-send,
the row sits in 'sending' state — and the next daemon startup auto-
resets anything older than an hour back to 'draft'. To act sooner:
mxr drafts recover # show orphansmxr drafts resume DRAFT_ID # back to 'draft'; retry with mxr sendmxr drafts discard DRAFT_ID # permanently deleteSee the crash-safe drafts guide for the full state machine.
In real life
Section titled “In real life”- You write better at night, send better in the morning: compose
the draft, save it (
mxr drafts), then send tomorrow withmxr send DRAFT_ID --at 'tomorrow 9am'. - Repetitive client onboarding emails: keep a
;welcomesnippet with{first_name}placeholders. - Composing from a script:
--body-stdinlets you pipe rendered Markdown / templated output straight into a reply without ever opening an editor.
Agent prompts that work
Section titled “Agent prompts that work”"Draft a polite decline to the latest message from acme.com using myprior tone. Don't send — write to a draft so I can review with `mxrdrafts`. Use `mxr draft-assist` for the body.""Schedule a Friday-afternoon nudge to anyone I haven't replied to in 7days. Use `mxr stale --mine --older-than-days 7 --format ids | xargs-I{} mxr remind {} --when 'friday 16:00'`. Show me what would fire."See also
Section titled “See also”- Pre-send safety — the six checks every draft passes through, plus the override-token flow
- Crash-safe drafts
- LLM features — draft assist
- Recipes — compose loops
- CLI — Compose and drafts