From Sendmux
Reads, searches, counts, syncs, triages, files, deletes, threads, and replies to messages in a single Sendmux mailbox using an smx_mbx_ key or scoped smx_agent_ token.
How this skill is triggered — by the user, by Claude, or both
Slash command
/sendmux:sendmux-mailbox-agentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill for mailbox-scoped workflows with an `smx_mbx_` key or scoped `smx_agent_` token: read, search, triage, reply when allowed, and sync one mailbox.
Use this skill for mailbox-scoped workflows with an smx_mbx_ key or scoped smx_agent_ token: read, search, triage, reply when allowed, and sync one mailbox.
sendmux-management.smx_agent_ tokens as read/receive only. They do not have email.send; owner-approved app-resource smx_agent_ tokens may send from their assigned mailbox when the token includes email.send.mailbox_id on mailbox calls; otherwise omit it.| Task | Preferred call |
|---|---|
| Identify the mailbox | mailbox_get_me, CLI mailbox:me:get, SDK mailboxGetMe. |
| Count matching messages | mailbox_count_messages, CLI mailbox:count-messages, SDK mailboxCountMessages. |
| Search text | mailbox_search_message_snippets, CLI mailbox:search-message-snippets, SDK mailboxSearchMessageSnippets. |
| Read known IDs | mailbox_batch_get_messages, CLI mailbox:batch-get-messages, SDK mailboxBatchGetMessages. |
| Mark, flag, or label many messages | mailbox_batch_update_messages, CLI mailbox:batch-update-messages, SDK mailboxBatchUpdateMessages. |
| Delete many messages | mailbox_batch_delete_messages, CLI mailbox:batch-delete-messages, SDK mailboxBatchDeleteMessages. |
| Reply/send from this mailbox | mailbox_send_message, CLI mailbox:send-message, SDK mailboxSendMessage. |
| Upload/read attachments | mailbox_upload_attachment, mailbox_get_attachment, and sendmux-attachments for zero-context files. |
| Threads | mailbox_list_threads, mailbox_get_thread, mailbox_list_thread_messages. |
| Folders | mailbox_list_folders; inspect folders before filing or moving messages. |
| Broad sync | mailbox_get_changes, CLI mailbox:get-changes, SDK mailboxGetChanges. |
| Filtered message sync | CLI/SDK mailbox:query-message-changes / mailboxQueryMessageChanges. MCP does not curate this yet. |
| Live mailbox events | CLI/SDK mailbox:stream-events / mailboxStreamEvents. MCP does not curate this yet. |
Use this sequence for most "find messages about X" tasks:
limit.CLI:
SENDMUX_API_KEY="$SENDMUX_MBX_KEY" sendmux mailbox:count-messages \
--query q=invoice \
--query is_unread=true \
--json
SENDMUX_API_KEY="$SENDMUX_MBX_KEY" sendmux mailbox:search-message-snippets \
--query q=invoice \
--query is_unread=true \
--query limit=10 \
--json
SENDMUX_API_KEY="$SENDMUX_MBX_KEY" sendmux mailbox:batch-get-messages \
--body '{
"ids": ["eml_abc", "eml_def"],
"body_mode": "clean_json",
"max_body_chars": 4000,
"strip_quotes": true,
"strip_signature": true,
"include_attachments": "metadata"
}' \
--json
Use the same commands by putting a scoped smx_agent_ token in SENDMUX_API_KEY when the operation is within its scopes.
SDK:
import {
createMailboxClient,
mailboxBatchGetMessages,
mailboxCountMessages,
mailboxSearchMessageSnippets,
} from "@sendmux/mailbox";
const client = createMailboxClient({ apiKey: process.env.SENDMUX_API_KEY! });
const count = await mailboxCountMessages({
client,
query: { q: "invoice", is_unread: true },
});
const snippets = await mailboxSearchMessageSnippets({
client,
query: { q: "invoice", is_unread: true, limit: 10 },
});
const messages = await mailboxBatchGetMessages({
client,
body: {
ids: snippets.data.snippets.map((item) => item.message_id),
body_mode: "clean_json",
max_body_chars: 4000,
strip_quotes: true,
strip_signature: true,
include_attachments: "metadata",
},
});
Use batch mutations for more than one message. Get user confirmation first.
Mark or label messages:
SENDMUX_API_KEY="$SENDMUX_MBX_KEY" sendmux mailbox:batch-update-messages \
--body '{
"ids": ["eml_abc", "eml_def"],
"seen": true,
"flagged": false,
"keywords": {
"agent_triaged": true,
"needs_reply": false
},
"if_in_state": "state_from_prior_read"
}' \
--json
Delete messages only after explicit confirmation:
SENDMUX_API_KEY="$SENDMUX_MBX_KEY" sendmux mailbox:batch-delete-messages \
--body '{
"ids": ["eml_abc", "eml_def"],
"permanent": false,
"if_in_state": "state_from_prior_read"
}' \
--json
permanent: false moves messages to Trash. Treat permanent: true as irreversible and ask for explicit confirmation.
Before composing, read the identity:
mailbox_get_identity
Then send from the authenticated mailbox. Use Idempotency-Key for retries.
SENDMUX_API_KEY="$SENDMUX_MBX_KEY" sendmux mailbox:send-message \
--idempotency-key "$IDEMPOTENCY_KEY" \
--body '{
"to": [{ "email": "[email protected]", "name": null }],
"subject": "Re: Your message",
"html_body": "<p>Thanks for the update.</p>",
"text_body": "Thanks for the update."
}' \
--json
Mailbox send uses to as an array. subject and to are required. from is optional when sending from the authenticated mailbox identity.
For attachments, route to sendmux-attachments.
Prefer zero-context file flows:
mailbox_upload_attachment with file_path, then send with the returned blob_id.PUT the file without an API key, then send with the returned blob_id.sendmux mailbox:send-message --attach ./report.pdf.Mailbox upload paths share a 7,500,000 byte per-attachment cap. For larger files, split them or send a link to externally hosted content.
Inline base64 is only for tiny generated files. If you already have a blob, send it as:
{
"filename": "report.pdf",
"content_type": "application/pdf",
"blob_id": "blob_..."
}
mailbox_list_threads with small limit for conversation-level scanning.mailbox_get_thread for one thread summary.mailbox_list_thread_messages for message summaries in a known thread.mailbox_list_folders before moving or filing messages.CLI examples:
sendmux mailbox:list-threads --query q=renewal --query limit=10 --json
sendmux mailbox:list-thread-messages --path thread_id=thr_abc --query limit=20 --json
sendmux mailbox:folders:list --query limit=100 --json
Use sync endpoints instead of re-listing the mailbox.
Broad mailbox sync:
sendmux mailbox:get-changes \
--query types=messages,folders,threads \
--query messages_since_state="$MESSAGES_STATE" \
--query folders_since_state="$FOLDERS_STATE" \
--query threads_since_state="$THREADS_STATE" \
--query limit=100 \
--json
Filtered message-list sync:
sendmux mailbox:query-message-changes \
--query since_query_state="$QUERY_STATE" \
--query q=invoice \
--query is_unread=true \
--query calculate_total=true \
--query limit=100 \
--json
Store the returned new state token. Follow has_more with the same filters when more changes remain.
401: missing, invalid, or revoked key.403: wrong key surface or missing mailbox permission.404: selected message, thread, or folder does not exist in this mailbox.409: stale state or idempotency conflict; re-read state before mutating.429 or 503: retry according to response headers.sendmux-getting-started.sendmux-send-email.sendmux-attachments.sendmux-management.sendmux-cli.sendmux-token-efficient-usage.npx claudepluginhub sendmux/skills --plugin sendmuxGuides selection of the cheapest Sendmux surface (MCP, CLI, SDK, or HTTP) for email API tasks to minimize token cost and round trips. Covers batch operations, cursor pagination, ETags, and conditional requests.
Manages Apple Mail on macOS: read, search, send, reply, forward, and organize emails and mailboxes via MCP tools.
Evidence-first email workflow: triage, draft, send verification, and confirm messages landed in Sent. Use for organizing, drafting, or proving email delivery.