Authenticated email gateway for AI agents — SPF/DKIM verified inbound, HMAC-signed delivery, webhook + WebSocket fan-out, CLI + SDKs
git clone https://github.com/tokencanopy/e2a{
"mcpServers": {
"e2a": {
"command": "e2a"
}
}
}MCP Servers overview
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/e2a-wordmark-dark.svg">
<img src="assets/e2a-wordmark-light.svg" width="320" alt="e2a">
</picture>
### Give your AI agents a real, authenticated email address.
Receive inbound over **webhook · WebSocket · REST · MCP**. Send through an **HTTP API**. Every sender — human or agent — **identity-verified**.
<sub>A [Token Canopy](https://tokencanopy.com) product</sub>
[](https://github.com/tokencanopy/e2a/actions/workflows/test.yml)
[](https://github.com/tokencanopy/e2a/actions/workflows/build-image.yml)
[](LICENSE)
[](https://www.npmjs.com/package/@e2a/sdk)
[](https://pypi.org/project/e2a/)
[Hosted (e2a.dev)](https://e2a.dev) · [Quickstart](#quickstart) · [Concepts](#concepts) · [API](#api) · [SDKs](#sdks) · [MCP](#mcp-server) · [Deploy](#deployment) · [FAQ](#faq)
<a href="https://www.producthunt.com/products/e2a-open-source-email-api-for-agents?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-e2a-open-source-email-api-for-agents" target="_blank" rel="noopener noreferrer"><img alt="e2a – open-source email API for agents - Give your AI agents a real, authenticated email address. | Product Hunt" width="250" height="54" src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1145559&theme=light&t=1778615217650"></a>
</div>
---
> [!IMPORTANT]
> **The `/v1` API and SDKs are release candidates and are not yet stable. GA is planned by July 31, 2026; stable compatibility guarantees begin only with the explicitly announced GA release tag.** Existing `v1.0.x` application/cherry-pick tags predate the API freeze and are not `/v1` compatibility baselines. Pin your SDK versions and watch [Releases](https://github.com/tokencanopy/e2a/releases).
e2a is an **authenticated email gateway for AI agents**. It receives inbound mail, evaluates SPF, every DKIM signature, and DMARC, and delivers structured authentication evidence over whichever channel fits your runtime. Outbound goes back out through an HTTP API, with an optional human-in-the-loop approval gate.
**Four ways to plug an agent in:**
- **MCP** — point any MCP-aware runtime at the hosted server (`https://api.e2a.dev/mcp`) and your agent gets an inbox toolset (`list_messages`, `send_message`, `reply_to_message`, …). The fastest path for agent frameworks. → [MCP server](#mcp-server)
- **SDKs** — TypeScript (`@e2a/sdk`) and Python (`e2a`) clients with one-call webhook verification and a WebSocket `listen()` stream. → [SDKs](#sdks)
- **Raw delivery** — subscribe a **webhook**, open a **WebSocket**, or **poll** the REST API directly. → [Delivery channels](#delivery-channels)
- **CLI** — `e2a listen` bridges inbound mail to a local HTTP handler (including an OpenAI Responses auto-reply mode). → [CLI](#cli)
What you get on top of bare SMTP:
- **Authenticated inbound identity** — normalized SPF, DKIM, and DMARC evidence, with an explicit aligned DMARC verdict
- **No public URL required** — WebSocket, REST polling, and MCP all work from a laptop or behind a firewall
- **Outbound API** — agents send to other agents (SMTP relay) or humans (upstream SMTP, e.g. SES, Resend)
- **Human in the loop** — opt-in approval gate that holds outbound mail until a reviewer approves via dashboard, magic-link email, the MCP tools, or the API
- **Inbound threat screening** — opt-in content scan flags **prompt-injection** payloads (hidden HTML, Unicode-tag smuggling, encoded text) — and, with the LLM detector, **phishing** — then routes each message to *allow · review · block*, feeding the same review queue as HITL → [Content screening](#content-screening)
- **Conversation threading** — a stable `conversation_id` that survives the email ↔ structured-data boundary
- **Email templates (beta)** — reusable `{{variable}}` templates rendered server-side at send time, plus a pre-built starter catalog → [docs/templates.md](docs/templates.md)
## Quickstart
The fastest path is to give your AI agent an inbox directly. Install the e2a plugin — it registers the hosted [MCP server](#mcp-server) and an operate-well skill, so your agent can send, receive, reply in-thread, and hold mail for review out of the box. On first tool use it runs an OAuth flow in your browser — no API key to paste.
**Claude Code**
```
claude plugin marketplace add tokencanopy/e2a
claude plugin install e2a@e2a
```
**Codex**
```
codex plugin marketplace add tokencanopy/e2a
```
Then launch `codex`, run `/plugins`, and install **e2a**.
**Cursor** — add the MCP server directly. Put this in `.cursor/mcp.json` (or `~/.cursor/mcp.json` to get it in every project); Cursor opens your browser to authorize on first use, no API key to paste:
```json
{
"mcpServers": {
"e2a": { "url": "https://api.e2a.dev/mcp" }
}
}
```
**Other MCP clients** (Zed, Goose, Windsurf, Claude Desktop, raw `mcp.json`) — point straight at `https://api.e2a.dev/mcp`; ready-to-paste configs are in [plugins/e2a/clients/](plugins/e2a/clients). See [plugins/e2a/README.md](plugins/e2a/README.md) for the full per-client guide.
## Use it
You can either use the hosted instance or self-host.
- **Hosted** — sign up at [e2a.dev](https://e2a.dev). Includes the shared `agents.e2a.dev` domain for instant slug-based onboarding (no DNS setup), a dashboard, the hosted MCP server, and managed deliverability.
- **Self-host** — see [Self-host (Docker)](#self-host-docker) and [Deployment](#deployment). Every feature works the same; the shared-domain slug shortcut just needs you to point a mail domain at your relay and set `shared_domain` in `config.yaml`.
## How it works
```
Human (Gmail/Outlook) · another e2a agent
│ ▲
inbound │ │ outbound
SMTP ▼ │ upstream SMTP (to humans) / relay (to agents)
┌───────────────┐
│ e2a relay │ ← MX for your agent domain points here
│ │
│ inbound ↓ │ ← evaluate SPF/DKIM/DMARC · deliver
│ outbound ↑ │ ← optional HITL hold · send
└───────────────┘
│ ▲
deliver │ │ send · reply · forward (HTTP API)
▼ │
┌───────────────┐
│ your agent │ ← webhook / WebSocket / REST poll / MCP · SDK · CLI
└───────────────┘
```
Inbound flow: SMTP → SPF/DKIM/DMARC evaluation → agent lookup → webhook / WebSocket / REST / MCP delivery.
Outbound flow: API call → optional HITL hold → SMTP relay (agent-to-agent) or upstream SMTP (agent-to-human).
## Concepts
### Delivery channels
Inbound mail reaches you several complementary ways — **chosen per integration, not set on the agent**. There is no delivery "mode" on the agent record; any agent the caller owns can be consumed over any of these:
| Channel | How | Public URL needed? |
|---------|-----|---------------------|
| **Webhooks** | Account-level subscriptions (`POST /v1/webhooks`) — HTTPS POST per event, filterable by agent / conversation / event type | Yes |
| **WebSocket** | Per-agent real-time notification stream (`/v1/agents/{email}/ws`) + REST fetch | No |
| **REST polling** | Pull messages via `GET /v1/agents/{email}/messages` — the default path for MCP-based agents | No |
| **MCP tools** | The e2a [MCP server](#mcp-server)'s inbox tools (`list_messages`, `get_message`, `get_attachment`, `list_conversations`, …) layered over the REST API | No |
Notifications carry lightweight metadata (message id, sender, subject); you fetch the full body + attachments over REST when you want them. A disconnected WebSocket client accumulates "unread" messages; on reconnect, the server drains them as notifications.
Webhooks are an **account-level resource** (`/v1/webhooks`), chosen per integration rather than configured on the agent.
### Inbound authentication
Inbound messages expose `header_from` (the parsed RFC 5322 From address), `envelope_from` (SMTP MAIL FROM), `verified_domain` (a nullable DMARC-pass convenience projection), and—on detail responses—`authentication` (SPF, every DKIM signature, and the aligned DMARC result). Reply-To remains separate and never replaces `header_from`.
For list and review decisions, a non-null `verified_domain` means DMARC passed for that RFC 5322 From domain. On detail responses, the equivalent check is `authentication?.dmarc.status === "pass"`. Neither field authenticates the mailbox local part, a person, or message content. `authentication` is null for outbound messages and providerless local loopback delivery.
Before trusting any webhook field, verify the delivery envelope's `X-E2A-Signature` with the webhook's `whsec_…` signing secret. The envelope signature covers the complete structured payload, including `authentication`.
The one-call shortcut parses **and** verifies a delivery, returning a typed event — use it instead of trusting any field on an unverified payload:
For small signed-webhook references using the ergonomic inbound facade, see
the [minimal Python and TypeScript OpenAI examples with provider snippets](examples/agent-framework-webhooks/README.md).
```python
from e2a.v1 import construct_event, E2AWebhookSignatureError
# raw request body + the X-E2A-Signature header + your whsec_… secret
try:
event = construct_event(request_body, signature_header, webhook_secret)
except E2AWebhookSignatureError:
abort(400) # bad signature — reject the delivery
if event.type == "email.received":
email = await client.inbound.from_event(event)
print(email.envelope_from, email.verified, email.reply_targets)
result = await email.reply({"text": "Got it"})
if result.status == "pending_review":
notify_human(result.messageWhat people ask about e2a
What is tokencanopy/e2a?
+
tokencanopy/e2a is mcp servers for the Claude AI ecosystem. Authenticated email gateway for AI agents — SPF/DKIM verified inbound, HMAC-signed delivery, webhook + WebSocket fan-out, CLI + SDKs It has 177 GitHub stars and was last updated today.
How do I install e2a?
+
You can install e2a by cloning the repository (https://github.com/tokencanopy/e2a) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is tokencanopy/e2a safe to use?
+
tokencanopy/e2a has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains tokencanopy/e2a?
+
tokencanopy/e2a is maintained by tokencanopy. The last recorded GitHub activity is from today, with 24 open issues.
Are there alternatives to e2a?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy e2a to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/tokencanopy-e2a)<a href="https://claudewave.com/repo/tokencanopy-e2a"><img src="https://claudewave.com/api/badge/tokencanopy-e2a" alt="Featured on ClaudeWave: tokencanopy/e2a" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!