Skip to main content
Glama
Sendmux Email Inbox API + Sending

Sendmux Email Inbox API + Sending

Official
by qubrics

Email Inbox API + Sending by Qubrics

PyPI version Python versions PyPI downloads Licence

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

Related MCP server: sendook-mcp

Requirements

  • Python 3.10 or newer.

  • A send-capable smx_mbx_* key or owner-approved Sending-resource smx_agent_* token for Sending tools.

  • A mailbox-scoped smx_mbx_* key or scoped smx_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-mcp

Usage

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-sending

Run 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-mcp

Run 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-mcp

The 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 stdio

http 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

QUBRICS_MCP_SURFACES

required for qubrics-mcp; wrapper commands select one surface

API key fallback

QUBRICS_API_KEY

accepted for compatible single-key setups

Mailbox API key

QUBRICS_MAILBOX_API_KEY

required when mailbox is selected unless a compatible fallback is provided

Management API key

QUBRICS_MANAGEMENT_API_KEY

required when management is selected unless a compatible fallback is provided

Sending API key

QUBRICS_SENDING_API_KEY

required when sending is selected unless the fallback key is a send-capable smx_mbx_* key or owner-approved Sending-resource smx_agent_* token

App API base URL

QUBRICS_APP_BASE_URL

https://app.qubrics.com/api/v1

Sending API base URL

QUBRICS_SENDING_BASE_URL

https://smtp.qubrics.com/api/v1

Transport

QUBRICS_MCP_TRANSPORT

stdio

HTTP host

QUBRICS_MCP_HOST

127.0.0.1

HTTP port

QUBRICS_MCP_PORT

8765

HTTP path

QUBRICS_MCP_PATH

/mcp

HTTP bearer token

QUBRICS_MCP_HTTP_BEARER_TOKEN

required for HTTP unless opt-out is enabled

Allow unauthenticated HTTP

QUBRICS_MCP_ALLOW_UNAUTHENTICATED_HTTP

false

Allowed browser origins

QUBRICS_MCP_ALLOWED_ORIGINS

no browser origins

Snapshot directory override

QUBRICS_MCP_OPENAPI_INPUT_DIR or OPENAPI_INPUT_DIR

packaged snapshots

App snapshot override

QUBRICS_MCP_APP_OPENAPI

packaged app snapshot

Sending snapshot override

QUBRICS_MCP_SENDING_OPENAPI

packaged sending snapshot

Request timeout

QUBRICS_MCP_TIMEOUT_SECONDS

30

Retry attempts

QUBRICS_MCP_RETRY_MAX_ATTEMPTS

3

Retry time budget, in seconds

QUBRICS_MCP_RETRY_MAX_ELAPSED_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 scoped smx_agent_* token. Agent tokens remain limited by server-side scopes; pre-claim self-registered agent tokens do not include email.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-resource smx_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:

  1. Call qubrics_mailbox_read_attachment with message_id and attachment_id when you need the attachment contents.

  2. For small text-like attachments, read the returned text.

  3. For binary or oversized attachments, use the returned resource_link / download_url promptly outside model context.

  4. Use qubrics_mailbox_get_attachment only 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=true for hosted MCP or shell-capable agents; upload the file to the returned URL with exact headers and no API key, then send with the returned blob_id.

  • content_base64 only for tiny agent-authored files, capped at 32 KiB decoded. 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-mcp

  • qubrics-mcp-mailbox

  • qubrics-mcp-management

  • qubrics-mcp-sending

  • qubrics-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 tools
mailbox_batch_delete_messagesBatch Delete MessagesA
Destructive
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 MessagesA
Idempotent
Inspect

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 ScheduleA
Idempotent
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 calendarA
DestructiveIdempotent
Inspect

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 EventA
DestructiveIdempotent
Inspect

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 DraftA
Destructive
Inspect

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 MetadataA
Read-onlyIdempotent
Inspect

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 TextA
Read-onlyIdempotent
Inspect

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 CalendarA
Read-onlyIdempotent
Inspect

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 EventA
Read-onlyIdempotent
Inspect

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 ChangesA
Read-onlyIdempotent
Inspect

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 ChangesA
Read-onlyIdempotent
Inspect

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 ConnectionA
Read-onlyIdempotent
Inspect

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 DraftA
Read-onlyIdempotent
Inspect

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 IdentityA
Read-onlyIdempotent
Inspect

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 ProfileA
Read-onlyIdempotent
Inspect

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 MessageA
Read-onlyIdempotent
Inspect

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 choicesB
Read-onlyIdempotent
Inspect

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 SessionA
Read-onlyIdempotent
Inspect

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 ThreadA
Read-onlyIdempotent
Inspect

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 BodyA
Read-onlyIdempotent
Inspect

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 EventsA
Read-onlyIdempotent
Inspect

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 CalendarsA
Read-onlyIdempotent
Inspect

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 ContentA
Read-onlyIdempotent
Inspect

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 DraftsA
Read-onlyIdempotent
Inspect

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 FoldersA
Read-onlyIdempotent
Inspect

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 MailboxesA
Read-onlyIdempotent
Inspect

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 IdentitiesA
Read-onlyIdempotent
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 ThreadsB
Read-onlyIdempotent
Inspect

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 AttachmentA
Read-onlyIdempotent
Inspect

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 TextA
Idempotent
Inspect

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 SnippetsA
Read-onlyIdempotent
Inspect

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 EventA
Idempotent
Inspect

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 IdentityA
Idempotent
Inspect

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 MessageA
Read-onlyIdempotent
Inspect

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 MessagesA
Destructive
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 MessagesA
Idempotent
Inspect

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 ScheduleA
Idempotent
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 calendarA
DestructiveIdempotent
Inspect

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 EventA
DestructiveIdempotent
Inspect

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 DraftA
Destructive
Inspect

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 MetadataA
Read-onlyIdempotent
Inspect

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 TextA
Read-onlyIdempotent
Inspect

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 CalendarA
Read-onlyIdempotent
Inspect

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 EventA
Read-onlyIdempotent
Inspect

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 ChangesA
Read-onlyIdempotent
Inspect

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 ChangesA
Read-onlyIdempotent
Inspect

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 ConnectionA
Read-onlyIdempotent
Inspect

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 DraftA
Read-onlyIdempotent
Inspect

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 IdentityA
Read-onlyIdempotent
Inspect

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 ProfileB
Read-onlyIdempotent
Inspect

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 MessageA
Read-onlyIdempotent
Inspect

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 choicesB
Read-onlyIdempotent
Inspect

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 SessionA
Read-onlyIdempotent
Inspect

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 ThreadA
Read-onlyIdempotent
Inspect

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 BodyA
Read-onlyIdempotent
Inspect

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 EventsA
Read-onlyIdempotent
Inspect

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 CalendarsA
Read-onlyIdempotent
Inspect

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 ContentB
Read-onlyIdempotent
Inspect

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 DraftsA
Read-onlyIdempotent
Inspect

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 FoldersB
Read-onlyIdempotent
Inspect

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 MailboxesA
Read-onlyIdempotent
Inspect

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 IdentitiesA
Read-onlyIdempotent
Inspect

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 MessagesA
Read-onlyIdempotent
Inspect

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 MessagesB
Read-onlyIdempotent
Inspect

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 ThreadsA
Read-onlyIdempotent
Inspect

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 AttachmentA
Read-onlyIdempotent
Inspect

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 TextA
Idempotent
Inspect

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 SnippetsA
Read-onlyIdempotent
Inspect

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 EventA
Idempotent
Inspect

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 IdentityA
Idempotent
Inspect

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 MessageA
Read-onlyIdempotent
Inspect

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 MetadataA
Read-onlyIdempotent
Inspect

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 ConnectionA
Read-onlyIdempotent
Inspect

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 MetadataA
Read-onlyIdempotent
Inspect

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 ConnectionA
Read-onlyIdempotent
Inspect

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

    B3.1/5.0

    Scored across 104 tools

    Disambiguation1/5

    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).

    Naming Consistency2/5

    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.

    Tool Count1/5

    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.

    Completeness4/5

    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

    ActivityActive
    ResponsivenessUsually handled

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      MCP server for Sendook - an AI email communication platform. Enables AI agents to send and receive emails, manage inboxes, threads, and webhooks programmatically.
      16
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Official 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.
      55
      144 npm
      2
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      The 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.
      79
      68 npm
      MIT