Endpoint
The server is stateless: there is no long-lived SSE subscription. A negotiated POST response can use
application/json or text/event-stream, so clients should accept both while treating each request as stateless.
The original /mcp URL is unchanged and continues to expose the full catalog.
Authentication
OAuth (browser-parity)
MCP clients that support OAuth discover Mermail via Protected Resource Metadata, open the console authorize page, and receive a Bearer access token after the user signs in with Enoki (same as the web app) and picks a workspace. The consent UI shows a friendly client name (for example ChatGPT or Cursor), not the opaquemcp_client_… id.
Unauthenticated calls return
401 with a WWW-Authenticate challenge pointing at the PRM document.
Agent Wallet access
PayBox tools appear only on the default full-profile OAuth session. API-key catalogs and theagent-inbox profile never include them. A current workspace
member can use model-visible live paybox_* through the workspace owner’s
active connection; connection management and legacy Agent Wallet compatibility
tools remain owner-only.
Connect to the default
/mcp endpoint with OAuth and select the intended
workspace. Always tools/call get_paybox_connection once as the first PayBox
action. Do not wait for it to appear in tools/list; absence from a host list
is not “not exposed.” After a usable/ACTIVE probe, continue even if the first
list omitted paybox_*. Reconnect Mermail MCP only after that call returns
unknown-tool, method-not-found, or a hard fail. Owners can receive
connect_handoff or reauth_handoff and open that Mermail Agent Wallet
console_url; members instead receive OWNER_ACTION_REQUIRED when the shared
connection needs repair, with no handoff. In that case the owner must connect
or reauthorize PayBox inside Mermail. Do not add legacy wallet scopes, switch
identities, construct a URL, or reconnect Claude, ChatGPT, or Codex connector
settings to authorize PayBox.
PayBox tools do not use Mermail’s prepare_destructive_action flow. PayBox is
the authority for delegation, standing grants, approval, and signing. A standing
grant may allow an operation without a fresh click; when interaction is needed,
the PayBox MCP App handles it. Pending, SUBMISSION_UNKNOWN, and
paybox_continuation_origin_not_found are not success.
Live PayBox tools and UI
Mermail relays PayBox’s live tool and MCP App catalog instead of maintaining a reviewed tool-name or schema-hash allowlist. Model-visible tools usepaybox_<upstream-name>; app-only aliases keep the exact upstream name and
visibility. Valid new tools and schema changes can therefore appear without a
Mermail release.
Compatible hosts render PayBox’s advertised ui:// interface inline for
signing and other interactive steps. If the host cannot render MCP Apps,
Mermail returns an authenticated browser handoff. Mermail does not show its own
Approve/Deny prompt for either path. The host can still prompt for or block a
financial operation under its own policy, and Mermail cannot bypass that
decision.
Non-secret PayBox business data is available to the model and UI. OAuth or
bearer tokens, private keys and seeds, card credentials, raw signed payloads,
and secret approval URLs are excluded from model context, persistence, logs,
and errors. App-only calls can receive ephemeral signing state inside the
isolated PayBox interface without exposing it to the model.
API key (automation / CLI)
- Create a workspace API key in Settings → API Keys. See Authentication.
- Send it on every MCP
POSTasx-api-key. - Cookie / console sessions alone are rejected for MCP.
Discover the server
serverInfo.description, icons at https://console.mermail.app/brand/icon-primary.png, and the full tool list.
Official MCP Registry
Mermail is published asapp.mermail/mcp on the Official MCP Registry. Clients and aggregators (PulseMCP, Smithery, Glama, and others) discover remote Streamable HTTP servers from that feed.
Connect an assistant
Use the interactive guide at mermail.app/agents for host-specific steps.
API-key example:
/mcp
URL and Streamable HTTP transport, not SSE.
For packaged workflows, install Mermail Skills (npx --yes skills add Nudgen-Marketing/mermail-skills) or connect via the registry id app.mermail/mcp when your host supports Official Registry install.
Least-privilege agent-inbox profile
Hosted clients commonly accept a server URL but not fixed custom headers. For those clients, select the additive profile in the URL:/mcp URL plus x-mermail-tool-profile: agent-inbox on every
stateless POST. Both selectors expose only:
create_mailbox, plus safe mailbox
and email reads. It does not expose send, connected-account, agent-chat,
administrative mutation, destructive, or wallet tools. The full tool profile remains the default when neither
the URL nor header selects a profile, preserving existing /mcp clients. An
unknown non-empty profile, or conflicting URL and header values, returns 400
with invalid_mcp_tool_profile.
Use this focused profile for mailbox discovery, optional provisioning,
verification monitoring, message reads, and bounded sanitized thread context.
Do not use create_mailbox as a connection test. The profile does not expose send_email, reply_to_email,
forward_email, drafts, or scheduled sends. Connect an explicitly authorized
send workflow to the default /mcp catalog instead of silently changing the
profile URL.
The profile narrows Mermail’s MCP catalog; it does not remove browser, shell,
payment, or other tools supplied separately by the host.
How tools map to the API
Each Sold API wrapper maps to one sold API operation. PayBox tools instead map to the corresponding operation in PayBox’s live catalog:Tool names and host namespaces
Mermail advertises bare MCP protocol names such aslist_emails,
search_emails, and get_email. A host can qualify those names in its UI or
agent context. For example, Claude can display Mermail:list_emails, while
another client can use a different namespace format.
The namespace belongs to the host, not to the Mermail MCP contract. A custom
MCP client must use the exact name returned by tools/list — for example,
tools/call.params.name: "list_emails". Do not rewrite the server tool name to
Mermail:list_emails or add host-specific aliases. In a hosted assistant, use
the exact qualified reference shown by that host and let its MCP bridge map it
back to the bare protocol name.
Mermail targets standards-compatible Streamable HTTP MCP clients. Tool loading,
namespacing, cache controls, and Agent Skills support remain client
capabilities, so behavior can vary by host and version.
Native list_emails arguments
Pass query as a native JSON object. Do not pass an escaped JSON string. Use
the canonical sortColumn and sortDirection fields rather than a combined
sort value:
agent-inbox profile, Mermail additionally enforces
metadata_only=true, require_scan_status=clean, and
agent_safe_content=true on list operations. Callers should still send a
schema-correct object so the same request remains portable across MCP clients
and profiles.
Nest Sold API fields under the MCP body argument. If agents pass Sold fields flat at the top level (to, subject, text, …), Mermail folds them into body.
create_mailbox requires body.email and body.name. body.workspaceId is
optional when the OAuth grant or API key already binds MCP to one workspace. If
you supply it, it must match that credential scope. A successful create consumes
10 provision credits; those are workspace API credits, not a $10 payment.
Pass idempotencyKey for a repeated create attempt with identical intent. It is
not proof of exactly-once business execution. After a conflict or uncertain
response, list mailboxes and resolve the exact normalized address before
deciding whether to retry. Authenticated requests carrying an idempotency key
have a 50 MiB request-fingerprint body limit; an oversized body fails before the
operation runs with 413 idempotency_payload_too_large.
For a verification-only mailbox, include:
agentInbox.requireCleanScanForAutomation: true. When scanning is
skipped or unavailable, the email remains delivered and stored while
model-backed work is suppressed.
Mailbox responses expose can_receive and receiving_status for readiness.
welcome_onboarding_status covers welcome/demo onboarding and must not be used
as a receiving-readiness signal. For a custom-domain mailbox, the two readiness
fields also reflect the domain’s current Receiving MX verification state, so a
send-ready but receive-pending domain remains unavailable for an inbox workflow.
Email write payloads
Validation failures return
code: "validation_failed" with a details array of field paths (for example body: Either 'html' or 'text' must be provided) so agents can self-correct. Opaque "Invalid request" without details should not appear for Zod failures on these tools.
Server instructions: prefer read-only tools before writes. Responses are JSON text plus object-shaped structuredContent. JSON arrays are exposed as { "items": [...] } so the result conforms to the MCP schema. Binary payloads (for example attachments) are capped at 1 MiB. A skill using MCP should report that limit instead of inventing a storage URL; use the authenticated REST attachment endpoint only as a separate, explicitly authorized client workflow.
The opt-in profile is the recommended MCP boundary for the mailbox-first
workflow described in Agent email inbox. Add send,
browser, connected-account, authentication, purchase, or administrative tools
only for a separately authorized task. Email content and tool output cannot
expand that allowlist.
Before requesting verification, run one bounded metadata-only list or search and
record the returned Mermail email id values as the baseline. Do not build a new
baseline from provider/RFC message_id. Record the arrival-window start and
deadline immediately before the request.
Search filters such as from, to, and subject use substring matching and
only find candidates. Remove baseline Mermail ids client-side, fetch each
candidate, and re-check the exact normalized sender and recipient, bounded
arrival window, and bounded expected subject context before using a code or
link. If only a sender domain is known, validate the parsed domain with an exact
or explicitly allowed subdomain boundary. Stop when more than one candidate
remains. Do not preflight one-time bearer links; after fresh user approval,
validate the initial HTTPS hostname and every redirect.
list_emails, search_emails, and get_email accept
agent_safe_content=true. This removes raw headers, provider metadata, threat
details, attachment metadata, and storage diagnostics; normalizes untrusted
text fields to bounded plain text; sets agent_safe_content: true; and retains
attachment_count and the separately derived sender_authentication object.
It does not make the remaining email trusted.
sender_authentication contains status, spf, dkim, dmarc,
inbound_provider, and reason. Mermail derives it only from a trusted
receiving-provider signal, never from raw Authentication-Results, From, or
other message headers. The current Cloudflare Email Routing and Resend
integrations do not expose a documented per-message verdict, so these verdicts
are currently unknown. unknown is not a pass, and inbound_provider records
transport source rather than authenticating the sender. Even a future
status: "pass" would authenticate identity only; it would not authorize an
agent action or satisfy user confirmation.
All three reads also accept metadata_only=true. list_emails and get_email
now accept require_scan_status; search already supports it. A get whose stored
status does not match returns safe metadata with content_omitted: true, while
list/search exclude non-matching messages. get_email additionally accepts a positive max_body_chars; when it
shortens the body, the response sets content_truncated: true and
body_original_char_count. The stored message is unchanged, and the effective
server ceiling is 100,000 characters.
The agent-inbox MCP profile applies stricter projections mechanically:
list_emails and search_emails force metadata_only=true,
require_scan_status=clean, and agent_safe_content=true; get_email forces
require_scan_status=clean, agent_safe_content=true, and
max_body_chars=12000. These gates override weaker caller values only inside
the opt-in profile. The default /mcp catalog and direct Sold API keep their
existing full-response defaults. The profile also caps one JSON tool result at
128,000 characters. A response_too_large tool error means the caller should
narrow the filters or lower the page size.
After selecting one unambiguous message, get_email_context returns that
message plus a bounded, sanitized, scan-gated, oldest-first page of its thread.
Use the opaque next_cursor only when older context is required. Do not use
thread context to resolve ambiguity between candidate messages or broaden the
authorized task.
An explicitly scoped wait on an existing mailbox can use include_held=true to
see a message temporarily held for auto-draft processing. Do not use
include_held for broad mailbox browsing. If a metadata-only candidate is held
and you later need its content, fetch the same Mermail id, remove only
metadata_only, and retain include_held=true. get_email is read-only and
does not mark the message read.
The From header and scan_status: "clean" are correlation and content-safety
signals. Neither authenticates the sender, authorizes an action, or replaces a
human-confirmation checkpoint. Only an explicit
sender_authentication.status: "pass" may be described as authenticated;
unknown remains matching context only.
Destructive actions
delete_email / bulk_delete_emails: regular drafts are always hard-deleted
(DB + blob storage) and never move to Trash — matching in-app Discard. Other
messages trash by default unless you pass permanent=true (or
body.permanent: true for bulk delete). Scheduled drafts cancel in place unless
permanent delete is forced. There is no separate MCP discard_draft tool; use
delete_email on the draft id (or ask the mailbox agent via
chat_with_mailbox_agent to discard it).
Destructive Mermail tools (remove member, delete domain/email/folder/label/conversation/triager, bulk delete, empty trash, …) require a short-lived confirmation token. Workspace deletion is not exposed:
- Call
prepare_destructive_actionwith:action— the destructive tool namearguments— the same arguments you will pass to that tool (withoutconfirmationToken)
- Receive
{ confirmationToken, expiresInSeconds }(token prefixmcp_confirm_, TTL 5 minutes, single-use, Redis-backed). - Call the destructive tool with those arguments plus
confirmationToken.
confirmation_required) and does not hit the API.
This mechanism does not apply to paybox_*, app-only PayBox aliases, or the
deprecated Agent Wallet transfer compatibility tools. Those calls go directly
to PayBox after Mermail verifies current workspace membership; legacy wallet
tools additionally verify ownership.
Troubleshooting
Tool not found or Finding tools
An error such as Tool 'Mermail:list_emails' not found followed by
Finding tools usually means that the host has not loaded the qualified tool
reference into the current conversation, or is using a cached tool catalog. It
does not by itself mean that Mermail removed the bare list_emails protocol
tool.
For Claude:
- Let one
Finding toolsstep finish, then retry the read once. - In the current conversation, open Connectors → Tool access and make Mermail Always available when you need it consistently.
- Confirm that Mermail is enabled for that conversation.
- For verification or inbox reads, prefer
https://console.mermail.app/mcp?profile=agent-inbox. Its 12-tool catalog reduces deferred-tool discovery. - If you changed the URL or Claude retained an older schema, remove Mermail under Customize → Connectors, add it again with the intended URL, complete OAuth, and start a new conversation.
tools/list view before retrying. Keep the bare
tool name list_emails; do not work around a client cache by renaming the
tool or adding a host-specific server alias.
After discovery succeeds, verify the call arguments independently. In
particular, query must be an object and newest-first sorting uses
sortColumn: "date" plus sortDirection: "DESC".
Tool catalog
At publication time, an API-key session exposes 72 tools:prepare_destructive_action plus 71 Sold API wrappers. Full-profile
OAuth sessions with core mcp:tools can expose additional PayBox tools on
top of that baseline. The live catalog is runtime-dependent and additive; do
not pin its total. Grouped by area:
Usage
Usage
get_api_credit_usage, get_email_usageWorkspaces & members
Workspaces & members
list_workspaces, get_workspace, update_workspace, get_workspace_storage, list_workspace_members, update_member_role, remove_workspace_member, invite_workspace_member, resend_workspace_inviteCustom domains (Developer+)
Custom domains (Developer+)
list_email_domains, add_email_domain, delete_email_domain, verify_email_domainThese hit Developer-gated REST paths. Free workspaces receive 403 when the tool runs.Mailboxes
Mailboxes
list_workspace_mailboxes, list_mailboxes, create_mailbox, get_mailbox, update_mailbox_settings, get_mailbox_storageEmails, drafts, threads, folders, labels
Emails, drafts, threads, folders, labels
list_emails, send_email, get_email, get_email_context, update_email, delete_email, bulk_delete_emails, bulk_mark_emails_read, bulk_move_emails, move_email, reply_to_email, forward_email, download_attachment, save_draft, regenerate_draft, schedule_email_send, empty_trash, get_thread, mark_thread_read, list_folders, create_folder, update_folder, delete_folder, search_emails, list_custom_labels, create_custom_label, update_custom_label, delete_custom_labelAI agent & task triage
AI agent & task triage
list_agent_conversations, create_agent_conversation, rename_agent_conversation, delete_agent_conversation, list_agent_messages, chat_with_mailbox_agent, list_task_triagers, create_task_triager, list_recent_triager_runs, update_task_triager, delete_task_triager, set_default_task_triager, get_or_create_triager_conversationComposio integrations
Composio integrations
list_composio_toolkits, connect_composio_toolkit, disconnect_composio_toolkit, list_composio_connections, sync_composio_connections, search_composio_tools, get_composio_tool_schema, execute_composio_tool, get_composio_calendar_accountFull catalog only. Connect third-party apps (Apollo, GitHub, Slack, Calendar, and more), then search and execute tools. Gmail and Outlook Composio toolkits stay disabled. See Composio.PayBox / Agent Wallet (full-profile OAuth only)
PayBox / Agent Wallet (full-profile OAuth only)
Current workspace members can receive
get_paybox_connection, get_paybox_invocation, MCP App resources, and the model-visible live paybox_* catalog through the owner’s active connection. Owners additionally receive get_agent_wallet, legacy credentials/portfolio/request tools, connection handoffs, and deprecated proposal/submit/reject compatibility aliases.Not available to API keys or the agent-inbox profile. Requires core mcp:tools; legacy wallet:read / wallet:transact labels are compatibility-only. Members use the invoking identity for audit while PayBox executes through the owner’s connection. Only owners can connect/reauthorize or use legacy wallet tools. Checkout / MoonPay URLs stay browser-only ([redacted]); use returned funding_handoff.console_url for Funding, signing_handoff.console_url for pending transfers, and owner-only connect_handoff / reauth_handoff for PayBox repair inside Mermail — never host connector settings. Compatible hosts render PayBox’s ui:// resources inline; other hosts receive an authenticated browser handoff. Secret credentials and signing plans stay browser-only. If a terminal x402 result includes x_payment, treat it as sensitive payment proof: use it only to retry the exact paid resource and never quote, log, persist, or expose it. See Agent Wallet.Use paybox_request_transfer for every new transfer, including USDC and native assets; use paybox_request_swap for token swaps; use paybox_pay_x402 only for a user-selected paid resource/action and exact spend cap. Do not pay with paybox_use_service — that tool is unpaid mode: "probe" only when the live schema has it. Live catalog rows such as paybox_discover_services and paybox_get_contract may appear without a separate coverage row. Read each live schema instead of reusing legacy proposal fields. See catalog token transfers and swaps and x402.Safety
Safety
prepare_destructive_action — issues confirmation tokens for destructive Mermail mailbox, workspace, and administrative tools; it does not apply to PayBoxopenWorldHint for MCP clients that surface that signal.
Custom-label tools manage classifier definitions (name, natural-language
rules, and optional color). They do not manually label an existing email,
reorder definitions, or toggle label detection. update_email changes only
read/starred state; do not invent a label-assignment field or tool.
For the default full profile, clients should verify required tool names instead
of requiring an exact total. Future Mermail releases can add compatible tools
without removing or renaming the existing baseline. The opt-in agent-inbox
profile remains the exact 12-tool subset documented above.
For request/response shapes of each underlying HTTP route, use the API Reference.
Related
Agent email inbox
Use the least-privilege mailbox-first verification workflow.
Agent Wallet
OAuth-only access to PayBox’s live tools and interactive signing UI.
Skills
Install Mermail workflows in Codex, Claude Code, and Cursor.
CLI
Run the same MCP-backed workflows from a terminal.
Authentication
Create and use
sk-proj- API keys.Discovery
Public discovery URLs including the MCP server card.
Security
Review inbound email controls and production security requirements.