MOLTED EMAIL
CLI Reference

molted doctor

Can this key send yet, and why isn't mail flowing? Renders GET /v1/agent/setup plus the after-send checks. Exit code: 1 if any blocker is found (not ready to send); otherwise 2 if any check could not be fully verified; otherwise 0 -- 0 means ready to send and every check fully verified, safe to gate a script on.

Agent context

The "can I send?" checks run server-side, in GET /v1/agent/setup (the same checklist the MCP setup_status tool returns): credentials, plan, holds (account pause, quota, inbound hold), mailbox, sending_domain, policy (what the send path would do with a first send, from the mailbox's real autonomy level) and first_send. Doctor renders each step as a check (a blocked or open step is a blocker; first_send is the goal, never a blocker) and leads with the next step and whose move it is. It then runs the after-send checks concurrently: held approvals, recent policy blocks, DLQ, alerts. A check that needs a scope the current key doesn't have (operator for held approvals and alerts, an all-mailbox key for the DLQ, or a mailbox outside the key's scope) reports "skipped", not "error". A check whose call
fails outright reports "error"; one that ran but couldn't classify its result reports "unknown" -- neither is treated as healthy.

molted doctor
# → READY TO SEND / NOT READY TO SEND YET, the next step, and every check

molted doctor --mailbox 3f1e0c2a-8b7d-4a3e-9c1f-2b6a7d8e9f01
# → checks that one mailbox (and narrows held approvals to it)

molted doctor --json
# → { "setup": { "readyToSend": false, "next": { "step": "plan", "owner": "human", "do": "...", "request"?: {...} },
#                "steps": [...] },
#     "blockers": [{ "check": "...", "detail": "...", "fix": "..." }],
#     "checks": [{ "name": "...", "status": "ok|blocker|warning|skipped|unknown|error",
#                   "detail": "...", "fix"?: "..." }] }

Exit code: 1 if any blocker was found (not ready to send); otherwise 2 if any check reports "error" or "unknown"; otherwise 0. 0 means ready to send and every check fully verified -- scripts can gate on it:

molted doctor --json > /dev/null || echo "blocked, or not fully verified -- see molted doctor"

A skipped check (missing scope, or a mailbox outside the key's scope) does NOT affect the exit code on its own -- it's a permissions gap on this key, not evidence of a problem -- but the human-readable report says "N check(s) skipped" instead of claiming every check was fully verified. One exception: a --mailbox this key may not send from makes the setup check a blocker (exit 1), since that answers "can I send?". A malformed --mailbox (not a UUID) exits 2, not 1 -- 1 is reserved for an actual diagnosed blocker, and no check even ran.

This command calls no write endpoint. The setup check is read-only; checking alerts may notify configured alert destinations (deduplicated). Every fix it prints that would loosen a protection (unpausing, resuming a paused account, choosing a plan) says it is a human call rather than running it.

Related: molted adopt, molted billing, molted budget, molted mailboxes, molted domains, molted overrides, molted analytics

Commands

molted doctor

Can this key send yet, and why isn't mail flowing? Renders GET /v1/agent/setup plus the after-send checks. Exit code: 1 if any blocker is found (not ready to send); otherwise 2 if any check could not be fully verified; otherwise 0 -- 0 means ready to send and every check fully verified, safe to gate a script on.

molted doctor [options]
OptionDescriptionDefault
--mailbox <id>Check one mailbox (UUID) the key may send from; also narrows held approvals
--jsonPrint { setup, blockers, checks } as JSON instead of a human-readable report

See CLI overview for global options, credentials and output format.