smails

Disposable email for humans and AI agents. An instant, anonymous throwaway inbox for sign-ups, one-time codes, and confirmations β with a REST API, a CLI, and an MCP server, so your AI agent can receive verification emails too. No signup, no password.
β smails.dev Β· npx @smails/cli create
Give your agent its own inbox: plug the MCP server into Claude, Cursor, or any MCP client and it can create a mailbox and read incoming mail (verification codes, magic links) on its own.
Features
- Instant inbox β open the site and you have an address, zero clicks
- Real-time β new mail arrives over WebSocket, no polling
- Built for agents β REST API, CLI, and an MCP server share the same mailbox
- Multi-domain β pick from configurable receiving domains
- Self-cleaning β mailboxes auto-expire after 7 days of inactivity
- Serverless β Cloudflare Workers + Durable Objects (one DO per mailbox, SQLite storage)
Quick start
Web
Visit smails.dev β an inbox is created for you on first load.
CLI
npx @smails/cli create
npx @smails/cli inbox
npx @smails/cli read <id>
npx @smails/cli whoami
npx @smails/cli create --force
MCP (for AI agents)
Add the server to any MCP client (e.g. Claude Desktop, ~/.claude/mcp.json):
{
"mcpServers": {
"smails": { "command": "npx", "args": ["@smails/cli", "mcp"] }
}
}
Tools: create_mailbox, list_messages, read_message, delete_message, get_address.
REST API
curl -X POST https://smails.dev/api/mailbox
curl https://smails.dev/api/mailbox/messages \
-H "Authorization: Bearer <token>"
| Method | Path | Description |
|---|
POST | /api/mailbox | Create a mailbox β { address, token } |
GET | /api/mailbox/messages | List messages |
GET | /api/mailbox/messages/:id | Read a message (full parsed body) |
DELETE | /api/mailbox/messages/:id | Delete a message |
WS | /api/mailbox/connect?token= | Stream new-mail notifications |
Authenticate every request (except create) with Authorization: Bearer <token>.
How it works
Inbound mail βββΆ Cloudflare Email Routing (catch-all)
β
βΌ
Worker email() handler βββ
βΌ
Web / CLI / MCP ββREST + WSβββΆ Durable Object (one per mailbox)
ββ SQLite (messages)
ββ token auth
ββ 7-day alarm β cleanup
- Each mailbox is a single Durable Object, addressed by its name; messages live in the DO's SQLite.
- The token is
{address}.{secret}; the Worker routes by address, the DO verifies the full token.
- A 7-day alarm wipes inactive mailboxes; any activity renews it.
Project structure
frontend/ React Router SPA (prerendered) β Tailwind v4 + shadcn
worker/ Cloudflare Worker + Durable Objects β Hono routing, postal-mime parsing
cli/ npm package β CLI + MCP server (@smails/cli)
Development
Each package is independent (pnpm). Install per package.
cd frontend && pnpm install && pnpm dev
cd worker && pnpm install && pnpm dev
cd cli && pnpm install && pnpm build
SMAILS_API_URL=http://localhost:8787 node dist/index.js create
Deployment
There are two independent release tracks β pushing to main ships the service, but not the CLI.
Worker + frontend β auto-deployed by Cloudflare Workers Builds on every push to main (the frontend builds to static assets the Worker serves). No manual step. To deploy by hand instead:
cd frontend && pnpm build
cd ../worker && pnpm run deploy
CLI (@smails/cli) + MCP server β not auto-deployed; publishing is a separate, manual release:
- Bump the version in
cli/package.json (npm rejects re-publishing an existing version).
- Push to
main.
gh release create cli-vX.Y.Z --target main β creating the GitHub Release triggers .github/workflows/publish-cli.yml, which publishes to npm and syncs the MCP registry listing from server.json.
server.json's description must be β€ 100 characters or the MCP registry publish step 422s.
Receiving mail uses Cloudflare Email Routing (catch-all β the Worker's email handler). Configure receiving domains via the DOMAINS var and the route in worker/wrangler.jsonc.
License
MIT