The mails.ai MCP server
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)claude mcp add --transport http --scope user mails https://api.mails.ai/mcp --header 'Authorization: Bearer ${MAILS_API_KEY}'Claude adds remote servers as connectors and signs in through the browser. Open Add the mails connector: Claude shows its Add custom connector form with the name and address filled in. Choose Add, then Connect, and approve the sign-in.
{
"mcpServers": {
"mails": {
"url": "https://api.mails.ai/mcp"
}
}
}{
"mcpServers": {
"mails": {
"url": "https://api.mails.ai/mcp",
"headers": {
"Authorization": "Bearer ${env:MAILS_API_KEY}"
}
}
}
}Or add it with one click: Add to Cursor with sign-in or Add to Cursor with an API key.
The config goes in ~/.cursor/mcp.json. Restart Cursor, or reload its window, so it reads the new server. With sign-in, sign in to mails in Cursor's MCP settings.
code --add-mcp '{"name":"mails","type":"http","url":"https://api.mails.ai/mcp"}'{
"servers": {
"mails": {
"type": "http",
"url": "https://api.mails.ai/mcp",
"headers": {
"Authorization": "Bearer ${input:mails-api-key}"
}
}
},
"inputs": [
{
"type": "promptString",
"id": "mails-api-key",
"description": "mails.ai API key",
"password": true
}
]
}Or add it with one click: Add to VS Code.
With sign-in, VS Code opens your browser the first time mails starts. With an API key, run the command MCP: Open User Configuration and paste the config. VS Code asks for the key once and keeps it in its own secret storage.
codex mcp add mails --url https://api.mails.ai/mcp
codex mcp login mailscodex mcp add mails --url https://api.mails.ai/mcp --bearer-token-env-var MAILS_API_KEYWith an API key, the command writes this to ~/.codex/config.toml:
[mcp_servers.mails]
url = "https://api.mails.ai/mcp"
bearer_token_env_var = "MAILS_API_KEY"Windsurf’s MCP documentation now lives with Devin Desktop. Its default agent, Devin Local, reads servers from ~/.config/devin/mcp_config.json (%APPDATA%\devin\mcp_config.json on Windows).
devin mcp add mails https://api.mails.ai/mcp
devin mcp login mails{
"mcpServers": {
"mails": {
"url": "https://api.mails.ai/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer ${env:MAILS_API_KEY}"
}
}
}
}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.
{
"mcpServers": {
"mails": {
"command": "npx",
"args": ["-y", "@mailsai/mcp-server"],
"env": {
"MAILS_API_KEY": "mk_test_xxxxxxxx"
}
}
}
}Most clients take this mcpServers block.
{
"mcpServers": {
"mails": {
"command": "npx",
"args": ["-y", "@mailsai/mcp-server"],
"env": {
"MAILS_API_KEY": "mk_test_xxxxxxxx"
}
}
}
}| Variable | What it does |
|---|---|
MAILS_API_KEY | Required. Your API key, mk_live_… or mk_test_…. A test key sends no real mail and is never billed. |
MAILS_BASE_URL | The 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-demoTools
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
Send an email.
Reply in-thread to a message.
Forward a message to new recipients.
Lists emails the workspace's agents sent or scheduled, newest first, with recipients, subject, status and timestamps.
Sends up to 100 emails in one call, each with its own agent, recipients and content.
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.
Returns one sent or scheduled email by its msg_ id: recipients, subject, body, status, delivery times, tags and metadata.
Moves a scheduled email to a new send time.
Cancels an email that is still scheduled, so it is never sent.
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.
Received mail
List recently received messages.
Get one received message: its text, including the extracted reply text.
List recent reply events (reply.received) for an agent.
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.
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.
Lists every file in a received email (rcv_ id), embedded images included (inline: true), with filename, content type and size.
Returns one file from a received email.
Threads
List threads (conversations) for the workspace or a specific agent.
Get a full thread with all messages in chronological order.
Marks a thread read or unread, moves it to inbox, archive, spam or trash, sets its status (open, closed, archived) or replaces its labels.
Moves a thread to trash, where mails_threads_update can move it back and where it is emptied after 30 days.
Drafts
Stage a draft.
Send a previously-created draft.
Lists drafts and scheduled drafts, newest first, filtered by agent or status; next_cursor fetches the next page.
Returns one draft by its id: recipients, subject, body, send_at and status.
Edits a draft's recipients, subject, body or send_at.
Deletes a draft, or a scheduled draft before it is sent.
Agents
List the agents in the workspace.
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.
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.
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).
Archives an agent: it can no longer send, and its address is kept and never reused.
Sends one test email, from mails.ai, to the own address of an agent in forwarding mode (support@acme.com), and returns the agent.
Returns an agent's unread count, its thread and unread counts per folder and per label, and the time of its latest message.
Labels
Lists the workspace's labels (at most 200) by name, each with its id and colour.
Creates a label with a name (unique in the workspace, ignoring case) and a colour from a fixed palette of 12.
Returns one label by its lbl_ id.
Renames a label or changes its colour.
Deletes a label and takes it off every thread that carries it.
Search
Full-text search over received and sent mail (subject, body and addresses), newest first; every word must match.
Events
Get one event by its id (evt_…), whatever its type: received mail, a send, a draft or a suppression.
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.
Sends a stored event again to every webhook endpoint subscribed to its type.
Webhooks
Lists the workspace's webhook endpoints with their URL, event types, description and whether each is active.
Registers an HTTPS endpoint that receives the workspace's events: every event, or the listed types.
Returns one webhook endpoint by its id.
Changes a webhook endpoint's URL, event types, description or whether it is active.
Deletes a webhook endpoint and its delivery history.
Issues a new signing secret for a webhook endpoint, returned only this once.
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.
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.
Sends the event behind a past delivery attempt again.
Domains
Lists the workspace's custom sending domains with their verification status and DNS records.
Registers a custom sending domain (paid plans) and returns the DNS records to create at the domain's registrar.
Returns one custom domain with its overall and per-record verification status.
Removes a custom domain.
Checks every DNS record of a custom domain now and returns the domain with its per-record and overall status.
API keys
Lists the workspace's API keys by prefix, name, mode, scopes and agent, with when each was last used.
Creates an API key with the given scopes and mode, optionally tied to one agent or expiring.
Revokes an API key at once: anything using it stops working.
Suppression
Check if an address is suppressed.
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.
Lists the workspace's allowlist: addresses mail may go to despite a suppression, each with its attestation.
Removes an allowlist entry by its id, so the suppression applies to that address again.
Account
Get an agent's sending-reputation health (0-1) + its 30-day bounce/complaint/reply counts.
Get the current billing period usage.
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.
Returns counts of sent, delivered, bounced, complained, received and reply messages per day or per hour (UTC), for the workspace or one agent.
Lists the workspace's audit log of changes, newest first, filtered by category or action if asked.
Returns whether the mails.ai API is up (healthy or degraded) and its clock.
Connected apps
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.
Ends a connected app's sign-in at once: its tokens stop working and it has to be approved again.
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 withsincereads 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?