Read our privacy policy
Skip to content

Guide · AI agents

How an AI agent sends and reads email over MCP

An agent can write the message; sending it still needs a server that checks the sending domain, the quota and the suppressions. MepMail's MCP server gives the agent those tools, on the same pipeline as the REST API.

Two ways to connect

The hosted server at https://api.mepmail.dev/mcp speaks Streamable HTTP and signs in with OAuth, so no key is pasted into the client's config.

The npm package @mepmail/mcp speaks stdio and reaches your instance with a team key or a mailbox key, for clients that launch servers from a config file.

The names and the result shape are the same on both, so a prompt written for one works on the other; the hosted server also exposes the tools that manage domains, webhooks, templates and broadcasts.

Option 1: the hosted server, with OAuth

  1. In Claude Code, run the command below, then /mcp and pick mepmail to sign in. Add --scope user to make it available in every project.
  2. In Cursor, add the URL to .cursor/mcp.json in the project, or to ~/.cursor/mcp.json for every project.
  3. In VS Code, add it to .vscode/mcp.json with type http and the URL.
  4. In Claude Desktop, add a custom connector under Settings → Connectors, or bridge to the HTTP endpoint with mcp-remote.
  5. On the consent screen, pick the team the client may act on and untick the permissions you do not want to grant. Nothing is copied or pasted.
Claude Code
claude mcp add --transport http mepmail https://api.mepmail.dev/mcp

Option 2: the local package

The package needs Node.js 20 or newer and runs with npx, with no OAuth and no browser step: the config block is the whole install.

Set MEPMAIL_API_KEY for the sending tools, a team key that starts with ms_, and MEPMAIL_MAIL_TOKEN for the mailbox tools, an agent key that starts with mmb_ for one mailbox or mmt_ for several. At least one of the two.

MEPMAIL_BASE_URL points at another instance; leave it out to talk to MepMail Cloud.

claude_desktop_config.json
{
  "mcpServers": {
    "mepmail": {
      "command": "npx",
      "args": ["-y", "@mepmail/mcp"],
      "env": {
        "MEPMAIL_API_KEY": "ms_...",
        "MEPMAIL_MAIL_TOKEN": "mmb_..."
      }
    }
  }
}

Reading and answering mail

  1. mailbox_list_accounts lists the mailboxes the credential reaches, with their permissions.
  2. mailbox_list_messages returns one page, newest first: pass the returned nextCursor as cursor until hasMore is false, and filter on the server with query, from, subject, unread, after and before. A short page never proves a message is absent.
  3. mailbox_read_message returns headers, text, the revision and the attachment metadata.
  4. mailbox_save_draft creates or edits a plain-text draft without sending, and mailbox_send_draft sends it.
  5. Without the send permission, mailbox_send_draft emails you to approve the send, which waits in the dashboard.
  6. On the hosted server, the same mailbox tools answer at https://api.mepmail.dev/mcp/correio with an agent key instead of OAuth.

Sending transactional email

send_email sends or schedules one message, send_email_batch takes up to 100 in one call, and update_email and cancel_email handle a scheduled one.

For a safe retry, pass an idempotency_key: keep the same key and the same arguments when retrying the same send, and use a new key for a new operation. Keys belong to the team and last 24 hours, and a completed retry replays the original result.

The sending domain has to be verified first: an unverified sender fails send_email exactly as it fails POST /emails.

list_emails and get_email show the status and the last event, delivered, bounced or complained.

Permissions, and why the agent asks

Each tool needs a scope, such as emails:send, mail:read or mail:draft. Tools whose permissions you untick are never granted, so the client does not see them.

Sending without asking is a separate tick: leave Direct sending off and every send emails you for approval, and ticking mailboxes never turns it on by itself.

Grants are listed under Settings → Connected apps, where you can revoke your own. Revocation lands at the client's next token refresh, within an hour, and a member removed from the team loses access at once.

Tool results arrive in an untrusted_data envelope: subjects, senders and bodies were written by third parties, and the agent is told to treat them as data, never as instructions.

MCP calls share the API's per-minute rate limit.

Before you point an agent at a real inbox

  1. Verify the sending domain, and read its records with get_domain before debugging anything else.
  2. Create the mailbox and its agent key in Correio → Settings → Agents: mmb_ for one mailbox, mmt_ for several.
  3. Start with read and drafts: the agent reads, prepares the reply and asks you before sending.
  4. Check the grant under Settings → Connected apps, then send one message to your own address.
  5. Keep the reach to the mailboxes you ticked: a team credential only reaches the ones mailbox_list_accounts returns.

Frequently asked questions

Does the agent need my password?

No. The hosted server uses OAuth: you sign in the browser and the client keeps a token you can revoke under Settings → Connected apps. The npm package uses an API key or a mailbox key.

Can it read every mailbox in the team?

Only the ones you tick at consent, or the ones the agent key covers. The grant is bound to a single team, and the mail tools answer only for the mailboxes in it.

What if a send times out?

For mail, call mailbox_send_draft again with the same id and revision: that returns the send's status and never sends twice. For transactional email, retry with the same idempotency_key.

Which clients work?

Any MCP client. The docs give the config for Claude Code, Claude Desktop, Cursor and VS Code, and the package speaks stdio for everything else.

More guides

Give your agent a mailbox, not a script

Create an account, verify a domain and connect the MCP server in a few minutes.

Create free account

MCP server docs