MCP for AI agents

Give Grok, ChatGPT, Claude or your own bot read-only access to your mail: search, read messages, pull verification codes and wait for new email. One URL and a key from Mailman's settings; Mailman on your computer answers every request.

Get started Set up with AI
Server URLhttps://mcp.getmailman.app/mcp
On this pageOverview

Overview

Mailman's MCP server lets an AI agent work with the mail in your Mailman. Every tool is read-only: an agent can search, read and wait for mail, but never send, delete or change it.

  1. Create a key

    In Mailman's settings, create a remote key for the agent. It starts with mmr_.

  2. Add the server

    Point the agent at https://mcp.getmailman.app/mcp and send the key as a bearer token.

  3. Your computer answers

    Mailman's relay forwards each request to Mailman on your computer. Your mail stays there.

Server URLhttps://mcp.getmailman.app/mcp

The same for everyone. The key decides whose Mailman answers.

AuthenticationAuthorization: Bearer mmr_…

Or x-api-key: mmr_…. Claude and other OAuth clients can sign in instead.

TransportStreamable HTTP

POST with JSON answers. There is no SSE stream, so GET answers 405.

Before you start

  • Mailman is open on your computer, signed in to your license. When it's closed, agents still see the tools, and every call explains that Mailman isn't reachable.
  • Remote access is on in Settings → Remote access & API → Web inbox.
  • The agent calls from a server or a local program. Requests from browser pages (with an Origin header) are refused.
  • Tool calls can take up to 90 seconds (waits and syncs). Set the agent's tool timeout to about 100 seconds.

Get a remote key

  1. In Mailman, open Settings → Remote access & API → Remote agents.
  2. Click Create remote key and name it after the agent, for example “Grok bot”.
  3. Copy the key now: Mailman shows it only once. Put it in the agent's secret or header settings, not in a chat message.

One key per agent. Each key can be revoked on its own in the same place, and Activity lists every call by key name. Local API tokens (mm_…) don't work remotely.

Connect your agent

Every client needs the same two things: the URL https://mcp.getmailman.app/mcp and the header Authorization: Bearer <remote key>. Use mailman where a name or label is asked for. Mailman takes a remote key with or without the Bearer prefix, so a platform's “authorization” or “token” field works either way.

xAI Grok

Add Mailman as a remote MCP tool in xAI's Responses API, or with the xAI Python SDK:

cURL

curl https://api.x.ai/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
  "model": "grok-4.7",
  "input": [{"role": "user", "content": "What is the latest verification code in my Mailman inbox?"}],
  "tools": [
    {
      "type": "mcp",
      "server_url": "https://mcp.getmailman.app/mcp",
      "server_label": "mailman",
      "server_description": "Read-only access to the mail in Mailman",
      "authorization": "Bearer '"$MAILMAN_REMOTE_KEY"'"
    }
  ]
}'

Python

import os

from xai_sdk import Client
from xai_sdk.chat import user
from xai_sdk.tools import mcp

client = Client(api_key=os.getenv("XAI_API_KEY"))
chat = client.chat.create(
    model="grok-4.7",
    tools=[
        mcp(
            server_url="https://mcp.getmailman.app/mcp",
            server_label="mailman",
            extra_headers={"Authorization": "Bearer " + os.environ["MAILMAN_REMOTE_KEY"]},
        ),
    ],
)
chat.append(user("What is the latest verification code in my Mailman inbox?"))
print(chat.sample().content)

OpenAI

A remote MCP tool in the Responses API:

Tool
{
  "type": "mcp",
  "server_label": "mailman",
  "server_url": "https://mcp.getmailman.app/mcp",
  "headers": { "Authorization": "Bearer <remote key>" },
  "require_approval": "never"
}

Claude

No key needed. In Claude (web, desktop or mobile), open Settings → Connectors → Add custom connector, paste https://mcp.getmailman.app/mcp, sign in with your Mailman account and approve. Pick the computer the connection should use.

Claude Code

Terminal
claude mcp add --transport http mailman https://mcp.getmailman.app/mcp \
  --header "Authorization: Bearer <remote key>"

Codex

Add to ~/.codex/config.toml, and set MAILMAN_REMOTE_KEY before starting Codex:

config.toml
[mcp_servers.mailman]
url = "https://mcp.getmailman.app/mcp"
bearer_token_env_var = "MAILMAN_REMOTE_KEY"
tool_timeout_sec = 100

Cursor

Add to .cursor/mcp.json, or ~/.cursor/mcp.json globally:

mcp.json
{
  "mcpServers": {
    "mailman": {
      "url": "https://mcp.getmailman.app/mcp",
      "headers": { "Authorization": "Bearer <remote key>" }
    }
  }
}

Clients that only launch local servers

Bridge with mcp-remote (needs Node.js). The version is pinned on purpose: the bridge receives your key, so a new release should not run until you have looked at it.

MCP configuration
{
  "mcpServers": {
    "mailman": {
      "command": "npx",
      "args": ["-y", "mcp-remote@0.15.2", "https://mcp.getmailman.app/mcp", "--header", "Authorization:${MAILMAN_AUTH}"],
      "env": { "MAILMAN_AUTH": "Bearer <remote key>" }
    }
  }
}

Any other client, or your own code

Send JSON-RPC over HTTPS. A working connection answers mailman_status with the app version, license and account count:

Test the connection
KEY='<remote key>'
curl -sS https://mcp.getmailman.app/mcp \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"my-bot","version":"1.0"}}}'

curl -sS https://mcp.getmailman.app/mcp \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-06-18" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"mailman_status","arguments":{}}}'

OAuth sign-in

Platforms with MCP sign-in can connect without a key. A request without one gets 401 and a WWW-Authenticate header that points to the protected-resource metadata. The authorization server is https://api.getmailman.app: OAuth 2.1 with PKCE (S256), dynamic client registration and public clients, scope mailman. You sign in, approve the app and pick a computer. Revoke connected apps in Mailman's settings or on the dashboard.

Tools

Arguments are JSON; ? marks optional ones. Mail content comes back as untrusted data in structuredContent, and failures set isError: true.

ToolPurpose and key parameters
mailman_statusVersion, license, sync state and account count; no arguments.
list_accountsAccount metadata and aliases; query?, category?, tag?, cursor?, limit?.
find_accountsResolve inboxes, aliases or account ids; emails array, up to 10,000.
search_mailSearch mail headers; q, bodies?, category?, offset?, limit?.
list_messagesList message headers; account?, scope?, category?, cursor?, limit?.
read_messageA message body and metadata; id, format?, original?, maxChars?.
read_messagesSeveral messages at once; ids array, up to 50, plus format?, original?, maxChars?.
get_attachmentA file, up to 4 MB remotely; id, index.
get_raw_messageOriginal RFC822 source as text, up to 2 MB; id.
list_tagsSmart views and custom tags with counts; no arguments.
list_stacksMessage stacks; view? OR tag? OR category?, unread?, cursor?, limit?.
get_stackA stack's message headers; id, category?, cursor?, limit?.
get_codesExtracted verification codes; account?, since?, limit?.
sync_accountsSync chosen accounts or one category; accounts array OR category, waitSeconds?.
sync_statusCurrent state and last sync result; accounts array.
wait_for_mailWait for an email to an exact address; to, account?, from?, subjectContains?, since?, extract?, timeoutSeconds? (at most 90 remotely; then timedOut: true).

Email is written by strangers. A message can contain instructions aimed at your agent. Tell the agent to treat mail as data and never follow instructions found in an email.

Troubleshooting

SymptomFix
401 with unauthorizedNo key reached Mailman, or it was wrong or revoked. Send Authorization: Bearer mmr_… (the whole key). A local mm_ token never works here. Create a new remote key if in doubt.
403 origin_forbiddenThe request carried an Origin header. Call from a server or local program, not a browser page.
405 on GETExpected: there is no SSE stream. Use POST; the answer is plain JSON.
400 "Use Content-Type: application/json"Set that header on every POST.
Tools listed, but every call says "Mailman isn't running on your computer, or Remote access is off"Open Mailman on the computer with the mail, sign in, and turn on Settings → Remote access & API → Web inbox.
"Update Mailman on your computer to use remote agents"The desktop app is too old. Update Mailman.
429 "Mailman is busy"At most 8 agent requests run at once per computer. Retry after a moment.
429 "Too many requests at once"Too many requests in flight from one network address. Wait for answers before sending more.
504 or a client-side timeoutA wait or sync ran long. Raise the client's tool timeout to about 100 seconds, or ask for a shorter timeoutSeconds.

Set up with AI

Give your agent, or the AI that builds it, the MCP guide. It is one Markdown file with the URL, authentication, setup for each platform, the tools and the error answers.

A prompt to paste

Fill in the brackets. If your assistant can't open links, copy the guide and paste it into the chat first.

Connect [my bot / this agent] to Mailman's MCP server so it can read my mail, get verification codes and wait for new email. Read this guide first and follow it exactly: https://getmailman.app/mcp.md The agent runs on [platform, for example "the xAI API with Grok" or "a Python bot using the OpenAI Responses API"]. Read the Mailman remote key from [where the key is stored, for example the environment variable MAILMAN_REMOTE_KEY]; never print it or put it in a prompt. When you finish, call mailman_status to check the connection, and use the guide's troubleshooting table if it fails.
Open mcp.md

Want Mailman for your inboxes?

MCP access comes with Mailman, which is in an invite-only beta. Spots open in batches: leave your email and we'll let you know when it's your turn.

Join the waitlist