Skip to main content

The mails.ai MCP server

Give an AI client email tools: the hosted server, or the local one through npx.

The mails.ai MCP server gives an AI client the mails.ai API as 72 tools: sending, reading and replying, threads, drafts and labels, agents, webhooks, domains and a sandbox inbox. Use the hosted server at https://api.mails.ai/mcp, or run the server on your own machine with npx.

Hosted server

The hosted server speaks MCP over HTTP at https://api.mails.ai/mcp. A client signs in through your browser, and you approve its access on a mails.ai page, so no key goes into the client’s settings. A client can also send an API key in the Authorization header instead. Connected apps says what an app you approve may do, and how to revoke it.

The settings for Claude, Claude Code, Cursor, Codex and VS Code below are the ones the mails CLI prints with mails mcp install --client <client> --auth <oauth|key> --print, and mails mcp install --client <client> writes them for you. The key itself is never written to a file: the API key settings name the MAILS_API_KEY variable, so set MAILS_API_KEY where the client starts, and VS Code asks for the key once and keeps it in its own secret storage.

claude mcp add --transport http --scope user mails https://api.mails.ai/mcp
# Then run /mcp in Claude Code and choose mails to sign in (or: claude mcp login mails)

Local server

@mailsai/mcp-server (version 0.3.0 on npm) runs on your own machine and talks to the client over stdio. It needs Node.js 20 or newer and an API key.

In the Claude desktop app, open the Claude menu, choose Settings…, then Developer, then Edit Config. The file is ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows. Quit and restart Claude after saving.

claude_desktop_config.json
{
  "mcpServers": {
    "mails": {
      "command": "npx",
      "args": ["-y", "@mailsai/mcp-server"],
      "env": {
        "MAILS_API_KEY": "mk_test_xxxxxxxx"
      }
    }
  }
}
VariableWhat it does
MAILS_API_KEYRequired. Your API key, mk_live_… or mk_test_…. A test key sends no real mail and is never billed.
MAILS_BASE_URLThe API address. Default: https://api.mails.ai.

Try it without a key

The package has a demo that grades two emails, a normal one and a prompt-injection attack, through the same scanner every inbound message within your plan’s limits goes through. It needs no key and sends nothing.

npx -y -p @mailsai/mcp-server mails-mcp-demo

Tools

Every API operation that can be a tool is one: 72 tools, as version 0.3.0 of the server lists them. 20 are written by hand, with short names such as mails_send, and the other 52 are generated from the API’s OpenAPI document, so each takes the fields its page in the API reference lists. Before version 0.3.0 the names were dotted, as in mails.send: the server still answers a call by the old name, but lists only the new ones. Your client reads each tool’s full description and input schema from the server itself.

The server lists only the tools your key or sign-in may call, and refuses a call to any other. A tool is left out when the credential lacks its scope. mails_test_inbound is listed only for a test key, and mails_agents_verify_forwarding, which sends a real email, only for a live key. A key tied to one agent is not shown the 21 tools that act on the whole workspace, such as creating webhooks, labels or domains. An app connected by signing in, other than the mails CLI, is not shown the 5 that create API keys or webhooks, rotate a webhook’s signing secret, or list and revoke connected apps. mails_me reports how many tools the credential can use.

Sent mail

mails_send

Send an email.

Needs to, subject · Scope: send

mails_reply

Reply in-thread to a message.

Needs message_id · Scope: send

mails_forward

Forward a message to new recipients.

Needs message_id, to · Scope: send

mails_emails_list

Lists emails the workspace's agents sent or scheduled, newest first, with recipients, subject, status and timestamps.

Scope: read

mails_emails_send_batch

Sends up to 100 emails in one call, each with its own agent, recipients and content.

Needs messages · Scope: send

mails_emails_appeal

Asks for an independent second review of content the cold-email firewall refused (cold_email_prohibited), given the same agent, subject and body the refused send used.

Scope: send

mails_emails_get

Returns one sent or scheduled email by its msg_ id: recipients, subject, body, status, delivery times, tags and metadata.

Needs message_id · Scope: read

mails_emails_reschedule

Moves a scheduled email to a new send time.

Needs message_id · Scope: manage and send

mails_emails_cancel

Cancels an email that is still scheduled, so it is never sent.

Needs message_id · Scope: manage

mails_emails_raw

Returns a sent email (msg_ id) as an RFC 822 message rebuilt from what is stored: its headers and its HTML or text body, without attachments.

Needs message_id · Scope: read

Received mail

mails_list_received

List recently received messages.

Scope: read

mails_get_received

Get one received message: its text, including the extracted reply text.

Needs id · Scope: read

mails_list_replies

List recent reply events (reply.received) for an agent.

Needs agent · Scope: read

mails_list_messages

List recent cold/first-contact inbound (message.received) for an agent — senders that are NOT replying to one of your sends — together with mail that failed authentication (message.received.unauthenticated: its From domain's DMARC policy is quarantine or reject, and no DKIM signature aligned with that domain verifies), newest first.

Needs agent · Scope: read

mails_test_inbound

SANDBOX (test key only): simulate an email arriving to one of your agents, to exercise the whole two-way loop — receive → prompt-injection scan → reply — with NO live mail server and no waiting.

Needs agent, from, body_text · Scope: send · Listed only for a test key

mails_attachments_list

Lists every file in a received email (rcv_ id), embedded images included (inline: true), with filename, content type and size.

Needs message_id · Scope: read

mails_attachments_get

Returns one file from a received email.

Needs message_id, attachment_id · Scope: read

Threads

mails_list_threads

List threads (conversations) for the workspace or a specific agent.

Scope: read

mails_get_thread

Get a full thread with all messages in chronological order.

Needs thread_id · Scope: read

mails_threads_update

Marks a thread read or unread, moves it to inbox, archive, spam or trash, sets its status (open, closed, archived) or replaces its labels.

Needs thread_id · Scope: manage

mails_threads_delete

Moves a thread to trash, where mails_threads_update can move it back and where it is emptied after 30 days.

Needs thread_id · Scope: manage

Drafts

mails_create_draft

Stage a draft.

Needs agent, to · Scope: send or draft

mails_send_draft

Send a previously-created draft.

Needs draft_id · Scope: send

mails_drafts_list

Lists drafts and scheduled drafts, newest first, filtered by agent or status; next_cursor fetches the next page.

Scope: read or draft

mails_drafts_get

Returns one draft by its id: recipients, subject, body, send_at and status.

Needs draft_id · Scope: read or draft

mails_drafts_update

Edits a draft's recipients, subject, body or send_at.

Needs draft_id · Scope: manage or draft

mails_drafts_delete

Deletes a draft, or a scheduled draft before it is sent.

Needs draft_id · Scope: manage or draft

Agents

mails_list_agents

List the agents in the workspace.

Scope: read

mails_create_agent

Create a new agent: on the workspace's mails.ai address (name), or at an address on a domain the workspace has verified (address), with forwarding: true when the mail service that already hosts that address forwards its mail to the agent.

Scope: manage · Not listed for a key tied to one agent

mails_agents_get

Returns one agent by name or agt_ id: its address, status, send limits, recipient allowlist and blocklist, whether its new mail is read for intent, and its unread count.

Needs agent · Scope: read

mails_agents_update

Changes an agent's status (active or paused), its daily and hourly send limits, its recipient allowlist and blocklist, whether its new mail is read for intent, or forwarding mode for an agent at an address on the workspace's own domain (turning it on or off starts its forwarding test again).

Needs agent · Scope: manage

mails_agents_archive

Archives an agent: it can no longer send, and its address is kept and never reused.

Needs agent · Scope: manage

mails_agents_verify_forwarding

Sends one test email, from mails.ai, to the own address of an agent in forwarding mode (support@acme.com), and returns the agent.

Needs agent · Scope: manage · Not listed for a test key

mails_agents_inbox

Returns an agent's unread count, its thread and unread counts per folder and per label, and the time of its latest message.

Needs agent · Scope: read

Labels

mails_labels_list

Lists the workspace's labels (at most 200) by name, each with its id and colour.

Scope: read

mails_labels_create

Creates a label with a name (unique in the workspace, ignoring case) and a colour from a fixed palette of 12.

Needs name · Scope: manage · Not listed for a key tied to one agent

mails_labels_get

Returns one label by its lbl_ id.

Needs label_id · Scope: read

mails_labels_update

Renames a label or changes its colour.

Needs label_id · Scope: manage · Not listed for a key tied to one agent

mails_labels_delete

Deletes a label and takes it off every thread that carries it.

Needs label_id · Scope: manage · Not listed for a key tied to one agent

Search

mails_search_mail

Full-text search over received and sent mail (subject, body and addresses), newest first; every word must match.

Scope: read

Events

mails_get_event

Get one event by its id (evt_…), whatever its type: received mail, a send, a draft or a suppression.

Needs event_id · Scope: read

mails_events_list

Lists events newest first (message.sent, message.delivered, message.bounced, reply.received, message.received, thread.updated and the rest), of one type, for one agent or since a time if asked.

Scope: read

mails_events_redeliver

Sends a stored event again to every webhook endpoint subscribed to its type.

Needs event_id · Scope: manage · Not listed for a key tied to one agent

Webhooks

mails_webhooks_list

Lists the workspace's webhook endpoints with their URL, event types, description and whether each is active.

Scope: read

mails_webhooks_create

Registers an HTTPS endpoint that receives the workspace's events: every event, or the listed types.

Needs url · Scope: manage · Not listed for a key tied to one agent or for a connected app

mails_webhooks_get

Returns one webhook endpoint by its id.

Needs webhook_id · Scope: read

mails_webhooks_update

Changes a webhook endpoint's URL, event types, description or whether it is active.

Needs webhook_id · Scope: manage · Not listed for a key tied to one agent

mails_webhooks_delete

Deletes a webhook endpoint and its delivery history.

Needs webhook_id · Scope: manage · Not listed for a key tied to one agent

mails_webhooks_rotate_secret

Issues a new signing secret for a webhook endpoint, returned only this once.

Needs webhook_id · Scope: manage · Not listed for a key tied to one agent or for a connected app

mails_webhooks_list_deliveries

Lists a webhook endpoint's delivery attempts, newest first, each with its event, attempt number, status, HTTP status, the start of the endpoint's answer (or why it could not be reached), and when it was made, delivered and next retried.

Needs webhook_id · Scope: read

mails_webhooks_test

Sends a synthetic webhook.test event to a webhook endpoint, signed like a real delivery, and returns whether it answered with a 2xx (ok), its HTTP status (null when it could not be reached) and the start of its answer.

Needs webhook_id · Scope: manage · Not listed for a key tied to one agent

mails_webhooks_replay_delivery

Sends the event behind a past delivery attempt again.

Needs delivery_id · Scope: manage · Not listed for a key tied to one agent

Domains

mails_domains_list

Lists the workspace's custom sending domains with their verification status and DNS records.

Scope: read

mails_domains_create

Registers a custom sending domain (paid plans) and returns the DNS records to create at the domain's registrar.

Needs domain · Scope: manage · Not listed for a key tied to one agent

mails_domains_get

Returns one custom domain with its overall and per-record verification status.

Needs domain_id · Scope: read

mails_domains_delete

Removes a custom domain.

Needs domain_id · Scope: manage · Not listed for a key tied to one agent

mails_domains_verify

Checks every DNS record of a custom domain now and returns the domain with its per-record and overall status.

Needs domain_id · Scope: manage · Not listed for a key tied to one agent

API keys

mails_api_keys_list

Lists the workspace's API keys by prefix, name, mode, scopes and agent, with when each was last used.

Scope: read

mails_api_keys_create

Creates an API key with the given scopes and mode, optionally tied to one agent or expiring.

Scope: manage · Not listed for a connected app

mails_api_keys_revoke

Revokes an API key at once: anything using it stops working.

Needs key_id · Scope: manage · Not listed for a key tied to one agent

Suppression

mails_check_suppression

Check if an address is suppressed.

Needs address · Scope: read

mails_allowlist_address

Override a complaint or unsubscribe suppression for one address, with an attestation of at least 20 characters that the recipient agreed to receive the mail.

Needs address, attestation · Scope: manage · Not listed for a key tied to one agent

mails_suppressions_list

Lists the workspace's allowlist: addresses mail may go to despite a suppression, each with its attestation.

Scope: read

mails_suppressions_revoke

Removes an allowlist entry by its id, so the suppression applies to that address again.

Needs entry_id · Scope: manage · Not listed for a key tied to one agent

Account

mails_get_reputation

Get an agent's sending-reputation health (0-1) + its 30-day bounce/complaint/reply counts.

Needs agent · Scope: read

mails_get_usage

Get the current billing period usage.

Scope: read · Not listed for a key tied to one agent

mails_me

Who am I — returns the authenticated workspace, agent, tier, and API-key scopes, with this server's version and how many tools this credential can use.

Scope: any

mails_metrics_get

Returns counts of sent, delivered, bounced, complained, received and reply messages per day or per hour (UTC), for the workspace or one agent.

Scope: read

mails_logs_list

Lists the workspace's audit log of changes, newest first, filtered by category or action if asked.

Scope: read · Not listed for a key tied to one agent

mails_health_check

Returns whether the mails.ai API is up (healthy or degraded) and its clock.

Scope: none

Connected apps

mails_connected_apps_list

Lists the apps connected to the workspace by signing in (the mails CLI, Claude, ChatGPT, Cursor …) with the scope each was approved for, when it was last used, and the API keys, webhook endpoints and signing secrets it left behind.

Scope: manage · Not listed for a key tied to one agent or for a connected app

mails_connected_apps_revoke

Ends a connected app's sign-in at once: its tokens stop working and it has to be approved again.

Needs app_id · Scope: manage · Not listed for a key tied to one agent or for a connected app

Operations without a tool

Four API operations are not tools, for these reasons:

  • GET /v1/events/stream: a server-sent event stream that stays open, which a tool call cannot return; mails_events_list with since reads the same events.
  • POST /v1/billing/portal: its answer is a billing or checkout link, and MCP tool output carries no plan, upgrade or checkout links.
  • GET /v1/unsubscribe: the page a recipient lands on from an unsubscribe link, authorised by the link's token rather than a credential.
  • POST /v1/unsubscribe: the one-click unsubscribe a recipient's mail client sends, authorised by the link's token rather than a credential.

Next steps

Was this page helpful?