Skip to content
machinemail

Mail workflow

Top-level commands for the jobs agents and people do most: send a message, read one with its trust verdict, wait for a message or a verification code, and follow events live. Usage, flags and examples for `machinemail send`, `machinemail read`, `machinemail wait`, `machinemail tail`.

Top-level commands for the jobs agents and people do most: send a message, read one with its trust verdict, wait for a message or a verification code, and follow events live.

CommandSummary
sendSend an email from an inbox
readShow a message: headers, trust verdict and agent-safe text
waitWait for a message to arrive (and extract a code or magic link with —otp)
tailFollow live events (messages, deliveries, inboxes) as they happen

Every command also takes the global flags.

send

Send an email from an inbox.

Sends through POST /v0/inboxes/{inbox_id}/messages/send. The body comes from —text, —html or —file (a .html/.htm file is sent as HTML, anything else as text); pass - to any of them to read stdin. Stdin is never read unless you ask. —from defaults to MACHINEMAIL_INBOX, the profile inbox from machinemail register, or the inbox of an inbox-scoped key.

shell
machinemail send [flags]

Flags

--from <inbox-id>string
Inbox to send from.
--to <address>string[]
Recipient (repeat or comma-separate). Repeat the flag for several values.
--cc <address>string[]
CC recipient. Repeat the flag for several values.
--bcc <address>string[]
BCC recipient. Repeat the flag for several values.
-s, --subject <text>string
Subject.
--text <text|->string
Plain-text body, or - for stdin.
--html <html|->string
HTML body, or - for stdin.
-f, --file <path|->string
Body from a file (.html is HTML), or - for stdin.
--attach <path>string[]
Attach a file (6 MB per request in total). Repeat the flag for several values.
--reply-to <address>string[]
Reply-To address. Repeat the flag for several values.
--label <label>string[]
Label for the sent message. Repeat the flag for several values.
--header <Name: value>string[]
Extra header. Repeat the flag for several values.

Examples

shell
machinemail send --from agent@machinemail.dev --to ada@acme.dev -s "Hello" --text "Hi Ada"
echo "Build passed" | machinemail send --to ops@acme.dev -s "CI" --text -
machinemail send --to ada@acme.dev -s "Report" --file report.html --attach report.pdf

read

Show a message: headers, trust verdict and agent-safe text.

Shows one message with its trust report summary (verdict, score, authentication, flags) and the agent-safe body (trust.content.text: hidden text, zero-width characters, quotes and signatures removed). —original shows the text as the sender wrote it, labelled untrusted; —raw prints the raw RFC 5322 source.

Piped (or with —json) it prints the agent view: headers, the trust verdict, untrusted: true unless the sender authenticated (verified or known), and body: the agent-safe text (body_source says where it came from; quarantined mail is withheld, as the MCP server does). —full prints the whole API object instead, with the original text and HTML. The inbox can be given as —inbox or as the first argument; without it the CLI finds it.

shell
machinemail read <message-id> [flags]

Arguments

<message-id>stringRequired
Message id (msg_...), optionally preceded by its inbox

Flags

--inbox <inbox-id>string
Inbox the message is in (found automatically when omitted).
--originalboolean
Show the original text instead of the agent-safe text (untrusted).
--fullboolean
JSON output: the whole API message (original text and HTML included, untrusted) instead of the agent view.
--rawboolean
Print the raw RFC 5322 message.

Examples

shell
machinemail read msg_01m4g46p1y0000bqmf6m6yv7h5
machinemail read agent@machinemail.dev msg_01m4...
machinemail read msg_01m4... --json | jq -r .body
machinemail read msg_01m4... --json --full | jq .trust

wait

Wait for a message to arrive (and extract a code or magic link with —otp).

Blocks until a new inbound message matching the filters arrives in the inbox, then prints it. Listens on the SSE event stream and polls as a fallback. Only mail received after the command starts counts; —since 5m also accepts mail from the last five minutes (use it when you triggered the email before calling wait).

Piped (or with —json) it prints the agent view of the message: headers, the trust verdict, untrusted: true unless the sender authenticated, and the agent-safe body (withheld for quarantined mail); —full prints the whole API object instead, original text included.

—otp prints only the verification code (or the magic link when there is no code), read from the agent-safe text. It only uses mail whose sender authenticated (trust level verified or known, or a DMARC pass, or an aligned SPF or DKIM pass); —allow-unauthenticated also accepts unauthenticated mail and mail without a trust report, and suspicious or quarantined mail is never used. Unauthenticated mail does reach the inbox (labelled UNAUTHENTICATED), so this check matters. —from matches an address exactly, or a domain and its subdomains (github.com matches mail.github.com, not github.com.example.net). —json prints {code, link, message_id, …} instead. Exits 8 on —timeout.

shell
machinemail wait [flags]

Flags

--inbox <inbox-id>string
Inbox to watch (default: MACHINEMAIL_INBOX or the profile inbox).

DefaultMACHINEMAIL_INBOX or the profile inbox

--from <address|domain>string[]
Sender is this address, or on this domain or a subdomain of it; a bare word matches inside the local part (any of several matches). Repeat the flag for several values.
--subject <text>string[]
Subject contains this, case-insensitive (any of several matches). Repeat the flag for several values.
-t, --timeout <duration>string
Give up after this long: 90, 90s, 5m (default 5m; 0 waits forever).

Default5m

--since <duration|iso>string
Also accept mail received this long ago (5m) or since this time.
--otpboolean
Print only the verification code, or the magic link when there is none.
--linkboolean
With --otp: print the magic link even when there is a code.
--pattern <regex>string
With --otp: extract with this regex (first group, else the match).
--link-domain <domain>string
With --otp: the magic link must be on this domain or a subdomain of it (default: the sender domain).

Defaultthe sender domain

--allow-unauthenticatedboolean
With --otp: also use mail whose sender did not authenticate, or that has no trust report (never suspicious or quarantined mail).
--fullboolean
JSON output: the whole API message (original text and HTML included, untrusted) instead of the agent view.
--pollboolean
Poll only; do not use the event stream.

Examples

shell
machinemail wait --inbox signup-7f3k@machinemail.dev --otp
CODE=$(machinemail wait --inbox "$ADDR" --from github.com --otp --timeout 2m)
machinemail wait --inbox "$ADDR" --subject invoice --json | jq .trust.level
machinemail wait --inbox "$ADDR" --otp --allow-unauthenticated   # e.g. a test sender without SPF/DKIM

tail

Follow live events (messages, deliveries, inboxes) as they happen.

Streams GET /v0/events/stream. On a terminal: one line per event with the trust badge of inbound mail, and a status line. Piped: NDJSON, one {id, event, data} per line. Reconnects on its own and resumes with Last-Event-ID; pass —last-event-id to resume from an earlier run. Ctrl-C stops it (exit 0).

shell
machinemail tail [flags]

Flags

--inbox <inbox-id>string[]
Only these inboxes. Repeat the flag for several values.
--pod <pod-id>string[]
Only these pods. Repeat the flag for several values.
-e, --event-typesstring[]
Only these event types (comma-separated or repeated). Repeat the flag for several values.

Typemessage.received | message.received.spam | message.received.quarantined | message.received.unauthenticated | message.received.blocked | message.sent | message.delivered | message.bounced | message.complained | message.rejected | domain.verified | domain.updated | inbox.created | inbox.expired | draft.sent | webhook.test

--last-event-id <evt_...>string
Replay events after this one first.
--max <n>integer
Stop after n events.

Examples

shell
machinemail tail
machinemail tail --inbox agent@machinemail.dev -e message.received
machinemail tail -e message.bounced,message.complained | jq -c .data.message.to