Sendmux Email Inbox API + Sending
OfficialYou can use this MCP server to read, organize, and send email through Sendmux's Mailbox and Sending APIs.
Inspect mailbox connection/profile, granted mailboxes, session limits/capabilities, identities, folders, threads, and message metadata.
Search, count, list, batch-get, and read message bodies/content; wait briefly for new mail; resume mailbox sync via change cursors.
Update messages with flags/keywords, batch move/update, and delete messages soft or permanently.
Work with mailbox attachments: get metadata/download links, read text or resource links, and upload via presigned URL or tiny inline base64.
Send mailbox messages with recipients, subject, text/HTML, headers, and inline or uploaded attachments.
Send single or batch outbound emails with CC/BCC/Reply-To, custom headers, delivery groups, and attachment IDs; also inspect Sending credentials and temporary attachment uploads.
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
Email Inbox API + Sending by Qubrics
Email inbox API, inbound mail, and outbound sending MCP and A2A servers for AI agents, with inbound email, clean JSON parsing, webhooks, and multi-provider routing through Qubrics.
This package is the Qubrics MCP. Keep it separate from any documentation-search MCP used by docs tooling.
Documentation
Qubrics docs: qubrics.com/docs
Management API reference: qubrics.com/docs/api/introduction
Mailbox API reference: qubrics.com/docs/mailbox-api/introduction
Sending API reference: qubrics.com/docs/sending-api/introduction
Source repository: qubrics/qubrics-sdk
Related MCP server: sendook-mcp
Requirements
Python 3.10 or newer.
A send-capable
smx_mbx_*key or owner-approved Sending-resourcesmx_agent_*token for Sending tools.A mailbox-scoped
smx_mbx_*key or scopedsmx_agent_*token for Mailbox tools.A root
smx_root_*key for Management tools.
Attachment input migration
MCP attachment tools use upload references instead of local file_path and
roots inputs. Before upgrading a self-managed package or server, retain the prior
known-working package environment, dependency state, and MCP client and tool
configuration. Update attachment callers to use the
attachment workflow for agents, then verify
tool discovery and each attachment workflow your agents use.
To roll back a self-managed installation, restore the retained package environment, dependency state, and MCP client and tool configuration together. Verify tool discovery and the relevant attachment workflow before resuming agents. A package rollback doesn't reverse uploads or sends that have already completed.
For clients that use Qubrics's hosted endpoint, changing a local pip
environment doesn't change the deployed server version. A hosted deployment
rollback is a separate operator release action and must be verified against the
hosted endpoint.
Installation
These commands target the Qubrics release of qubrics-mcp. Until it is published, install sendmux-mcp with its existing import names.
pip install qubrics-mcpUsage
Run a single local server with the per-surface commands.
QUBRICS_API_KEY=smx_mbx_... qubrics-mcp-mailbox
QUBRICS_API_KEY=smx_root_... qubrics-mcp-management
QUBRICS_API_KEY=smx_mbx_... qubrics-mcp-sendingRun a combined local server with qubrics-mcp.
QUBRICS_MCP_SURFACES=mailbox,sending \
QUBRICS_MAILBOX_API_KEY=smx_mbx_... \
QUBRICS_SENDING_API_KEY=smx_mbx_... \
qubrics-mcpRun all three local surfaces when you have both key types.
QUBRICS_MCP_SURFACES=mailbox,management,sending \
QUBRICS_MAILBOX_API_KEY=smx_mbx_... \
QUBRICS_MANAGEMENT_API_KEY=smx_root_... \
QUBRICS_SENDING_API_KEY=smx_mbx_... \
qubrics-mcpThe generic qubrics-mcp command also accepts --surface or --surfaces. The wrapper commands select exactly one surface.
Transports
stdio is the default transport for local agent clients.
QUBRICS_API_KEY=smx_mbx_... qubrics-mcp-mailbox --transport stdiohttp and streamable-http expose the MCP endpoint over HTTP. HTTP mode defaults to 127.0.0.1:8765/mcp and requires a separate MCP bearer token unless you explicitly opt out.
QUBRICS_API_KEY=smx_mbx_... \
QUBRICS_MCP_HTTP_BEARER_TOKEN=local-mcp-token \
qubrics-mcp-mailbox --transport http --host 127.0.0.1 --port 8765 --path /mcp/health returns a small JSON health response for the selected surfaces.
Hosted Endpoint
The public hosted MCP endpoint is https://mcp.qubrics.com/mcp.
For hosted clients, use HTTP transport with OAuth. Do not add manual Authorization headers, API keys, custom OAuth endpoints, or custom scopes unless your client explicitly requires them.
Hosted OAuth clients that omit requested scopes during registration or authorization are supported; the server advertises the hosted scope set through discovery and bearer challenges.
The packaged qubrics-mcp-hosted command runs the hosted server runtime. Local and private deployments should use the local commands above unless you are operating a compatible OAuth-backed hosted environment.
Hosted A2A Endpoint
The same hosted runtime exposes deterministic A2A 1.0 over HTTP+JSON at https://a2a.qubrics.com/a2a/v1. Discover it from https://a2a.qubrics.com/.well-known/agent-card.json; OAuth resource metadata is at https://a2a.qubrics.com/.well-known/oauth-protected-resource.
Send exactly one JSON DataPart to the A2A message:send operation. Its data selects a curated Qubrics operation and supplies that operation's inputs:
{
"operationId": "managementListDomains",
"pathParameters": {},
"query": { "limit": 10 },
"headers": {},
"body": null,
"mailboxId": null
}operationId uses the same curated operation IDs as the hosted MCP service. OAuth grants are audience-bound to the A2A resource and retain their Qubrics surface and permission limits. The service returns one JSON DataPart containing the upstream status, safe response headers, and JSON body (or bodyBase64 for non-JSON responses).
The A2A endpoint is immediate and stateless: streaming, push notifications, persistent tasks, and task cancellation are not advertised or routed.
Configuration
Setting | Environment | Default |
Tool surfaces |
| required for |
API key fallback |
| accepted for compatible single-key setups |
Mailbox API key |
| required when mailbox is selected unless a compatible fallback is provided |
Management API key |
| required when management is selected unless a compatible fallback is provided |
Sending API key |
| required when sending is selected unless the fallback key is a send-capable |
App API base URL |
|
|
Sending API base URL |
|
|
Transport |
|
|
HTTP host |
|
|
HTTP port |
|
|
HTTP path |
|
|
HTTP bearer token |
| required for HTTP unless opt-out is enabled |
Allow unauthenticated HTTP |
|
|
Allowed browser origins |
| no browser origins |
Snapshot directory override |
| packaged snapshots |
App snapshot override |
| packaged app snapshot |
Sending snapshot override |
| packaged sending snapshot |
Request timeout |
|
|
Retry attempts |
|
|
Retry time budget, in seconds |
| unset |
Retries honour Retry-After and X-RateLimit-Reset without applying the local backoff ceiling, and stop for retryable: false. Set the optional retry budget with RetryConfig(max_elapsed_seconds=30), the environment variable above, or --retry-max-elapsed-seconds 30. A retry that would exceed the remaining budget returns the original error; in-flight requests keep their normal HTTP timeouts.
Packaged OpenAPI snapshots are the default so released tool names, schemas, and descriptions stay stable. Path, directory, and URL overrides are available for development, canary, and debugging runs.
Tool Surfaces
Mailbox: tools for granted mailboxes, profile/session discovery, messages, attachments, bounded message waits, threads, folders, search, counts, and mailbox sends. Requires an
smx_mbx_*key or scopedsmx_agent_*token. Agent tokens remain limited by server-side scopes; pre-claim self-registered agent tokens do not includeemail.send.Management: tools for domains, mailboxes, logs, metrics, spend summary, and webhooks. Requires an
smx_root_*key.Sending: tools for attachment upload refs, single sends, and batch sends. Requires an
smx_mbx_*key or owner-approved Sending-resourcesmx_agent_*token.
The server rejects keys with the wrong prefix before starting.
Package Contract For Maintainers
The source checkout includes qubrics/mcp/mcp-contract.json, generated from the actual server factory's public tool discovery. Use its tools.by_surface entries and tools.count instead of maintaining a separate catalogue. Each entry retains the tool's description, input/output schemas, and annotations. The contract also separates hosted resource, local transports, API origins, certified protocol revisions, and the runtime versions used during generation.
After installing a build that contains the contract, read it without credentials or network requests:
from qubrics.mcp.contract import load_contract
contract = load_contract()
print(contract["package"])The result identifies the installed distribution and version. load_contract() raises ValueError for stale source/version evidence, a mismatched pinned FastMCP runtime, or unsupported certified revisions. The recorded transitive MCP version is provenance, not a narrower dependency constraint. Reading the artifact does not certify a newly resolved dependency version or prove a deployed service matches this build.
uploads distinguishes the locally enforced inline and Mailbox byte caps from Sending's returned max_size_bytes authority. The Sending presign request schema does not impose a numeric maximum; use the upload intent response, not a historical source constant. URL expiry and physical attachment retention are not equivalent, and this artifact does not certify storage cleanup.
From the repository root, pnpm generate:mcp refreshes native editable metadata and writes deterministic contract bytes. With that environment prepared, pnpm exec .tmp/python-venv/bin/python -m qubrics.mcp.contract --check checks freshness without rewriting. pnpm build:mcp verifies tests, wheel/sdist inclusion, installed consumption, and frozen conformance checks. Checkout changes are not available through pip install until their release is published.
Attachment Workflow For Agents
Use qubrics_mailbox_wait_for_message when a user asks an agent to wait for new mail. The tool is bounded; if it returns matched=false, call it again rather than holding an MCP tool call open indefinitely.
When a message has attachments:
Call
qubrics_mailbox_read_attachmentwithmessage_idandattachment_idwhen you need the attachment contents.For small text-like attachments, read the returned
text.For binary or oversized attachments, use the returned
resource_link/download_urlpromptly outside model context.Use
qubrics_mailbox_get_attachmentonly when metadata is enough or you need to refresh the link.
Use qubrics_mailbox_upload_attachment for outbound attachments over MCP. It accepts exactly one input mode:
presign_upload_url=truefor hosted MCP or shell-capable agents; upload the file to the returned URL with exact headers and no API key, then send with the returnedblob_id.content_base64only for tiny agent-authored files, capped at32 KiBdecoded. If it is too large, switch to a presigned upload, CLI--attach, or SDK file helpers.
Presigned uploads use the mailbox attachment cap, currently 7,500,000 bytes per attachment, and pin the exact declared byte length and content type.
For mailbox sends, qubrics_mailbox_send_message accepts either tiny inline base64 attachment objects (content, filename, content_type) or uploaded attachment references (blob_id, filename, content_type).
For Sending API sends, use qubrics_sending_upload_attachment only for tiny inline content, or call qubrics_sending_create_attachment_upload and PUT bytes outside model context. Then pass {"attachment_id": "att_..."} in qubrics_sending_send_email.attachments[].
Console Scripts
qubrics-mcpqubrics-mcp-mailboxqubrics-mcp-managementqubrics-mcp-sendingqubrics-mcp-hosted
Support
Open an issue in qubrics/qubrics-sdk with the package name, version, command, transport, and request ID from any API error.
Licence
MIT. See the licence file.
Available Tools
104 toolsmailbox_batch_delete_messagesBatch Delete MessagesADestructiveInspect
Use this only when the user explicitly asks to delete messages and supplies or confirms the message IDs. Deletion is a mailbox mutation.
Inputs: ids, permanent, mailbox_id, if_in_state. Returns: result
mailbox_batch_get_messagesBatch Get MessagesARead-onlyIdempotentInspect
Use this when the user supplies several message IDs or a prior search returns multiple candidates. It avoids repeated single-message calls.
Inputs: ids, part, body_mode, mailbox_id, +7 more. Returns: result
mailbox_batch_update_messagesBatch Update MessagesAIdempotentInspect
Use this to mark, flag, move to a folder, or set keywords/labels on multiple messages after the user has confirmed the desired change. Do not use it for read-only tasks.
Inputs: ids, seen, flagged, keywords, +2 more. Returns: result
mailbox_control_draft_scheduleChange Draft ScheduleAIdempotentInspect
Reschedule or cancel a saved draft send only when the user asks. Requires mailbox.read and email.send. Pass the current expected_revision and expected_schedule_version; scheduled_for=null cancels. Cancellation fails once sending has begun.
Inputs: draftId (required), scheduled_for (required), expected_revision (required), expected_schedule_version (required), +2 more. Returns: result
mailbox_count_messagesCount MessagesARead-onlyIdempotentInspect
Use this to count messages matching mailbox filters without listing every result. Follow with mailbox_list_messages only when examples are needed.
Inputs: q, cc, to, bcc, +16 more. Returns: result
mailbox_create_calendarCreate CalendarAInspect
Create a private calendar only when the user asks. Requires calendar.write. This does not send invitations or email reminders.
Inputs: name (required), time_zone (required), mailbox_id, Idempotency-Key. Returns: result
mailbox_create_calendar_eventCreate Calendar EventAInspect
Save an event without invitations or email reminders. Requires calendar.write. Retain the required UID before dispatch; after an uncertain result reconcile by UID lookup and never repeat the create after an empty immediate lookup.
Inputs: uid (required), start (required), title (required), duration (required), +5 more. Returns: result
mailbox_create_draftCreate Saved DraftAInspect
Save a message for review without sending it. Requires mailbox.read and mailbox.drafts.write. Use source.action for reply, reply_all, forward or adopt; explicit content overrides prepared defaults. Adoption requires Idempotency-Key; reuse it when retrying the same create request.
Inputs: cc, to, bcc, from, +10 more. Returns: result
mailbox_delete_calendarDelete an empty calendarADestructiveIdempotentInspect
Requires calendar.write. Fetch the calendar and pass its ETag in If-Match. A calendar containing events returns 409 conflict.
Inputs: If-Match (required), calendar_id (required), mailbox_id. Returns: result
mailbox_delete_calendar_eventDelete Calendar EventADestructiveIdempotentInspect
Delete an event only when the user asks. Requires calendar.write and the reviewed If-Match value. This does not send cancellation emails; reload after a conflict.
Inputs: If-Match (required), event_id (required), mailbox_id. Returns: result
mailbox_delete_draftDelete Saved DraftADestructiveInspect
Delete a saved draft only when the user asks. Requires mailbox.read and mailbox.drafts.write. Deletion finishes in the background; a send already in progress cannot be deleted.
Inputs: draftId (required), If-Match, mailbox_id. Returns: result
mailbox_get_attachmentGet Attachment MetadataARead-onlyIdempotentInspect
Use this after finding a message attachment. It returns metadata plus a fresh short-lived download_url for that exact attachment; fetch the URL promptly, and call this tool again if it expires.
Inputs: message_id (required), attachment_id (required), mailbox_id. Returns: object
mailbox_get_attachment_textRead Attachment TextARead-onlyIdempotentInspect
Read or poll a previously requested attachment extraction. Requires mailbox.read. This does not start conversion; cache expiry or source removal returns not_found. Check status and outcome before using text.
Inputs: message_id (required), attachment_id (required), max_bytes, mailbox_id, +1 more. Returns: result
mailbox_get_calendarGet CalendarARead-onlyIdempotentInspect
Read one calendar in the selected mailbox. Requires calendar.read.
Inputs: calendar_id (required), mailbox_id, If-None-Match. Returns: result
mailbox_get_calendar_eventGet Calendar EventARead-onlyIdempotentInspect
Read one event before editing or deleting it. Requires calendar.read. Retain its current concurrency token for the next conditional change.
Inputs: event_id (required), mailbox_id, If-None-Match. Returns: result
mailbox_get_calendar_event_changesGet Calendar Event ChangesARead-onlyIdempotentInspect
Read bounded event changes from a retained state. Requires calendar.read. When sync_required is true, perform a full event resync; these coalesced changes are not a complete activity history.
Inputs: limit, mailbox_id, since_state. Returns: result
mailbox_get_changesGet Mailbox ChangesARead-onlyIdempotentInspect
Use this to resume mailbox sync from a prior state cursor. Do not use it for ad hoc message search.
Inputs: limit, types, mailbox_id, since_state, +6 more. Returns: result
mailbox_get_connectionGet Mailbox ConnectionARead-onlyIdempotentInspect
Validate the current Mailbox credential and read its team, connection label, permissions and authorised mailboxes. No mailbox selection or mailbox storage access is required.
Inputs: If-None-Match. Returns: result
mailbox_get_draftRead Saved DraftARead-onlyIdempotentInspect
Read a saved draft and its current revision before editing or sending. Requires mailbox.read. Keep the revision and schedule version for later changes.
Inputs: draftId (required), mailbox_id, If-None-Match. Returns: result
mailbox_get_identityGet Mailbox IdentityARead-onlyIdempotentInspect
Use this to read the mailbox sender identity and display name. Use it before composing replies when the sender should match the mailbox identity.
Inputs: mailbox_id. Returns: result
mailbox_get_meGet Mailbox ProfileARead-onlyIdempotentInspect
Use this to identify the authenticated mailbox before acting on mail. It returns profile details for the mailbox key currently in use.
Inputs: mailbox_id, If-None-Match. Returns: result
mailbox_get_messageGet MessageARead-onlyIdempotentInspect
Use this to fetch one message summary or detail by message_id. Use mailbox_list_body or mailbox_list_content when the body content is required.
Inputs: message_id (required), mailbox_id, If-None-Match. Returns: result
mailbox_get_sender_choicesGet permitted sender choicesBRead-onlyIdempotentInspect
Intersects current team, inbox and credential policies with provider restrictions and selected delivery groups. Subdomains require separate authorisation. Sending checks these permissions again before submission.
Inputs: mailbox_id, If-None-Match, delivery_group_id. Returns: result
mailbox_get_sessionGet Mailbox SessionARead-onlyIdempotentInspect
Use this before complex mailbox work to discover supported mailbox capabilities, limits, and endpoint metadata. Do not use it for message search.
Inputs: mailbox_id, If-None-Match. Returns: result
mailbox_get_threadGet ThreadARead-onlyIdempotentInspect
Use this to read one thread summary by thread_id. Use mailbox_list_thread_messages when the task needs the messages in the thread.
Inputs: thread_id (required), mailbox_id, If-None-Match. Returns: result
mailbox_list_bodyRead Message BodyARead-onlyIdempotentInspect
Use this to read the raw or simplified body for a known message_id. Prefer it when the task needs message text but not every MIME detail.
Inputs: message_id (required), part, mailbox_id, If-None-Match, +1 more. Returns: result
mailbox_list_calendar_eventsList Calendar EventsARead-onlyIdempotentInspect
List events in the selected mailbox or look up a caller-held UID. Requires calendar.read. UID search is eventually consistent: an empty immediate lookup leaves an uncertain create unresolved and never authorises repeating it.
Inputs: uid, limit, cursor, mailbox_id, +1 more. Returns: result
mailbox_list_calendarsList CalendarsARead-onlyIdempotentInspect
List calendars in the selected mailbox. Requires calendar.read. Use a small limit and continue with the returned cursor.
Inputs: limit, cursor, mailbox_id. Returns: result
mailbox_list_contentRead Message ContentARead-onlyIdempotentInspect
Use this to read structured content for a known message_id. Prefer it when headers, participants, or body parts affect the answer.
Inputs: message_id (required), part, mailbox_id, include_html, +7 more. Returns: result
mailbox_list_draftsList Saved DraftsARead-onlyIdempotentInspect
List saved drafts in the selected inbox, newest first. Requires mailbox.read. Use a small limit and continue with the returned cursor.
Inputs: limit, cursor, mailbox_id. Returns: result
mailbox_list_foldersList FoldersARead-onlyIdempotentInspect
Use this to inspect mailbox folders before filing or moving messages. It is read-only.
Inputs: limit, cursor, mailbox_id. Returns: result
mailbox_list_granted_mailboxesList Granted MailboxesARead-onlyIdempotentInspect
Use this first when the token can access more than one mailbox. It searches only the mailboxes granted to this connection and returns IDs to pass as mailbox_id.
Inputs: q, limit, cursor. Returns: result
mailbox_list_identitiesList Mailbox IdentitiesARead-onlyIdempotentInspect
Use this to list sender identities available to the mailbox. Prefer mailbox_get_identity when only the default identity is needed.
Inputs: limit, cursor, mailbox_id. Returns: result
mailbox_list_messagesList MessagesARead-onlyIdempotentInspect
Use this to scan mailbox messages by cursor without fetching full bodies. Filter by folder_id, keyword/not_keyword, dates, sender/recipient, text query, unread state, or has_attachment; attachment metadata includes a short-lived download_url.
Inputs: q, cc, to, bcc, +20 more. Returns: result
mailbox_list_thread_messagesList Thread MessagesARead-onlyIdempotentInspect
Use this to list messages inside a known thread. Use message body tools only for messages that need full content.
Inputs: thread_id (required), sort, limit, cursor, +1 more. Returns: result
mailbox_list_threadsList ThreadsBRead-onlyIdempotentInspect
Use this to scan conversation threads without loading every message. Continue with next_cursor only when additional threads are needed.
Inputs: q, after, limit, before, +7 more. Returns: result
mailbox_read_attachmentRead AttachmentARead-onlyIdempotentInspect
Use this after finding a message attachment when you need the attachment contents. Text-like attachments are downloaded server-side and returned as text, so agents do not need a generic web_fetch tool. Binary or oversized attachments return metadata plus a fresh download link.
Inputs: message_id (required), attachment_id (required), mode, mailbox_id, +1 more. Returns: object
mailbox_request_attachment_textRequest Attachment TextAIdempotentInspect
Extract readable text from an attachment up to 7500000 bytes at no extra charge. Requires mailbox.read. Repeated requests reuse the current extraction for 24 hours. OCR is unavailable; check status and outcome, and use the original download if extraction cannot complete.
Inputs: message_id (required), attachment_id (required), max_bytes, mailbox_id. Returns: result
mailbox_search_message_snippetsSearch Message SnippetsARead-onlyIdempotentInspect
Use this to search message snippets by query text. Narrow with folder_id, keyword/not_keyword, dates, sender/recipient, unread state, or has_attachment; use returned message IDs with a read tool before making content-specific claims.
Inputs: q (required), cc, to, bcc, +17 more. Returns: result
mailbox_send_draftSend Saved DraftAInspect
Send only the saved revision the user approved. Requires mailbox.read and email.send. Pass expected_revision; to schedule within 30 days also pass scheduled_for and expected_schedule_version. After cancelling a schedule, include the current schedule version.
Inputs: draftId (required), expected_revision (required), If-Match, mailbox_id, +2 more. Returns: result
mailbox_send_messageSend Mailbox MessageAInspect
Use this to send a message from the authenticated mailbox. For attachments, call mailbox_upload_attachment first using presign_upload_url or tiny content_base64, then pass the returned blob_id. Include an Idempotency-Key for retries.
Inputs: cc, to, bcc, from, +8 more. Returns: result
mailbox_update_calendar_eventEdit Calendar EventAIdempotentInspect
Edit an event without sending invitations or email reminders. Requires calendar.write and the reviewed If-Match value. Reload after a conflict before making another change.
Inputs: If-Match (required), event_id (required), start, title, +4 more. Returns: result
mailbox_update_draftEdit Saved DraftAInspect
Edit a saved draft without sending it. Requires mailbox.read and mailbox.drafts.write. Pass the reviewed expected_revision; reload after a conflict before making another edit.
Inputs: draftId (required), expected_revision (required), cc, to, +10 more. Returns: result
mailbox_update_identityUpdate Mailbox IdentityAIdempotentInspect
Use this only when the user explicitly asks to change sender identity details. Do not use it for one-off message composition.
Inputs: name, mailbox_id, html_signature, text_signature. Returns: result
mailbox_upload_attachmentUpload AttachmentAInspect
Use this before sending a mailbox attachment. For real files set presign_upload_url=true with filename, content_type, and size_bytes, then PUT the file to the returned short-lived URL promptly and send the returned blob_id. Inline content_base64 is a last resort for tiny agent-authored files only and is capped at 32 KiB decoded.
Inputs: filename (required), mailbox_id, size_bytes, content_type, +2 more. Returns: object
mailbox_wait_for_messageWait For MessageARead-onlyIdempotentInspect
Use this to wait briefly for new mail instead of manual polling. It polls for up to 25 seconds, returns a matching message with attachment metadata when found, or a clean no_message result so you can call again.
Inputs: q, after, keyword, subject, +5 more. Returns: object
qubrics_mailbox_batch_delete_messagesBatch Delete MessagesADestructiveInspect
Use this only when the user explicitly asks to delete messages and supplies or confirms the message IDs. Deletion is a mailbox mutation.
Inputs: ids, permanent, mailbox_id, if_in_state. Returns: result
qubrics_mailbox_batch_get_messagesBatch Get MessagesARead-onlyIdempotentInspect
Use this when the user supplies several message IDs or a prior search returns multiple candidates. It avoids repeated single-message calls.
Inputs: ids, part, body_mode, mailbox_id, +7 more. Returns: result
qubrics_mailbox_batch_update_messagesBatch Update MessagesAIdempotentInspect
Use this to mark, flag, move to a folder, or set keywords/labels on multiple messages after the user has confirmed the desired change. Do not use it for read-only tasks.
Inputs: ids, seen, flagged, keywords, +2 more. Returns: result
qubrics_mailbox_control_draft_scheduleChange Draft ScheduleAIdempotentInspect
Reschedule or cancel a saved draft send only when the user asks. Requires mailbox.read and email.send. Pass the current expected_revision and expected_schedule_version; scheduled_for=null cancels. Cancellation fails once sending has begun.
Inputs: draftId (required), scheduled_for (required), expected_revision (required), expected_schedule_version (required), +2 more. Returns: result
qubrics_mailbox_count_messagesCount MessagesARead-onlyIdempotentInspect
Use this to count messages matching mailbox filters without listing every result. Follow with mailbox_list_messages only when examples are needed.
Inputs: q, cc, to, bcc, +16 more. Returns: result
qubrics_mailbox_create_calendarCreate CalendarAInspect
Create a private calendar only when the user asks. Requires calendar.write. This does not send invitations or email reminders.
Inputs: name (required), time_zone (required), mailbox_id, Idempotency-Key. Returns: result
qubrics_mailbox_create_calendar_eventCreate Calendar EventAInspect
Save an event without invitations or email reminders. Requires calendar.write. Retain the required UID before dispatch; after an uncertain result reconcile by UID lookup and never repeat the create after an empty immediate lookup.
Inputs: uid (required), start (required), title (required), duration (required), +5 more. Returns: result
qubrics_mailbox_create_draftCreate Saved DraftAInspect
Save a message for review without sending it. Requires mailbox.read and mailbox.drafts.write. Use source.action for reply, reply_all, forward or adopt; explicit content overrides prepared defaults. Adoption requires Idempotency-Key; reuse it when retrying the same create request.
Inputs: cc, to, bcc, from, +10 more. Returns: result
qubrics_mailbox_delete_calendarDelete an empty calendarADestructiveIdempotentInspect
Requires calendar.write. Fetch the calendar and pass its ETag in If-Match. A calendar containing events returns 409 conflict.
Inputs: If-Match (required), calendar_id (required), mailbox_id. Returns: result
qubrics_mailbox_delete_calendar_eventDelete Calendar EventADestructiveIdempotentInspect
Delete an event only when the user asks. Requires calendar.write and the reviewed If-Match value. This does not send cancellation emails; reload after a conflict.
Inputs: If-Match (required), event_id (required), mailbox_id. Returns: result
qubrics_mailbox_delete_draftDelete Saved DraftADestructiveInspect
Delete a saved draft only when the user asks. Requires mailbox.read and mailbox.drafts.write. Deletion finishes in the background; a send already in progress cannot be deleted.
Inputs: draftId (required), If-Match, mailbox_id. Returns: result
qubrics_mailbox_get_attachmentGet Attachment MetadataARead-onlyIdempotentInspect
Use this after finding a message attachment. It returns metadata plus a fresh short-lived download_url for that exact attachment; fetch the URL promptly, and call this tool again if it expires.
Inputs: message_id (required), attachment_id (required), mailbox_id. Returns: object
qubrics_mailbox_get_attachment_textRead Attachment TextARead-onlyIdempotentInspect
Read or poll a previously requested attachment extraction. Requires mailbox.read. This does not start conversion; cache expiry or source removal returns not_found. Check status and outcome before using text.
Inputs: message_id (required), attachment_id (required), max_bytes, mailbox_id, +1 more. Returns: result
qubrics_mailbox_get_calendarGet CalendarARead-onlyIdempotentInspect
Read one calendar in the selected mailbox. Requires calendar.read.
Inputs: calendar_id (required), mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_get_calendar_eventGet Calendar EventARead-onlyIdempotentInspect
Read one event before editing or deleting it. Requires calendar.read. Retain its current concurrency token for the next conditional change.
Inputs: event_id (required), mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_get_calendar_event_changesGet Calendar Event ChangesARead-onlyIdempotentInspect
Read bounded event changes from a retained state. Requires calendar.read. When sync_required is true, perform a full event resync; these coalesced changes are not a complete activity history.
Inputs: limit, mailbox_id, since_state. Returns: result
qubrics_mailbox_get_changesGet Mailbox ChangesARead-onlyIdempotentInspect
Use this to resume mailbox sync from a prior state cursor. Do not use it for ad hoc message search.
Inputs: limit, types, mailbox_id, since_state, +6 more. Returns: result
qubrics_mailbox_get_connectionGet Mailbox ConnectionARead-onlyIdempotentInspect
Validate the current Mailbox credential and read its team, connection label, permissions and authorised mailboxes. No mailbox selection or mailbox storage access is required.
Inputs: If-None-Match. Returns: result
qubrics_mailbox_get_draftRead Saved DraftARead-onlyIdempotentInspect
Read a saved draft and its current revision before editing or sending. Requires mailbox.read. Keep the revision and schedule version for later changes.
Inputs: draftId (required), mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_get_identityGet Mailbox IdentityARead-onlyIdempotentInspect
Use this to read the mailbox sender identity and display name. Use it before composing replies when the sender should match the mailbox identity.
Inputs: mailbox_id. Returns: result
qubrics_mailbox_get_meGet Mailbox ProfileBRead-onlyIdempotentInspect
Use this to identify the authenticated mailbox before acting on mail. It returns profile details for the mailbox key currently in use.
Inputs: mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_get_messageGet MessageARead-onlyIdempotentInspect
Use this to fetch one message summary or detail by message_id. Use mailbox_list_body or mailbox_list_content when the body content is required.
Inputs: message_id (required), mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_get_sender_choicesGet permitted sender choicesBRead-onlyIdempotentInspect
Intersects current team, inbox and credential policies with provider restrictions and selected delivery groups. Subdomains require separate authorisation. Sending checks these permissions again before submission.
Inputs: mailbox_id, If-None-Match, delivery_group_id. Returns: result
qubrics_mailbox_get_sessionGet Mailbox SessionARead-onlyIdempotentInspect
Use this before complex mailbox work to discover supported mailbox capabilities, limits, and endpoint metadata. Do not use it for message search.
Inputs: mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_get_threadGet ThreadARead-onlyIdempotentInspect
Use this to read one thread summary by thread_id. Use mailbox_list_thread_messages when the task needs the messages in the thread.
Inputs: thread_id (required), mailbox_id, If-None-Match. Returns: result
qubrics_mailbox_list_bodyRead Message BodyARead-onlyIdempotentInspect
Use this to read the raw or simplified body for a known message_id. Prefer it when the task needs message text but not every MIME detail.
Inputs: message_id (required), part, mailbox_id, If-None-Match, +1 more. Returns: result
qubrics_mailbox_list_calendar_eventsList Calendar EventsARead-onlyIdempotentInspect
List events in the selected mailbox or look up a caller-held UID. Requires calendar.read. UID search is eventually consistent: an empty immediate lookup leaves an uncertain create unresolved and never authorises repeating it.
Inputs: uid, limit, cursor, mailbox_id, +1 more. Returns: result
qubrics_mailbox_list_calendarsList CalendarsARead-onlyIdempotentInspect
List calendars in the selected mailbox. Requires calendar.read. Use a small limit and continue with the returned cursor.
Inputs: limit, cursor, mailbox_id. Returns: result
qubrics_mailbox_list_contentRead Message ContentBRead-onlyIdempotentInspect
Use this to read structured content for a known message_id. Prefer it when headers, participants, or body parts affect the answer.
Inputs: message_id (required), part, mailbox_id, include_html, +7 more. Returns: result
qubrics_mailbox_list_draftsList Saved DraftsARead-onlyIdempotentInspect
List saved drafts in the selected inbox, newest first. Requires mailbox.read. Use a small limit and continue with the returned cursor.
Inputs: limit, cursor, mailbox_id. Returns: result
qubrics_mailbox_list_foldersList FoldersBRead-onlyIdempotentInspect
Use this to inspect mailbox folders before filing or moving messages. It is read-only.
Inputs: limit, cursor, mailbox_id. Returns: result
qubrics_mailbox_list_granted_mailboxesList Granted MailboxesARead-onlyIdempotentInspect
Use this first when the token can access more than one mailbox. It searches only the mailboxes granted to this connection and returns IDs to pass as mailbox_id.
Inputs: q, limit, cursor. Returns: result
qubrics_mailbox_list_identitiesList Mailbox IdentitiesARead-onlyIdempotentInspect
Use this to list sender identities available to the mailbox. Prefer mailbox_get_identity when only the default identity is needed.
Inputs: limit, cursor, mailbox_id. Returns: result
qubrics_mailbox_list_messagesList MessagesARead-onlyIdempotentInspect
Use this to scan mailbox messages by cursor without fetching full bodies. Filter by folder_id, keyword/not_keyword, dates, sender/recipient, text query, unread state, or has_attachment; attachment metadata includes a short-lived download_url.
Inputs: q, cc, to, bcc, +20 more. Returns: result
qubrics_mailbox_list_thread_messagesList Thread MessagesBRead-onlyIdempotentInspect
Use this to list messages inside a known thread. Use message body tools only for messages that need full content.
Inputs: thread_id (required), sort, limit, cursor, +1 more. Returns: result
qubrics_mailbox_list_threadsList ThreadsARead-onlyIdempotentInspect
Use this to scan conversation threads without loading every message. Continue with next_cursor only when additional threads are needed.
Inputs: q, after, limit, before, +7 more. Returns: result
qubrics_mailbox_read_attachmentRead AttachmentARead-onlyIdempotentInspect
Use this after finding a message attachment when you need the attachment contents. Text-like attachments are downloaded server-side and returned as text, so agents do not need a generic web_fetch tool. Binary or oversized attachments return metadata plus a fresh download link.
Inputs: message_id (required), attachment_id (required), mode, mailbox_id, +1 more. Returns: object
qubrics_mailbox_request_attachment_textRequest Attachment TextAIdempotentInspect
Extract readable text from an attachment up to 7500000 bytes at no extra charge. Requires mailbox.read. Repeated requests reuse the current extraction for 24 hours. OCR is unavailable; check status and outcome, and use the original download if extraction cannot complete.
Inputs: message_id (required), attachment_id (required), max_bytes, mailbox_id. Returns: result
qubrics_mailbox_search_message_snippetsSearch Message SnippetsARead-onlyIdempotentInspect
Use this to search message snippets by query text. Narrow with folder_id, keyword/not_keyword, dates, sender/recipient, unread state, or has_attachment; use returned message IDs with a read tool before making content-specific claims.
Inputs: q (required), cc, to, bcc, +17 more. Returns: result
qubrics_mailbox_send_draftSend Saved DraftAInspect
Send only the saved revision the user approved. Requires mailbox.read and email.send. Pass expected_revision; to schedule within 30 days also pass scheduled_for and expected_schedule_version. After cancelling a schedule, include the current schedule version.
Inputs: draftId (required), expected_revision (required), If-Match, mailbox_id, +2 more. Returns: result
qubrics_mailbox_send_messageSend Mailbox MessageAInspect
Use this to send a message from the authenticated mailbox. For attachments, call mailbox_upload_attachment first using presign_upload_url or tiny content_base64, then pass the returned blob_id. Include an Idempotency-Key for retries.
Inputs: cc, to, bcc, from, +8 more. Returns: result
qubrics_mailbox_update_calendar_eventEdit Calendar EventAIdempotentInspect
Edit an event without sending invitations or email reminders. Requires calendar.write and the reviewed If-Match value. Reload after a conflict before making another change.
Inputs: If-Match (required), event_id (required), start, title, +4 more. Returns: result
qubrics_mailbox_update_draftEdit Saved DraftAInspect
Edit a saved draft without sending it. Requires mailbox.read and mailbox.drafts.write. Pass the reviewed expected_revision; reload after a conflict before making another edit.
Inputs: draftId (required), expected_revision (required), cc, to, +10 more. Returns: result
qubrics_mailbox_update_identityUpdate Mailbox IdentityAIdempotentInspect
Use this only when the user explicitly asks to change sender identity details. Do not use it for one-off message composition.
Inputs: name, mailbox_id, html_signature, text_signature. Returns: result
qubrics_mailbox_upload_attachmentUpload AttachmentAInspect
Use this before sending a mailbox attachment. For real files set presign_upload_url=true with filename, content_type, and size_bytes, then PUT the file to the returned short-lived URL promptly and send the returned blob_id. Inline content_base64 is a last resort for tiny agent-authored files only and is capped at 32 KiB decoded.
Inputs: filename (required), mailbox_id, size_bytes, content_type, +2 more. Returns: object
qubrics_mailbox_wait_for_messageWait For MessageARead-onlyIdempotentInspect
Use this to wait briefly for new mail instead of manual polling. It polls for up to 25 seconds, returns a matching message with attachment metadata when found, or a clean no_message result so you can call again.
Inputs: q, after, keyword, subject, +5 more. Returns: object
qubrics_sending_create_attachment_uploadCreate Attachment UploadAInspect
Use this when a remote or shell-capable agent needs a short-lived upload URL for an outbound Sending API attachment. Provide filename, content_type, and exact size_bytes, PUT the file bytes outside model context with the returned headers, then pass the returned attachment_id to sending_send_email.
Inputs: filename (required), size_bytes (required), sha256, content_type, +1 more. Returns: result
qubrics_sending_get_attachmentGet Attachment MetadataARead-onlyIdempotentInspect
Use this to inspect a temporary Sending attachment_id before sending. It returns metadata only, not file bytes.
Inputs: attachment_id (required). Returns: result
qubrics_sending_get_connectionGet Sending ConnectionARead-onlyIdempotentInspect
Validate the current Sending credential and read its team, connection label and permissions. Requires email.send. This does not send email or check credits or provider readiness.
Inputs: If-None-Match. Returns: result
qubrics_sending_send_emailSend EmailAInspect
Use this to send one outbound email through the sending API. For attachments, call sending_upload_attachment first for local/tiny content or sending_create_attachment_upload for delegated file PUTs, then pass attachments as attachment_id refs. Inline base64 is only for tiny generated content. Include an Idempotency-Key so retries do not create duplicate sends.
Inputs: to (required), from (required), subject (required), html_body (required), +9 more. Returns: result
qubrics_sending_send_email_batchSend Email BatchAInspect
Use this to send multiple outbound emails in one request. For attachments, prefer uploaded attachment_id refs; avoid inline base64 except for tiny generated content. Use it only when the user confirms every recipient and message.
Inputs: messages (required), Idempotency-Key. Returns: result
qubrics_sending_upload_attachmentUpload AttachmentAInspect
Use this before sending a Sending API attachment. For real files use sending_create_attachment_upload and PUT the file outside model context. Inline content_base64 is a last resort for tiny agent-authored files only and is capped at 32 KiB decoded.
Inputs: filename (required), content_type, content_base64, idempotency_key. Returns: object
sending_create_attachment_uploadCreate Attachment UploadAInspect
Use this when a remote or shell-capable agent needs a short-lived upload URL for an outbound Sending API attachment. Provide filename, content_type, and exact size_bytes, PUT the file bytes outside model context with the returned headers, then pass the returned attachment_id to sending_send_email.
Inputs: filename (required), size_bytes (required), sha256, content_type, +1 more. Returns: result
sending_get_attachmentGet Attachment MetadataARead-onlyIdempotentInspect
Use this to inspect a temporary Sending attachment_id before sending. It returns metadata only, not file bytes.
Inputs: attachment_id (required). Returns: result
sending_get_connectionGet Sending ConnectionARead-onlyIdempotentInspect
Validate the current Sending credential and read its team, connection label and permissions. Requires email.send. This does not send email or check credits or provider readiness.
Inputs: If-None-Match. Returns: result
sending_send_emailSend EmailAInspect
Use this to send one outbound email through the sending API. For attachments, call sending_upload_attachment first for local/tiny content or sending_create_attachment_upload for delegated file PUTs, then pass attachments as attachment_id refs. Inline base64 is only for tiny generated content. Include an Idempotency-Key so retries do not create duplicate sends.
Inputs: to (required), from (required), subject (required), html_body (required), +9 more. Returns: result
sending_send_email_batchSend Email BatchAInspect
Use this to send multiple outbound emails in one request. For attachments, prefer uploaded attachment_id refs; avoid inline base64 except for tiny generated content. Use it only when the user confirms every recipient and message.
Inputs: messages (required), Idempotency-Key. Returns: result
sending_upload_attachmentUpload AttachmentAInspect
Use this before sending a Sending API attachment. For real files use sending_create_attachment_upload and PUT the file outside model context. Inline content_base64 is a last resort for tiny agent-authored files only and is capped at 32 KiB decoded.
Inputs: filename (required), content_type, content_base64, idempotency_key. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 104 tools
The set contains literal duplicates: every `mailbox_*` tool is repeated as `qubrics_mailbox_*` (and `sending_*` as `qubrics_sending_*`) with byte-identical descriptions, so an agent has no basis to choose between them. On top of that, several near-variants overlap heavily (mailbox_get_attachment vs mailbox_read_attachment vs mailbox_get_attachment_text vs mailbox_request_attachment_text; list_body vs list_content vs get_message).
Names mix three prefix families (bare `mailbox_`, `qubrics_mailbox_`, `sending_`, `qubrics_sending_`) with no discernible rule for when the prefix is applied. The verb_noun portion is mostly consistent, but the duplicated prefixed/unprefixed twins make the naming scheme arbitrary and unpredictable.
104 tools for what is effectively a ~35-tool mail/calendar/sending API is an extreme mismatch, and most of the excess is pure duplication rather than added capability. This bloats the tool list, wastes context, and multiplies the chance of misselection.
The underlying domain coverage is genuinely broad: messages (list/get/body/content/snippets/count/batch get/update/delete), drafts full lifecycle incl. scheduling, calendar and events CRUD plus change sync, attachments (upload/download/extract), folders, identities, threads, sender choices, and outbound sending with batch. Minor gaps exist (no explicit reply/forward tool outside draft `source.action`, no message move-as-standalone beyond batch update), but core workflows are covered.
Maintenance
Related MCP Connectors
Hosted email for AI agents: create inboxes, send, receive, and reply over MCP with scoped API keys
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Real email inboxes for AI agents: register, receive, read and send mail over MCP. Free to receive.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for LobsterMail — gives AI agents email tools. Create inboxes, send and receive email, search messages, and manage webhooks.119 npmMIT
- AlicenseAqualityDmaintenanceMCP server for Sendook - an AI email communication platform. Enables AI agents to send and receive emails, manage inboxes, threads, and webhooks programmatically.16MIT
- AlicenseBqualityBmaintenanceOfficial mailbox.bot MCP server for AI agents. Send letters, certified mail and postcards, and give an agent its own street address + postal mailbox number. Agent receiving virtual mailboxes with a real street address are live now at $15/mo in Manhattan Beach, CA. Sandbox keys, approval controls, tracking and webhooks.55144 npm2MIT
- AlicenseBqualityCmaintenanceThe email API your AI agent can actually use. A Model Context Protocol server for Send16 that gives Claude, Cursor, and any MCP client 79 tools to send transactional & marketing email, manage contacts, audiences, segments, automations, templates, the inbox, suppressions, and webhooks.7968 npmMIT