11# Email MCP (Durable Object SQL DB + Cloudflare Email)
22
33An MCP server that:
4+
45- Sends internal emails via Cloudflare's Email binding (only to verified addresses).
56- Manages email data via Durable Object SQLite storage.
67- Exposes MCP tools and resources to interact with emails.
78
89Features
10+
911- Tools:
1012 - create_test_email(from_addr, to_addr, subject, text) - Create test emails for database testing
1113 - send_email(to, subject, text) - Send real emails via Cloudflare Email Workers (requires domain setup)
@@ -16,39 +18,47 @@ Features
1618 - do://database/emails/{id} - Get specific email
1719
1820Important limitations
21+
1922- This is for internal email only. Cloudflare’s Send Email binding delivers only to verified recipients on your zone.
2023- Not a general outbound SMTP service.
2124
2225Setup
2326
24- 1 ) Durable Object SQL Database
27+ 1 . Durable Object SQL Database
28+
2529- No external database setup required! The Durable Object has built-in SQLite storage.
2630- Email data is stored in the Durable Object's persistent SQLite database.
2731
28- 2 ) Email Routing and bindings
32+ 2 . Email Routing and bindings
33+
2934- Verify MAIL_FROM (sender) address in Cloudflare Email Routing.
3035- Verify intended recipient addresses or domains (ALLOWED_RECIPIENTS).
3136- Add “Send Email” binding named SEND_EMAIL in wrangler.jsonc.
3237
33- 3 ) Durable Object binding
38+ 3 . Durable Object binding
39+
3440- EMAIL_MCP_SERVER is defined in wrangler.jsonc. No extra setup beyond deploy.
3541
36- 4 ) Env vars
42+ 4 . Env vars
43+
3744- MAIL_FROM: the verified sender (e.g., no-reply@example.com )
3845- ALLOWED_RECIPIENTS: comma-separated emails or @domain rules. Examples:
3946 - "alice@example.com ,bob@example.com ,@example .com"
4047
4148Local development
49+
4250- Install deps: pnpm i
4351- Update wrangler.jsonc vars and bindings.
4452- Run: pnpm dev
4553
4654Deploy
55+
4756- pnpm deploy
4857
4958Testing MCP with the Playground
59+
5060- Start the Playground package or your client.
51- - Connect via SSE/WebSocket to this Worker’s /sse (the MCP package already mounts standard endpoints in the DO).
61+ - Connect via HTTP/SSE to this Worker’s /mcp (the MCP package already mounts standard endpoints in the DO).
5262- Call tools:
5363 - send_email
5464 - list_emails
@@ -60,9 +70,9 @@ Testing the MCP Server
6070
6171You can test the core email management functionality immediately:
6272
63- 1 . ** Connect to MCP server** :
64- - Local: http://localhost:PORT/sse (where PORT is shown by wrangler dev)
65- - Production: https://your-worker.workers.dev/sse
73+ 1 . ** Connect to MCP server** :
74+ - Local: http://localhost:PORT/mcp (where PORT is shown by wrangler dev)
75+ - Production: https://your-worker.workers.dev/mcp
6676
67772 . ** Create test emails** :
6878 - Tool: ` create_test_email `
@@ -76,7 +86,7 @@ You can test the core email management functionality immediately:
7686 - Copy any full UUID for detailed viewing
7787
78884 . ** Get specific email** :
79- - Tool: ` get_email `
89+ - Tool: ` get_email `
8090 - Use: Any UUID from the list_emails results
8191 - Shows: Complete email details including full content
8292
@@ -85,13 +95,15 @@ You can test the core email management functionality immediately:
8595To test the ` send_email ` tool for actual email delivery:
8696
8797### Prerequisites:
98+
88991 . ** Own a domain** registered with any provider
891002 . ** Add domain to Cloudflare** and enable Email Routing
901013 . ** Verify sender addresses** in Cloudflare Email Routing → Send tab
911024 . ** Update MAIL_FROM** in wrangler.jsonc to your verified domain
921035 . ** Update ALLOWED_RECIPIENTS** with addresses you want to allow
93104
94105### Setup Steps:
106+
951071 . ** Cloudflare Dashboard** → Your Domain → Email → Email Routing
961082 . ** Enable Email Routing** (adds required DNS records automatically)
971093 . ** Add destination addresses** and verify them via email
@@ -107,12 +119,14 @@ To test the `send_email` tool for actual email delivery:
1071197 . ** Test** : Use ` send_email ` tool with allowed recipients
108120
109121### Expected Results:
122+
110123- ** ✅ Allowed recipients** : Email sent successfully
111124- ** ❌ Disallowed recipients** : "Recipient not allowed" error
112125- ** ❌ Unverified sender domain** : "domain not owned" error
113126
114-
115127Notes
128+
116129- Large raw messages: we store only the text and metadata in the Durable Object SQLite database. If you need full raw message storage, consider R2.
117130- If you see recipient not allowed, update ALLOWED_RECIPIENTS.
118- - The Durable Object SQLite database provides strong consistency and is automatically managed by Cloudflare.
131+ - The Durable Object SQLite database provides strong consistency and is automatically managed by Cloudflare.
132+
0 commit comments