Sendmux mailbox agent
Agent skills for Sendmux
npx -y skills add Sendmux/skills --skill sendmux-mailbox-agentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
What its author says it does
Copied from the file, not written here
Work efficiently with one Sendmux mailbox from an AI agent. Use for reading, searching, counting, syncing, triaging, filing, deleting, threading, or replying from a mailbox with an smx_mbx_ key or scoped smx_agent_ token, especially when the user asks an agent to inspect an inbox, find relevant messages, mark messages, or continue from a prior mailbox sync state.
The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
9.3 KB, as published. Nobody here has run it
Sendmux mailbox agent
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.
Boundaries
- Do not ask the user to paste an API key.
- Do not use a root key for mailbox work.
- Do not create mailboxes or mailbox keys here; route those tasks to
sendmux-management. - Do not delete or mutate messages without explicit user confirmation.
- Treat pre-claim
smx_agent_tokens as read/receive only. They do not haveemail.send; owner-approved app-resourcesmx_agent_tokens may send from their assigned mailbox when the token includesemail.send. - If a credential grants more than one mailbox, include
mailbox_idon mailbox calls; otherwise omit it.
Efficient defaults
| 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. |
Search before reading
Use this sequence for most "find messages about X" tasks:
- Count first when the user asks "how many" or when a broad search may be large.
- Use search snippets with a small
limit. - Batch-get only the selected message IDs.
- Read clean body/content only for messages whose content matters.
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",
},
});
Triage and mutation
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.
Reply or send from the mailbox
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:
- Local MCP:
mailbox_upload_attachmentwithfile_path, then send with the returnedblob_id. - Hosted or shell-capable MCP: mint a presigned upload URL,
PUTthe file without an API key, then send with the returnedblob_id. - CLI:
sendmux mailbox:send-message --attach ./report.pdf. - SDK: use the Node or Python file helpers.
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_..."
}
Threads and folders
- Use
mailbox_list_threadswith smalllimitfor conversation-level scanning. - Use
mailbox_get_threadfor one thread summary. - Use
mailbox_list_thread_messagesfor message summaries in a known thread. - Use clean content/body tools only for selected messages or threads.
- Use
mailbox_list_foldersbefore 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
Sync
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.
Error handling
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.429or503: retry according to response headers.
Routing
- First setup/auth check:
sendmux-getting-started. - Independent outbound sending or batch sends:
sendmux-send-email. - Attachment upload/download mechanics:
sendmux-attachments. - Domain/mailbox/key creation and mailbox admin:
sendmux-management. - CLI command details:
sendmux-cli. - Cheapest-call doctrine:
sendmux-token-efficient-usage.