Send one or many emails through Sendmux using approved mailbox or agent credentials, idempotency keys, attachments, MCP, CLI, SDKs, or HTTP.
Integrations
sendmux-token-efficient-usage
Try itChoose low-token Sendmux calls across MCP, CLI, SDKs, and HTTP by using snippets, counts, batches, deltas, cursors, ETags, and idempotency.
What it does
Choose low-token Sendmux calls across MCP, CLI, SDKs, and HTTP by using snippets, counts, batches, deltas, cursors, ETags, and idempotency.
The skill document
Sendmux token-efficient usage
ClawHub account note
This ClawHub skill connects OpenClaw agents to Sendmux. Some workflows require a Sendmux account and an appropriate Sendmux API key or agent token. Sendmux account usage is external to ClawHub; do not ask users to paste secrets into chat.
Use this skill to choose the lowest-cost Sendmux route that still answers the task correctly.
Boundaries
- Do not ask the user to paste an API key.
- Use send-capable
smx_mbx_*keys or owner-approved Sending-resourcesmx_agent_*tokens for Sending calls, andsmx_mbx_*keys for normal Mailbox calls. - Use scoped
smx_agent_*only for the calls its scopes and resource allow. Pre-claim agent tokens cannot send. - Use
smx_root_*for Management calls. - Do not default to MCP for every task. MCP is best when the required tool is curated; CLI and SDK cover broader surfaces.
- Do not pipe real attachments through model context as base64. Route attachment transfer to
sendmux-attachments; preferfile_path, presigned URLs, CLI--attach, or SDK file helpers. Mailbox uploads cap each attachment at 7,500,000 bytes; Sending uploads cap each file at 18 MiB; MCP inline base64 caps at 32 KiB decoded. - Do not read full mailbox bodies, every message, or every log row unless the user asks for full content and narrower calls cannot answer.
Surface choice
| Situation | Use | Why |
|---|---|---|
| Connected agent and curated tool exists | MCP tool | Small schema and no SDK boilerplate. |
| One-off terminal task | sendmux CLI with --json | Direct, scriptable, exposes the full generated operation set. |
| Application code or repeated workflow | SDK for the project already in use | Reuses client setup, pagination, headers, and retry helpers. |
| MCP lacks the needed operation | CLI for terminal work, SDK for code | Do not invent uncurated MCP tools. |
| No package/tooling available | Direct HTTP | Keep request bodies and headers aligned to OpenAPI. |
Cheapest-call map
| Task | Cheapest correct default |
|---|---|
| Send one outbound email | sending_send_email, CLI sending:send, SDK sendingSendEmail; include Idempotency-Key. |
| Send multiple outbound emails | sending_send_email_batch, CLI sending:send:batch, SDK sendingSendEmailBatch; do not loop single sends. |
| Send or read attachments | sendmux-attachments; use file_path, presigned upload/download URLs, CLI --attach, SDK file helpers, blob_id for mailbox sends, and attachment_id for Sending sends instead of inline base64. |
| Count matching mailbox messages | mailbox_count_messages, CLI mailbox:count-messages, SDK mailboxCountMessages. |
| Search mailbox text | mailbox_search_message_snippets, CLI mailbox:search-message-snippets, SDK mailboxSearchMessageSnippets; then fetch selected IDs. |
| Read several known messages | mailbox_batch_get_messages, CLI mailbox:batch-get-messages, SDK mailboxBatchGetMessages. |
| Update/delete several messages | Batch update/delete after explicit confirmation. |
| Resume broad mailbox sync | mailbox_get_changes, CLI mailbox:get-changes, SDK mailboxGetChanges. |
| Resume filtered mailbox sync | CLI/SDK mailbox:query-message-changes / mailboxQueryMessageChanges; MCP does not curate it yet. |
| Watch live mailbox events | CLI/SDK mailbox:stream-events / mailboxStreamEvents; MCP does not curate it yet. |
| Scan threads | List threads, then fetch one thread or its messages. |
| Manage domains/mailboxes/keys | Management MCP for curated create/list/get/update/suspend/resume/key tools; CLI/SDK for uncovered lifecycle work. |
| Manage sending accounts | CLI/SDK; MCP does not curate provider tools yet. |
| Manage webhooks | MCP for list/create/test; CLI/SDK for get/update/delete/rotate/delivery payloads. |
| Inspect spend, logs, metrics | Summary/metrics first; filter log lists with small limit, then fetch one selected row. |
Read less
For mailbox questions, reduce the result set before reading content:
- Count when the user asks "how many" or when the query may be broad.
- Search snippets with a small
limitwhen the user needs examples. - Batch-get only selected message IDs.
- Request clean body/content only when message text affects the answer.
CLI:
sendmux mailbox:count-messages \
--query q=invoice \
--query is_unread=true \
--json
sendmux mailbox:search-message-snippets \
--query q=invoice \
--query is_unread=true \
--query limit=10 \
--json
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
Write fewer requests
Batch when there is more than one target.
sendmux sending:send:batch \
--idempotency-key "$IDEMPOTENCY_KEY" \
--body-file ./messages.json \
--json
sendmux mailbox:batch-update-messages \
--body '{
"ids": ["eml_abc", "eml_def"],
"seen": true,
"if_in_state": "state_from_prior_read"
}' \
--json
For batch sends, inspect every per-message result before reporting success. Batch can contain mixed outcomes.
Sync by delta
Use sync endpoints instead of re-listing stable data.
Broad mailbox sync:
sendmux mailbox:get-changes \
--query messages_since_state="$MESSAGES_STATE" \
--query folders_since_state="$FOLDERS_STATE" \
--query threads_since_state="$THREADS_STATE" \
--query limit=100 \
--json
Filtered message sync:
sendmux mailbox:query-message-changes \
--query since_query_state="$QUERY_STATE" \
--query q=invoice \
--query is_unread=true \
--query limit=100 \
--json
Store the returned state token. Continue with the same filters only while has_more is true and the next page is needed.
Transfer less
- Use small
limitvalues on list calls. - Follow
pagination.next_cursoronly until enough evidence has been gathered. - Prefer summary or metrics endpoints before log lists.
- Use
If-None-Matchfor repeated detail reads that previously returned anETag. - Use
If-Matchfor updates when the prior read returned anETag. - For inbound attachments, fetch metadata and use the short-lived
download_url; if it expires, re-fetch metadata instead of building URLs manually. - For outbound attachments, a file path or presigned URL is usually under 100 tokens, while base64 can burn thousands of tokens and corrupt large files.
CLI conditional examples:
sendmux management:get-email-log \
--path public_id=dlog_abc \
--if-none-match "$ETAG" \
--json
sendmux management:update-mailbox \
--path public_id=mbx_abc \
--if-match "$ETAG" \
--body '{"display_name":"Agent Inbox"}' \
--json
SDK helpers:
import {
conditionalHeaders,
idempotencyHeaders,
paginate,
responseEtag,
} from "@sendmux/core";
const headers = conditionalHeaders({ ifNoneMatch: priorEtag });
const writeHeaders = {
...conditionalHeaders({ etag: priorEtag }),
...idempotencyHeaders(operationKey),
};
Retry safely
Use Idempotency-Key on supported mutations so retrying does not create duplicate work.
Good candidates:
sending:sendandsending:send:batch.mailbox:send-message.- Management creates, mailbox key creation, suspend/resume, provider mutations, webhook create/rotate/test.
When retrying application code, prefer SDK retry helpers only for safe reads or idempotent writes. Non-idempotent writes should fail rather than risk duplicate side effects.
Routing
- Setup, key scopes, first call:
sendmux-getting-started. - Email send bodies and SMTP-vs-HTTP choice:
sendmux-send-email. - Attachment upload/download mechanics:
sendmux-attachments. - Mailbox read/search/sync/triage/reply details:
sendmux-mailbox-agent. - Management domains, mailboxes, webhooks, billing, logs:
sendmux-management. - CLI syntax and profiles:
sendmux-cli. - MCP installation and client config:
sendmux-mcp-setup.
Related skills
Use the Sendmux CLI for durable agent inbox registration, owner invites, profiles, and terminal-driven Management, Mailbox, and Sending workflows.
Move email attachments through Sendmux without putting file bytes in model context, using file paths, presigned URLs, CLI, SDKs, or MCP.
Manage Sendmux domains, mailboxes, mailbox keys, sending accounts, webhooks, logs, billing, and account-level setup.
Connect OpenClaw and other agent clients to hosted or local Sendmux MCP servers for mailbox, sending, and management tools.
Set up Sendmux for agents, register a durable inbox without an existing key, link an owner, choose a runtime surface, and make the first harmless call.