A Cloudflare Workers-based email inbox service. Receives all emails sent to *@yourdomain.com via catch-all Email Routing, stores them in D1, and exposes a token-protected REST API for reading and searching emails.
Built to be consumed by AI agents (Claude Code, OpenClaw, etc.) for automated email processing.
- Catch-all inbox — Receive emails to any address on your domain
- Full-text search — Search emails by keyword in subject and body
- Flexible filtering — Filter by sender, recipient, date range
- Export API — Paginated export with full email content
- Token authentication — All API endpoints protected with Bearer token
- Edge computing — Runs on Cloudflare's global network
- Cloudflare Workers — Runtime
- Cloudflare D1 — SQLite database
- Cloudflare Email Routing — Email receiving
- Hono — Web framework
- postal-mime — Email parsing
- Bun — Package manager
- Bun installed
- A Cloudflare account with Workers access
- A domain added to Cloudflare with Email Routing enabled
git clone https://github.com/missuo/mailclaw
cd mailclaw
bun installbunx wrangler loginbun run db:createThis will output a database ID. Copy it.
Edit wrangler.jsonc and replace REPLACE_WITH_YOUR_DATABASE_ID with the ID from step 3:
bun run db:tables
bun run db:indexesGenerate a secure token and set it as a Worker secret:
# Generate a random token
openssl rand -hex 32
# Set it as a secret
bunx wrangler secret put API_TOKENSave this token — you'll need it to authenticate API requests.
bun run deployNote the Worker URL from the output (e.g., https://mailclaw.<your-subdomain>.workers.dev).
- Go to Cloudflare Dashboard
- Select your domain
- Navigate to Email > Email Routing > Routing rules
- Under Catch-all address, click Edit
- Set action to Send to a Worker
- Select the
mailclawworker - Save
All emails sent to *@yourdomain.com will now be received by MailClaw.
All /api/emails* endpoints require the Authorization header:
Authorization: Bearer <your-api-token>
GET /api/emails
Returns email metadata (no body content). Supports pagination and filtering.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
number | 20 | Page size (1-100) |
offset |
number | 0 | Pagination offset |
from |
string | — | Filter by sender (exact match) |
to |
string | — | Filter by recipient (exact match) |
q |
string | — | Search keyword in subject and body |
after |
string | — | Emails after date (ISO 8601 or Unix timestamp) |
before |
string | — | Emails before date (ISO 8601 or Unix timestamp) |
Example:
# List recent emails
curl -H "Authorization: Bearer $TOKEN" \
"https://mailclaw.example.com/api/emails"
# Filter by sender and date range
curl -H "Authorization: Bearer $TOKEN" \
"https://mailclaw.example.com/api/emails?from=partner@company.com&after=2026-03-01"
# Search by keyword
curl -H "Authorization: Bearer $TOKEN" \
"https://mailclaw.example.com/api/emails?q=partnership"Response:
{
"success": true,
"data": {
"emails": [
{
"id": "clx...",
"from_address": "partner@company.com",
"to_address": "bd@yourdomain.com",
"subject": "Partnership Inquiry",
"received_at": 1710000000,
"has_attachments": false,
"attachment_count": 0
}
],
"total": 42,
"limit": 20,
"offset": 0
}
}GET /api/emails/export
Same parameters as list, but includes text_content and html_content in the response.
curl -H "Authorization: Bearer $TOKEN" \
"https://mailclaw.example.com/api/emails/export?limit=10"GET /api/emails/:id
Returns full email including body content.
curl -H "Authorization: Bearer $TOKEN" \
"https://mailclaw.example.com/api/emails/clx123abc"DELETE /api/emails/:id
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
"https://mailclaw.example.com/api/emails/clx123abc"GET /api/health
No authentication required.
curl "https://mailclaw.example.com/api/health"MailClaw also ships with a Rust binary CLI named mailclaw. It wraps the same API endpoints and stores local credentials in ~/.mailclaw/config.json.
# Install into ~/.cargo/bin/mailclaw
cargo install --path .
# Or build a local release binary
cargo build --release
./target/release/mailclaw --helpmailclaw config set \
--host "https://mailclaw.example.com" \
--api-token "your-api-token-here"
mailclaw health# List recent email metadata
mailclaw list --limit 10
# Search emails and return machine-readable JSON
mailclaw list --q partnership --json
# Export full content
mailclaw export --from partner@company.com --limit 5 --json
# Read one email
mailclaw get clx123abc
# Delete one email
mailclaw delete clx123abcGitHub Releases can now publish prebuilt CLI binaries for:
x86_64-unknown-linux-gnuaarch64-unknown-linux-gnux86_64-apple-darwinaarch64-apple-darwinx86_64-pc-windows-msvc
If you prefer not to build locally, download the binary for your platform from the latest release, rename it if needed, and put it on your PATH. The uploaded asset names follow this pattern:
mailclaw-v1.0.0-<target>
mailclaw-v1.0.0-<target>.exe
Pushing a tag like v0.1.0 triggers .github/workflows/release-cli.yml, which creates a GitHub Release and uploads the compiled CLI binaries directly.
git tag v0.1.0
git push origin v0.1.0MailClaw ships with a built-in skill that lets AI agents (Claude Code, OpenClaw, etc.) read and manage your inbox.
npx skills add missuo/mailclawThe skill now shells out to the local mailclaw CLI instead of calling curl directly. If the CLI is missing, the skill should install the latest release binary automatically by default on macOS, Linux, and Windows.
On first use, the skill will ask you for your MailClaw Host and API Token, then save them through mailclaw config set to ~/.mailclaw/config.json for future sessions.
Once installed, you can use natural language like:
- "Check my recent emails"
- "Search emails from partner@company.com"
- "Read the latest email about partnership"
- "Show me all emails sent to tcook@apple.com this week"
The skill will automatically use the local mailclaw CLI to fetch and display results.
The skill definition is located at skills/mailclaw/SKILL.md. You can copy or adapt it for any AI agent framework that supports markdown-based skill definitions, or invoke the mailclaw CLI directly.
MailClaw currently supports receiving and reading emails only. Replying to and sending emails are not yet supported because Cloudflare Email Sending is still in beta with a waitlist. We will add send/reply support once the feature becomes generally available.
Create a .dev.vars file for local secrets:
API_TOKEN=dev-token-here
Start the dev server:
bun run devMIT