MCP · AGENTS

MCP email server for Claude, Cursor, and Claude Code agents

Most interesting things an AI agent wants to do start with a signup form. Stripe, GitHub, Supabase, your own SaaS. And most signup forms end the same way: an email sits in an inbox the agent cannot see.

The Model Context Protocol fixes that. This post walks through wiring MailSink’s MCP server into Claude Desktop, Claude Code, and Cursor so your agent provisions a disposable inbox, waits for the verification mail, pulls the OTP, and moves on, all inside one conversation.

Quick MCP refresher

MCP is Anthropic’s open spec for letting an LLM call external tools. An MCP server exposes typed functions; an MCP client (Claude Desktop, Claude Code, Cursor, and a growing list of others) discovers them at session start and invokes them on behalf of the user. Each tool call is a JSON-RPC round trip.

That matters here because “check this email” becomes one of those calls. No agent-side email parsing, no Gmail IMAP, no browser automation. The agent issues wait_for_email, MailSink’s server fetches the latest message, and the model sees the verification code as a normal tool result.

What the MailSink MCP server actually does

MailSink is a hosted temp-email API. Every inbox is a real address on a real MX. Mail lands in Cloudflare R2, metadata goes in D1, and a cleanup job drops it on a plan-configured TTL (one hour on free, seven days on Team).

Our MCP server, published on npm as @mailsink/mcp, wraps that API with eight typed tools:

ToolPurpose
create_inboxProvision a throwaway address. Returns id, address, expires_at.
wait_for_emailBlock up to 60 seconds for the next message to arrive.
get_verification_codeReturn the OTP extracted from the most recent message.
get_verification_linkReturn the magic link from the most recent message.
list_messagesMetadata-only listing of everything in an inbox.
get_messageFull message content (headers, text, HTML, extracted fields).
list_inboxesYour active inboxes that have not expired.
delete_inboxBurn an inbox early.

The first four cover 95% of signup-flow automation. The rest help when you want to inspect a specific message, reuse an inbox across steps, or clean up before TTL.

Install

Sign in at mailsink.dev with GitHub. You’ll see an API key once. Copy it somewhere safe; MailSink does not store the plaintext.

export MAILSINK_API_KEY="msk_your_key_here"

That’s all. The MCP server runs on demand through npx, so there is nothing else to install globally.

Configure Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%\Claude\claude_desktop_config.json on Windows:

{
  "mcpServers": {
    "mailsink": {
      "command": "npx",
      "args": ["-y", "@mailsink/mcp"],
      "env": {
        "MAILSINK_API_KEY": "msk_your_key_here"
      }
    }
  }
}

Restart Claude Desktop. The plug icon in the message composer shows MailSink tools are loaded. Ask “create a disposable inbox and wait for a verification email” to smoke-test.

Configure Claude Code

Add a per-project .claude/mcp.json with the same shape:

{
  "mcpServers": {
    "mailsink": {
      "command": "npx",
      "args": ["-y", "@mailsink/mcp"],
      "env": {
        "MAILSINK_API_KEY": "msk_your_key_here"
      }
    }
  }
}

Or use the built-in command:

claude mcp add mailsink npx -y @mailsink/mcp \
  -e MAILSINK_API_KEY=msk_your_key_here

Claude Code picks up the server on the next session start. Tools appear under /mcp in the slash-command list.

Configure Cursor

Open Cursor Settings, select the MCP tab, click “Add new MCP server”:

Save. Cursor pings the server and the tools appear in the AI pane alongside any other MCP servers you have configured.

End-to-end: Claude signs up for a service

Here is a real session. The prompt was:

“Create a disposable email, use it to start a Stripe account signup, then grab the verification code that lands in that inbox.”

The tool call trace Claude produced:

  1. create_inbox({ ttl: 3600 }) returned { id: "inb_rae1z", address: "[email protected]", expires_at: 1713711600 }
  2. Claude used a browser tool to navigate to the Stripe signup page and submit [email protected] in the email field.
  3. wait_for_email({ inbox_id: "inb_rae1z", timeout: 45 }) blocked for about 4 seconds until Stripe’s verification mail arrived.
  4. get_verification_code({ inbox_id: "inb_rae1z" }) returned { code: "847291", from: "[email protected]", subject: "Verify your email address" }.
  5. Claude submitted 847291 to Stripe’s confirmation field. Stripe accepted, signup complete.

Three MailSink tool calls total. No Gmail, no IMAP credentials, no page-polling heuristics.

Temporary vs persistent: which inbox model fits?

AgentMail is the other MCP-native email player worth knowing. They bet on persistent agent identities; every inbox sticks around. That’s the right choice for an agent acting as a named representative (a support bot, a lead-gen worker) that receives ongoing mail.

MailSink bets on the opposite side. Every inbox is throwaway, bound to a task or CI run, and auto-expires:

AgentMailMailSink
Inbox lifetimePersistent1 hour to 7 days
IdentityStable across sessionsOne-shot per task
Best forNamed agents, ongoing commsSignup flows, test automation, CI
PricingUsage-basedFlat plan

If you need both models, use both. They fit different slots in an agent’s toolkit.

Pricing

The free tier includes the MCP server and 50 inboxes per month, which covers personal projects and small test suites. Pro ($15/mo) lifts the cap to 2,000 inboxes, extends TTL to 24 hours, and bumps rate limits to 600 requests per minute. Team ($49/mo) goes to 20,000 inboxes and 7-day TTL. The pricing section on the landing page has the full breakdown.

FAQ

Does the MCP server ever see my email content?

Only in the sense that it fetches messages from the MailSink API when your agent asks. Messages are stored in your account’s isolated R2 namespace. MailSink does not read content beyond the OTP and verification-link extractors that run at ingest.

Can I use multiple inboxes in the same conversation?

Yes. list_inboxes shows everything still alive. Call create_inbox as many times as your plan allows. Each tool takes an explicit inbox_id, so there is no ambiguity about which inbox a call targets.

What happens when an inbox expires mid-conversation?

The agent gets a 404 from any subsequent call to that inbox. Claude usually recovers by calling create_inbox again. You can extend TTL up to the plan maximum (7 days on Team).

Does this work offline or self-hosted?

Not today. The MCP server needs a live API key against api.mailsink.dev. A self-hostable build is on the roadmap but is not near-term.

How does extraction accuracy look?

Good against common senders: Stripe, GitHub, Google, Clerk, Supabase, Auth0, Resend, AWS, and dozens more. If a sender is not supported, get_message still returns the raw body so your agent can parse it directly.

Next