openagentemail
The openagentemail server provides a self-hosted email management platform for AI agents, accessible via REST and MCP APIs, with an optional web dashboard for human oversight. It enables agents to:
Create identities with random localparts and optional display names.
List all existing identities on the server.
List recent messages for an identity (up to 200, newest first) with metadata.
Read full message content, including plain text, HTML, and automatically extracted OTP codes and verification links.
Mark messages as seen/unseen without side effects on other flags.
Wait for incoming mail via long-poll (up to 600 s), filtering by sender or subject, and returns the matched message with extracted OTPs/links.
Send emails from any existing identity, supporting plain text and optional HTML body.
It also offers scoped API tokens for granular access control, per-identity send rate limits, automatic mail retention, and self-hosting via Docker with custom domains and optional external SMTP relays.
Allows routing outbound email through Amazon SES as a relay.
openagent.email
Self-hosted email for AI agents. The open-source alternative to AgentMail.
openagent.email · website: openagentemail/website

One docker compose up on your own VPS gives every agent you run unlimited real
mailboxes on your own domain — over REST and MCP — with OTP and verification-link
extraction built in. No per-inbox pricing, no third party ever seeing your mail.
Quickstart
npx -y @openagentemail/setupA guided wizard: it checks what you already have, helps you pick a VPS and a domain if you're missing either, and connects your agent clients (Claude Code, Cursor, Kimi Code…) once the server is up.
The manual path needs a VPS with outbound/inbound port 25 open and a domain you control:
git clone https://github.com/openagentemail/openagentemail.git && cd openagentemail
cp .env.example .env # set DOMAIN, API_KEYS, and the mailbox password
docker compose up -d && ./deploy/dns-records.sh # prints the exact DNS records to createThen verify everything end to end:
./deploy/doctor.sh # checks DNS, TLS, IMAP/SMTP login, and a round-trip sendCreate an identity and hand your agent its scoped token (shown once):
curl -X POST http://localhost:3100/v1/identities \
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
-d '{"name":"signup-bot"}'
# → 201 {"address":"fox-k7d2@example.com","name":"signup-bot","token":"oa_…"}The API binds to 127.0.0.1 by default — reach it from other hosts over an
SSH tunnel or a TLS proxy: docs/security.md.
Related MCP server: useblip/email
Read mail in a browser
Open http://localhost:3100/ui and paste an admin
or identity API token. The built-in dashboard lists the addresses the token
may access, shows messages, extracts verification codes and links, offers
plain-text or isolated HTML previews, and can mark messages read or unread.
Admin sessions can also create identities (with custom address prefixes),
rotate tokens, and delete identities directly from the overview table.
The browser exchanges the token once for an HttpOnly session cookie; the
token never enters the URL or browser storage. Sessions live only in API
process memory, so restarting the API signs every browser out. They expire
after 12 idle hours or 24 hours total — or tick Trust this device at
login to keep a sliding 30-day session on that browser. Each token holds at
most five sessions; a sixth login evicts that token's least-recently-used one
instead of locking you out.
For another computer, use the same SSH tunnel recommended for the API or put a
TLS reverse proxy in front. The login form refuses non-local plain HTTP, and
session cookies are Secure away from localhost. Set UI_ENABLED=false in
.env to make every /ui route return 404.
HTML email is treated as hostile input. The UI removes scripts, images, forms,
links, sender CSS, and all attributes except numeric table spans, then loads the
result in a separately sandboxed frame with a restrictive CSP. The
sanitize-html 2.x dependency is deliberately pinned to an exact version;
upgrade it in a dedicated change and rerun the full poison-message corpus.
Admin overview
An admin session lands on Overview: every identity in one table with the
message count, unseen count, last delivery, and creation day, plus totals across
the top. Each row also shows whether the identity has a token (green dot) and
has Rotate and Delete action buttons. A Create Identity button
above the table opens a form where you can set a custom address prefix (e.g.
qa-bot) or leave it blank for a random one; the new token is shown once in a
copy-to-clipboard modal. Identity sessions never see the overview or management
controls — they go straight to their own inbox.
The page is served from the same in-process API as the rest of /ui; there is no
new public endpoint outside /ui/api.
What the numbers mean, and where they stop:
Counts are a window, not a lifetime total. One scan reads the newest 500 messages in the catch-all mailbox and attributes each one to the identities it was delivered to. The header says
newest N of M in the mailboxso the window is never mistaken for history. A message addressed to two identities counts once for each row and once — not twice — in the totals.Honest instead of round. Messages with enormous recipient lists can exceed the scanner's per-message and global memory bounds. Rows the scanner could not fully account for show
≥NorUnknownrather than a confident wrong number, the page explains why, andunmatchedInWindowis reported asnullinstead of a made-up zero. The same applies to an identity created after the last scan: it readsUnknownuntil the next one, never a false0.Snapshots are cached in memory for 15 seconds and reused for up to 10 minutes while a refresh runs in the background, so opening Overview or walking in and out of inboxes does not hammer IMAP. Refresh is floored at 5 seconds. Restarting the API drops the cache — the first request afterwards pays for a fresh scan.
Failures cool down and never lie. If a scan fails, the next attempt waits 5 seconds (the API sends
Retry-After), the table keeps showing the previous numbers, and the header says the last refresh failed. Once a snapshot is older than 10 minutes it is not revived by a failed refresh: the page reports the counts as unavailable instead of showing stale data as current. While a cold scan is still running the endpoint answers202and the address list renders immediately withLoading…in the count columns.GET /ui/api/overview(browser session only, admin only) returns exactly the fields the page renders — never message content.?refresh=1asks for a new scan, subject to the 5-second floor and the failure cooldown.
Deliberate limits, so nothing here is a surprise later:
Overview shows counts and timestamps only. Subjects, senders, and verification codes need per-message parsing, which is what the inbox view is for.
New mail can be up to 15 seconds late on the page;
Refreshfetches sooner. There is no steady-state polling: the page only schedules a follow-up while counts are loading or a refresh is pending, capped at 15 attempts over 20 seconds and paced by the server's own retry hint.A scan that misses its deadline is abandoned even if IMAP answers a moment later, and the next request scans again. The deadline covers connecting as well as fetching, so a hung server does not park a request behind IMAP's own 30-second socket timeout.
Up to 200 identities render in one pass. Beyond that, expect to want paging or virtual scrolling; filtering and sorting happen in the browser today.
The dashboard self-hosts the Satoshi webfont (
/ui/fonts/*, the same typeface as the website) so it renders identically on every machine;font-srcis'self'. The favicon is an SVG (/ui/favicon.svg) so it needs no build step, and/ui/favicon.icokeeps returning 204 as before.Form controls use a dedicated
--line-controlborder token so their outlines stay above 3:1 contrast. It is the one intentional deviation from the website's palette and is a one-line revert.
Features
Unlimited identities — one catch-all mailbox, unlimited
anything@yourdomainaddresses. No provisioning, no per-inbox cost.Scoped tokens — every identity gets its own token that can only read and send as that address. The admin key never has to touch your agents.
REST + MCP — the same seven operations over a plain HTTP API and a first-class MCP server your agents can call directly.
mail_wait_for/POST /v1/messages/wait— long-poll an inbox until a matching message arrives, with OTP codes and verification links already extracted. Built for automated signups.Read/unread state —
mail_mark_seen/POST /v1/messages/:id/seenlets an agent (or the human in the dashboard) mark a message handled, so the unseen count means "still needs attention". Reading a message never changes the flag by itself.Web dashboard for humans — inspect identities and messages at
/ui, with an admin overview across all identities, token status and rotation, identity creation with custom addresses, responsive layouts, and doubly isolated HTML previews.Safety rails built in — per-identity send rate limits (20/hour default), automatic mail retention (30 days default), localhost-only API binding.
Bring your own relay — send directly from the VPS, or route outbound through Amazon SES / SMTP2GO / any SMTP relay with one env var.
DNS wizard + doctor —
deploy/dns-records.shgenerates your exact DNS records;deploy/doctor.shdiagnoses deliverability before your agents depend on it.Single dependency: Docker. The stack is the API plus docker-mailserver. Nothing else.
How it works
┌─────────────┐ MCP (stdio) ┌──────────────────┐
│ AI agents ├──────────────────▶ │
│ (Claude Code,│ │ openagent api │
│ Cursor, …) │ REST /v1/* │ (Node, imapflow │
└─────────────┘──────────────────▶ │ + nodemailer) │
└────────┬─────────┘
│ IMAP + SMTP (localhost)
┌────────▼─────────┐ SMTP 25
│ docker-mailserver│ ◀──────────▶ the world
│ catch-all mailbox│ (or your relay: SES, …)
└──────────────────┘One catch-all account on your domain receives everything. The API logs into it over
IMAP, matches messages to identities by the To/Delivered-To header, and sends
via SMTP with the From rewritten to the chosen identity. Polling + IMAP IDLE for
low-latency waits.
Use it from your agent (MCP)
Requires Node.js 18+ on the machine running the MCP client — no install step,
npx downloads and runs the package on first use.
claude mcp add openagentemail \
--env OPENAGENTEMAIL_API_URL=http://localhost:3100 \
--env OPENAGENTEMAIL_API_KEY=oa_your-identity-token \
-- npx -y @openagentemail/mcpOr the raw JSON config (Claude Desktop, Cursor, Kimi Code):
{
"mcpServers": {
"openagentemail": {
"command": "npx",
"args": ["-y", "@openagentemail/mcp"],
"env": {
"OPENAGENTEMAIL_API_URL": "http://localhost:3100",
"OPENAGENTEMAIL_API_KEY": "oa_your-identity-token"
}
}
}
}Tools
Tool | Description |
| Create an identity; pass |
| List all identities |
| List messages for an address (id/from/to/subject/date/seen/snippet) |
| Full message: text, html?, and |
| Mark a message read (default) or unread — reading never changes the flag by itself |
| Block until a matching message arrives (default 120s, max 600s) |
| Send mail; |
Full per-client setup (Claude Code, Claude Desktop, Cursor, Kimi Code, generic): docs/mcp-clients.md · server details: packages/mcp/README.md
Why self-host?
Privacy — OTP codes and verification links are credentials. Self-hosted, they never leave a machine you own. No third party reads, stores, or trains on your mail.
Cost — a $5 VPS and a domain you already have vs. per-inbox/per-message SaaS pricing that scales linearly with your agent fleet.
Control — your IPs, your reputation, your retention. No rate limits, no account suspensions, no sudden API deprecations.
Server requirements
Measured on our own production instance, idle: ~190 MB RAM total, ~0% CPU, and ~2 GB of disk for the Docker images. Mail itself is a rounding error — retention auto-deletes after 30 days.
Tier | Spec | Notes |
Minimum | 1 vCPU / 1 GB RAM / 10 GB disk | works with the defaults (ClamAV and SpamAssassin off) |
Comfortable | 1 vCPU / 2 GB RAM / 20 GB disk | headroom to enable SpamAssassin |
With antivirus | 4 GB RAM | ClamAV alone needs ~1 GB extra |
That's a $5/mo VPS — or a $10–15/year deal box. The real prerequisite isn't size, it's port 25: AWS, GCP, Azure, DigitalOcean and Vultr block it by default (some unblock on request). Check before you buy — or route outbound through a relay and you don't need port 25 out at all.
Comparison
openagent.email | AgentMail.to | MailSlurp | |
Open source | ✅ Apache-2.0 | ❌ | ❌ |
Self-hosted | ✅ | ❌ | ❌ |
Price | Flat VPS cost | Per-inbox subscription | Usage-based subscription |
Unlimited inboxes | ✅ (catch-all) | Paid tiers | Paid tiers |
MCP-native | ✅ | ✅ | ❌ (REST/SDKs) |
OTP/link extraction | ✅ | ✅ | ✅ |
Data leaves your infra | Never | Always | Always |
Roadmap
v0.1 — REST + MCP, catch-all identities,
wait_forwith OTP/link extraction, DNS wizard + doctor, optional SMTP relay.v0.2 (current) — scoped per-identity tokens, send rate limits, automatic retention, localhost-safe defaults, expanded OTP corpus.
Next — outbound webhooks (push instead of
wait_forpolling), multi-domain support, Sieve-style per-identity rules.Distribution — planned one-click app in the OpenShip catalog.
Docs
docs/api.md — REST API reference with curl examples
docs/security.md — tokens, exposure, rate limits, retention
docs/mcp-clients.md — MCP setup for every major client
docs/agent-signup.md — let agents finish sign-ups that email a code, with a verified OKX wallet example
docs/dns-setup.md — DNS records, explained one by one
docs/deliverability.md — the field guide to actually landing in the inbox
Contributing
Issues and PRs welcome — see CONTRIBUTING.md.
License
Maintenance
Related MCP Servers
- AlicenseBqualityCmaintenanceDisposable email MCP server for autonomous AI agents. Create labeled temporary inboxes, wait for verification emails, extract OTP codes and confirmation links — zero human intervention required.Last updated6MIT
- AlicenseAqualityCmaintenanceMCP server for disposable email — create inboxes, receive emails, and extract OTP codes. Let your AI agent sign up for services, wait for verification emails, and extract codes autonomously.Last updated7921MIT

AgenticMailofficial
AlicenseAqualityAmaintenanceReal email and SMS for AI agents. Run a local mail server with disposable inboxes — agents send and receive real email, fetch verification codes, and drive a real inbox without going through any third-party email API.Last updated100180MIT- Alicense-qualityCmaintenanceOpen-source, self-hosted Inbox-as-a-Service API for AI agents. It enables agents to manage email inboxes, send/receive emails, search messages, and wait for replies via REST or MCP.Last updated26Apache 2.0
Related MCP Connectors
Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.
Shipmail MCP server for AI agent custom-domain email inboxes with REST API and webhooks.
Email for AI agents — send, receive as a webhook, manage domains, templates, routing.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/openagentemail/openagentemail'
If you have feedback or need assistance with the MCP directory API, please join our Discord server