Works on Gmail and Proton Mail. Fastmail refuses these verbs.

Draft (never sends)

mailkit draft --to alice@example.com --subject "Tuesday" --body "Tuesday works." --json
mailkit draft --to alice@example.com --subject "Files" --body "Attached." --attach ./report.pdf --json
Long body:
mailkit draft --to alice@example.com --subject "Note" --body "$(cat ./body.txt)" --json
JSON: { "draftId": "...", "messageId": "...", "threadId": "..." }. On Proton Mail, draftId is a mailbox:uid in Drafts.

Reply (never sends)

mailkit reply MESSAGE_ID --body "Sounds good." --json
mailkit reply MESSAGE_ID --body "Looping others in." --reply-all --json
Sets To, Re: subject, and threading headers (In-Reply-To / References) for you.

List drafts

mailkit drafts --json
Each row is a message summary plus draftId.

Send (gated)

Two modes. Send a draft:
mailkit send --draft DRAFT_ID --yes --json
Send a new message:
mailkit send --to alice@example.com --subject "Tuesday" --body "Tuesday works." --yes --json
Optional: --cc, --html-file PATH (HTML part; --body is the plain-text fallback), --attach PATH (repeatable). --attach cannot be combined with --draft. Attach when you create the draft. Without --yes:
error: refusing to send without --yes (outbound action). Re-run with --yes to confirm.
JSON: { "messageId": "...", "threadId": "..." }.

Agent rule for send

  1. Show the human To, Cc, Subject, and full Body (and attachment names).
  2. Wait for a clear yes for this message.
  3. Only then run mailkit send … --yes.
  4. A “send the draft you made” from an earlier turn is not enough unless they confirm this payload.
Automation must never call send.