Skip to content

ShaheedFazal/give-your-agent-a-mailbox

Repository files navigation

Give Your AI Agent a Mailbox

A Cloudflare Worker that gives any AI agent its own email address. Receive, read, and send email — with proper threading, attachment handling, and multi-agent isolation — all on Cloudflare's free tier.

Built for the era of AI agents that need to communicate beyond chat. Your agent gets a real email address like agent@yourdomain.com, can receive messages with attachments, and reply in threaded conversations — just like a human colleague.

What it does

Someone emails agent@yourdomain.com
  → Cloudflare Email Routing catches it
  → Worker parses the MIME, stores the email in KV, attachments in R2
  → Optionally forwards a webhook to your agent framework

Your agent calls POST /send
  → Worker builds a MIME message with proper threading headers
  → Delivers via Cloudflare Email Routing to your verified inbox

Features

  • Inbound email — parsed with PostalMime, stored in KV, attachments in R2
  • Outbound email — build and send via Cloudflare's native send_email binding
  • ThreadingIn-Reply-To / References headers are automatically stitched so replies land in the right thread in your email client
  • Attachments — inbound attachments stored in R2, downloadable via API
  • Multi-mailbox — one Worker serves many agents; storage is partitioned per mailbox so agents can't see each other's email
  • MCP server included — plug into Claude Code or any MCP-compatible client; your agent gets send_email, list_emails, read_email, and get_attachment tools
  • Webhook forwarding — optionally POST parsed emails to any HTTP endpoint (NanoClaw, n8n, Make, custom agents)

Architecture

┌─────────────────────────────────────────────────────┐
│              Cloudflare Email Worker                 │
│                                                     │
│  Inbound:  agent@yourdomain → parse → KV + R2      │
│  Outbound: POST /send → MIME → Email Routing        │
│  Read:     GET /emails, /email/:id                  │
│  Attach:   GET /email/:id/attachment/:filename      │
└──────────┬──────────────────────┬───────────────────┘
           │ webhook (optional)    │ HTTP API
           │                      │
     ┌─────▼──────┐     ┌────────▼────────────────┐
     │ Your agent │     │ MCP Server (included)   │
     │ framework  │     │ Claude Code / any MCP   │
     └────────────┘     └─────────────────────────┘

Quick start

Prerequisites

1. Clone and install

git clone https://github.com/YOUR_USERNAME/cloudflare-email-agent.git
cd cloudflare-email-agent
npm install

2. Create Cloudflare resources

wrangler kv namespace create THREADS
wrangler kv namespace create EMAILS
wrangler r2 bucket create email-attachments

3. Configure

Edit wrangler.jsonc:

{
  "send_email": [{
    "name": "SEND_EMAIL",
    "destination_address": "you@gmail.com"          // your verified inbox
  }],
  "kv_namespaces": [
    { "binding": "THREADS", "id": "<from step 2>" },
    { "binding": "EMAILS",  "id": "<from step 2>" }
  ],
  "r2_buckets": [{
    "bucket_name": "email-attachments",
    "binding": "ATTACHMENTS"
  }],
  "vars": {
    "AGENT_ADDRESS": "you@gmail.com",               // same as destination
    "FROM_ADDRESS": "agent@yourdomain.com",          // on your CF domain
    "FROM_NAME": "My Agent"
  }
}

4. Set secrets

wrangler secret put SEND_TOKEN      # token agents use to call the API
wrangler secret put WEBHOOK_URL     # optional: where to forward inbound email
wrangler secret put WEBHOOK_TOKEN   # optional: auth for webhook

5. Deploy

wrangler deploy

6. Route email to the Worker

In the Cloudflare dashboard: Email Routing → Routing Rules → Create address

  • Custom address: agent@yourdomain.com
  • Action: Send to Workercloudflare-email-agent

7. Test it

# Send an email from your agent
curl -X POST https://cloudflare-email-agent.<you>.workers.dev/send \
  -H "Authorization: Bearer $SEND_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mailbox": "agent@yourdomain.com",
    "subject": "Hello from my agent",
    "text": "The mailbox is working."
  }'

# Check your inbox, then reply to the email.
# After a moment, list inbound emails:
curl https://cloudflare-email-agent.<you>.workers.dev/emails?mailbox=agent@yourdomain.com \
  -H "Authorization: Bearer $SEND_TOKEN"

API reference

All endpoints except /health require Authorization: Bearer $SEND_TOKEN.

All read endpoints require ?mailbox=agent@yourdomain.com (or X-Mailbox header).

Method Path Description
GET /health Health check (no auth)
GET /emails List recent emails (paginated: ?limit=20&offset=0)
GET /email/:id Read full email by Message-ID
GET /email/:id/attachments List attachments for an email
GET /email/:id/attachment/:filename Download an attachment
POST /send Send an email

POST /send body

{
  "mailbox": "agent@yourdomain.com",
  "subject": "Required",
  "text": "Plain text body",
  "html": "<p>HTML body</p>",
  "from_name": "Agent Name",
  "in_reply_to": "<message-id@domain>"
}
  • mailbox and subject are required
  • At least one of text or html is required
  • in_reply_to is optional; when set, the email threads correctly in the recipient's mail client

Using the MCP server

The mcp/ directory contains an MCP server that wraps the Worker API. It exposes four tools: send_email, list_emails, read_email, and get_attachment.

Setup with Claude Code

cd mcp && npm install && npx tsc

Add to ~/.claude/settings.json (global) or your project's .mcp.json:

{
  "mcpServers": {
    "cloudflare-email": {
      "command": "node",
      "args": ["/path/to/cloudflare-email-agent/mcp/dist/index.js"],
      "env": {
        "WORKER_URL": "https://cloudflare-email-agent.<you>.workers.dev",
        "SEND_TOKEN": "your-send-token",
        "MAILBOX": "agent@yourdomain.com"
      }
    }
  }
}

Now in any Claude Code session:

"Check my email" "Send Shaheed a summary of today's changes" "Download the spreadsheet from that last email"

Multiple agents

Each agent gets its own MCP instance with a different MAILBOX. Add a route per address in Cloudflare Email Routing, then add another entry in your MCP config:

{
  "mcpServers": {
    "email-agent-1": {
      "command": "node",
      "args": ["/path/to/mcp/dist/index.js"],
      "env": {
        "WORKER_URL": "https://cloudflare-email-agent.<you>.workers.dev",
        "SEND_TOKEN": "same-token",
        "MAILBOX": "agent-1@yourdomain.com"
      }
    },
    "email-agent-2": {
      "command": "node",
      "args": ["/path/to/mcp/dist/index.js"],
      "env": {
        "WORKER_URL": "https://cloudflare-email-agent.<you>.workers.dev",
        "SEND_TOKEN": "same-token",
        "MAILBOX": "agent-2@yourdomain.com"
      }
    }
  }
}

Agents are isolated — agent-1 cannot read agent-2's email.

Multi-mailbox isolation

Storage is partitioned by mailbox address:

  • KV keys: agent@domain:__index__, agent@domain:<message-id>
  • R2 keys: agent@domain/<message-id>/<filename>
  • Thread cache: agent@domain:<message-id>

One Worker, one KV namespace, one R2 bucket — many isolated mailboxes.

Limitations

  • Outbound recipients must be verified in Cloudflare Email Routing. This is by design for personal agent setups. For sending to arbitrary external addresses, swap send_email for Resend, Postmark, or AWS SES.
  • Attachment bytes are not included in webhook payloads — only metadata. Retrieve them via the /attachment endpoint or add inline forwarding in the email() handler.
  • KV has eventual consistency — there's a small window after receiving an email where it may not appear in list_emails. In practice this is under a second.
  • Email storage expires after 90 days (configurable via EMAIL_TTL_SECONDS).

Local development

cp .dev.vars.example .dev.vars   # fill in test values
wrangler dev                     # local HTTP server on :8787

wrangler dev does not simulate inbound email. Test inbound by deploying and sending real mail.

Cost

Everything fits within Cloudflare's free tier:

Resource Free tier Typical agent usage
Workers 100,000 req/day Well under
KV 100,000 reads/day, 1,000 writes/day Well under
R2 10GB storage, 10M reads/month Well under
Email Routing Unlimited -

License

MIT

About

Give your AI agent a real email address. Receive, read, and send email with proper threading and attachments — all on Cloudflare's free tier. Includes MCP server for Claude Code.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors