Technology Apr 22, 2026 · 3 min read

Building MailSink: a temp email API with MCP server on Cloudflare Workers

The problem Testing email flows in CI has been painful for years. MailSlurp is $79/mo, Mailtrap's API isn't built for AI agents, and most alternatives want you to run your own SMTP server. I wanted something different: a REST API callable from tests, with an MCP server so AI agents could...

DE
DEV Community
by heocoi
Building MailSink: a temp email API with MCP server on Cloudflare Workers

The problem

Testing email flows in CI has been painful for years. MailSlurp is $79/mo, Mailtrap's API isn't built for AI agents, and most alternatives want you to run your own SMTP server.

I wanted something different: a REST API callable from tests, with an MCP server so AI agents could run email-verified signup flows natively.

So I built it.

What it does

MailSink gives you programmatic temporary email inboxes via a simple REST API:

# Spin up a disposable inbox
curl -X POST api.mailsink.dev/v1/inboxes
# → signup-k8m2@codenotify.net

# Your app or agent signs up with that address...

# Wait for the verification mail, extract the OTP code
curl api.mailsink.dev/v1/inboxes/inb_rae1z/wait-for-code
# → { "code": "847291", "from": "stripe.com" }

That's the whole API surface for the common case.

The MCP angle

An MCP server ships in the @mailsink/mcp npm package. Claude Code, Cursor, Windsurf, any MCP client can call these tools natively during autonomous workflows:

create_inbox({ ttl: 3600 })
// → signup-k8m2@codenotify.net

get_verification_code({ inbox_id, timeout: 30 })
// → { code: "847291" }

Your agent can actually sign up for Stripe, GitHub, Clerk, Supabase. Not a browser automation wrapper. Native.

The architecture

Everything runs on Cloudflare's edge:

  • workers/api - Hono on Cloudflare Workers. Routes: inboxes, messages, domains, keys, auth (GitHub OAuth), billing (Stripe), internal. KV-based rate limiting.
  • workers/email - Cloudflare Email Routing handler. Parses incoming mail with postal-mime, writes metadata to D1, raw body to R2, triggers OTP extraction.
  • packages/shared - OTP + magic-link extractors for Stripe, GitHub, Google, Clerk, Supabase, Auth0, Resend, AWS. Raw MIME always available if the extractor misses.
  • mcp - @mailsink/mcp npm package. 7 tools exposed to MCP clients.

Why Cloudflare:

  • Sub-20ms p50 latency via 320+ edge locations
  • Email Routing handles SMTP receipt for free on shared domains
  • D1 for metadata, R2 for bodies, zero infra to manage
  • One deploy target, one config

What I learned

  1. Email parsing is harder than it looks. postal-mime handles MIME well, but OTP patterns across senders are wildly inconsistent. I built per-sender extractors for the top 8 services and fall back to generic regex patterns for everything else.

  2. MCP turned a dev tool into an agent tool. Same REST API, new audience. Zero additional code to maintain, major differentiator in the pitch.

  3. Cloudflare Email Routing + shared domains lets you skip running Haraka or Postfix for shared-domain inboxes. You only need your own SMTP receiver when you support Bring Your Own Domain.

  4. Pricing anchors matter. MailSlurp at $79/mo signals "enterprise." I priced Pro at $15/mo because the real differentiator is agent-friendliness, not feature parity.

Pricing

  • Free: 3 inboxes, 100 msgs/mo
  • Pro: $15/mo unlimited
  • BYOD on Pro+ (bring your own domain, waitlist)

Try it

Live at https://mailsink.dev. GitHub OAuth, you're in in 10 seconds.

Feedback welcome, especially on API shape and pricing positioning.

First open stable release. Still learning what breaks.

DE
Source

This article was originally published by DEV Community and written by heocoi.

Read original article on DEV Community
Back to Discover

Reading List