Agents & automation
Agent guide
A practical operating guide for agents using icloud Mail: discover capabilities, keep reads small, review writes, and recover without guessing.
icloud is designed so an agent can work with Mail through normal commands instead of knowing how iCloud works underneath them.
Start by discovering the installed surface
Do not assume a feature exists because another version had it:
icloud --help
icloud capabilities --json
For a command you plan to use:
icloud mail search --help
capabilities --json also publishes the structured-input and output schemas supported by the installed build.
Prefer compact text for exploration
Normal output is intentionally concise:
icloud mail messages list
icloud mail search invoice
icloud mail threads list
This is usually the best mode when an agent is deciding what to do next. Switch to JSON when a programmatic parser needs exact fields rather than reflexively requesting JSON for every read.
Synchronize before assuming the local view is fresh
A reliable sequence is:
icloud mail sync
icloud mail search invoice
If the task specifically asks for the freshest possible provider search, use:
icloud mail search invoice --remote
A remote rem_… result is a discovery reference. Cache it before using it as a durable local object:
icloud mail message show rem_… --remote --cache --full
Expand content only when needed
List and search commands intentionally avoid dumping complete mail bodies. Follow stable IDs to the exact content you need:
icloud mail message show msg_…
icloud mail message show msg_… --full
icloud mail attachments list msg_…
For conversations:
icloud mail threads show thr_…
icloud mail threads show thr_… --full
Use raw MIME or binary attachment output only when the task genuinely needs exact bytes.
Use stable IDs between commands
Prefer returned IDs over re-identifying mail by mutable display text:
acct_… account
msg_… message
thr_… conversation
att_… attachment
drf_… draft
sel_… reviewed selection
send_… outbound attempt
A common agent flow is:
search → inspect msg_… → inspect attachments → dry-run action → apply action
Review outbound and destructive actions
For send/reply/forward and location-changing actions, use --dry-run first:
icloud mail reply msg_… --body-file reply.txt --dry-run
icloud mail archive msg_… --from inbox --dry-run
Only after reviewing the resolved action should a non-interactive agent use --yes.
For sends and location changes that support it, provide a stable idempotency key:
icloud mail reply msg_… \
--body-file reply.txt \
--idempotency-key customer-reply-01 \
--yes
Never invent a new key just because the command returned a network error. Inspect the recorded operation first.
Freeze search results before bulk writes
Do not run a search, wait, rerun it, and assume the membership is unchanged. Use a short-lived selection:
icloud mail selection create \
--search \
--unread \
--folder inbox \
--scope-folder inbox \
--limit 50
Then review and apply exactly sel_…:
icloud mail selection apply sel_… --action archive --dry-run
Use the returned review hash for the real apply. See Reviewed bulk actions.
Avoid accidental prompts
Agent invocations should normally include:
--no-input
For example:
icloud --no-input --account Personal mail search invoice
If setup needs a credential, provide one of the explicit non-interactive sources from Accounts and credentials.
Use request IDs for multi-step jobs
icloud --request-id ticket-482 mail search invoice --json
A request ID makes logs easier to correlate without changing the Mail operation itself.
Treat retryable as guidance, not permission to duplicate a write
Structured errors include a code and retryability signal. A retryable connectivity failure can still occur around an outbound operation whose final provider state is uncertain.
For sends, keep the send_… ID and follow Outbox and send recovery. For moves/deletes, inspect mutation history and current mail state before repeating a different request.
Prefer one clear command over shell scraping
When a task needs several filters or structured input, use --input-json rather than building brittle quoting:
{
"query": "invoice",
"folder": "inbox",
"unread": true,
"limit": 20
}
icloud mail search --input-json search.json --json
See Output and automation and Automation recipes.