Agents & automation
Automation recipes
Copyable patterns for agents and scripts that search, read, sync, draft, send, and organize iCloud Mail without hidden prompts.
These recipes assume the account is already configured. Add --account <name> when you have more than one account.
Sync, then list unread mail
icloud --no-input mail sync
icloud --no-input mail messages list --unread --limit 20 --json
Find unread invoices
icloud --no-input mail search invoice \
--folder inbox \
--unread \
--json
Get the full text of one chosen message
icloud --no-input mail message show msg_… \
--full \
--body-only
This keeps the earlier search small and expands only the message the workflow actually needs.
Save every attachment from a message
icloud --no-input mail attachments list msg_… --json
icloud --no-input mail attachments save-all msg_… --dir ./downloads --json
Prepare a draft for human review
icloud --no-input mail draft create \
--to client@example.com \
--subject 'Project update' \
--body-file response.txt \
--json
Inspect it later:
icloud --no-input mail draft show drf_… --full
Preview a reply without sending
icloud --no-input mail reply msg_… \
--body-file response.txt \
--dry-run \
--json
The dry run is appropriate even when the agent is authorized to send; it lets the workflow inspect recipients and composed content before the outbound side effect.
Send an already reviewed reply
icloud --no-input mail reply msg_… \
--body-file response.txt \
--idempotency-key ticket-482-reply-01 \
--yes \
--json
Persist the idempotency key with the job so a process restart does not invent a duplicate request.
Archive a reviewed search page
Create a frozen selection:
icloud --no-input mail selection create \
--search \
--query newsletter \
--folder inbox \
--scope-folder inbox \
--limit 50 \
--json
Review the exact action:
icloud --no-input mail selection apply sel_… \
--action archive \
--dry-run \
--json
Then use the returned request_hash:
icloud --no-input mail selection apply sel_… \
--action archive \
--request-hash <reviewed-hash> \
--yes \
--jsonl
Keep a process informed about new mail
icloud --no-input mail watch --jsonl
Consume one JSON object per line. The process can stop the watcher normally when its own job ends.
Search iCloud directly, then cache one result
icloud --no-input mail search invoice --remote --folder inbox --json
For a chosen rem_… result:
icloud --no-input mail message show rem_… \
--remote \
--cache \
--full \
--json
The cached result now has normal local message identity for later steps.
Use a request file for shell-sensitive input
search.json:
{
"query": "Q3 contract",
"participant": "legal@example.com",
"unread": true,
"limit": 20
}
icloud --no-input --request-id legal-review-07 \
mail search --input-json search.json --json
Recover from a send error
Do not immediately rerun a fresh send. Keep the returned send_… ID:
icloud --no-input mail operations outbound show send_… --json
icloud --no-input mail sync --reconcile-outbound --json
If the item appears in the safe-retry Outbox, review and retry that exact out_… item. If the send is still unknown, follow Outbox and send recovery rather than guessing.