cloud-1 (phx) and cloud-2 (us-sanjose-1) are both already OCI aarch64 instances, so the open question in ADR 0005 was answerable directly rather than by reading forum posts. Measured from cloud-2: BLOCKED 25 gmail-smtp-in.l.google.com, aspmx.l.google.com OPEN 587/465/2525 gmail, sendgrid, SES, OCI Email Delivery The community reports claiming 587 and 2525 are also blocked are wrong. Only 25 is blocked, exactly as Oracle documents, so relay works and the launch host is viable. Inbound :25 reachability is still unverified — that is a VCN security-list change, not a platform limit. ROADMAP.md carries the goal, three success signals that are deliberately not v0.1, a definition-of-ready checklist, and five standing rules. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JkyvfNJGTshJNE9FtwPLk7
OpenMail
An agent-native, self-hosted mail server, written in Rust.
One binary that gives an AI agent its own real email address — receive, parse, thread, search and send actual SMTP mail on infrastructure you control — behind a clean REST API and an MCP server. Humans and agents are both first-class users.
Status: v0.1, work in progress, not yet released. The workspace compiles and the domain model is taking shape; it does not yet send or receive mail. Follow
docs/adr/0004-milestones.md.
Why this exists
The hard part of an agent-mailbox product was never the API. It is the mail plumbing: receiving over SMTP/MX, sending with real deliverability (SPF/DKIM/DMARC, DANE/MTA-STS, IP reputation), parsing genuinely broken MIME, threading, and storage.
Hosted agent-mail products solve this well and run on someone else's infrastructure, closed. The self-hostable mail servers that exist — Postfix+Dovecot, iRedMail, Stalwart — solve the plumbing but have no notion of an agent: no per-agent inbox provisioning, no threads as API resources, no MCP, no way for an agent to own a mailbox.
OpenMail is the intersection nobody occupies: agent-native, self-hostable, and permissively licensed.
What makes it agent-native
- Inboxes are API resources, provisioned in one call — not Unix accounts.
- Threads are first-class, stitched from
In-Reply-To/References. An agent asks for a conversation, not a folder listing. extracted_text— the reply with quoted history stripped. An agent that reads full bodies re-reads the whole thread every turn and burns its context window on text it already has.- MCP server — an agent owns and operates its own mailbox as tools.
- Webhooks + WebSocket
message.receivedevents. Push, not poll. - Humans too — standard IMAP/SMTP access is a first-class goal, not an afterthought, so a person can point Apple Mail or Thunderbird at the same mailbox an agent is driving.
Why Rust, and why our own crates
Two implementations of the mail plumbing exist in a permissive licence: Mox (MIT, Go) and — for the primitives only — Stalwart's published crates (Apache-2.0/MIT, Rust). Stalwart's server is AGPL-3.0, which is why nobody has shipped a permissively licensed Rust mail server.
We are building one. See docs/adr/0001-rust.md for
the decision and its honest costs.
Concretely, this means writing what the Rust ecosystem does not have. At the
time of writing, dane and mta-sts do not exist on crates.io at all —
Stalwart keeps its implementations inside AGPL server crates. Ours ship
standalone and permissive, so any Rust mail project can use them.
The workspace
Twelve crates in three tiers. Tier 1 is published to crates.io as a contribution to the Rust mail ecosystem and depends on nothing else here.
Tier 1 — standalone, publishable
| Crate | What | Prior art in Rust |
|---|---|---|
mail-dane |
DANE / TLSA verification for SMTP (RFC 7672) | none — first permissive implementation |
mail-mta-sts |
MTA-STS policy discovery, fetch, parse, cache (RFC 8461) | none — first permissive implementation |
mail-dsn |
Delivery Status Notifications (RFC 3464) | none |
Tier 2 — the mail engine
| Crate | What |
|---|---|
openmail-smtpd |
Inbound SMTP: session state machine, STARTTLS, AUTH, PIPELINING |
openmail-relay |
Outbound: smarthost relays (SES, Oracle, generic) and direct-to-MX |
openmail-guard |
Abuse gate: iprev, DNSBL, rate limiting |
openmail-junk |
Per-inbox Bayesian spam classification |
Tier 3 — the agent-native layer (the product)
| Crate | What |
|---|---|
openmail-core |
Domain model, threading, quote-stripping. No I/O. |
openmail-store |
Postgres metadata + S3-compatible blobs |
openmail-api |
The v0 REST API |
openmail-mcp |
MCP server |
openmail |
The binary: serve, smtpd, sender, mcp, migrate |
Third-party
mail-parser, mail-builder, mail-auth (DKIM/DKIM2/SPF/DMARC/ARC),
smtp-proto — all Apache-2.0 OR MIT, all from Stalwart Labs' separately
published primitive crates — plus hickory-resolver for DNS and DNSSEC.
No AGPL, GPL, or LGPL code is linked into any OpenMail binary. We use none
of the Stalwart server. See NOTICE and
docs/adr/0003-own-crates.md.
Sending: bring your own reputation, or build your own
Outbound sits behind one interface with two paths:
- Relay — SES, Oracle Cloud Email Delivery, SendGrid, Postmark, Resend, or
any smarthost. Rents someone else's IP reputation; inbox placement on day
one. Providers are declarative data, not special cases —
crates/openmail-relay/src/providers.rs. - Direct-to-MX — we resolve MX and deliver ourselves, with MTA-STS and DANE enforced. Our reputation, our control, and a months-long IP warmup.
Receiving is always ours.
⚠️ Oracle Cloud blocks outbound TCP/25 for tenancies created after 2021-06-23. Inbound :25 is unaffected. So on OCI you receive directly and relay outbound on 587 — direct-to-MX is not possible there at all.
docs/adr/0005-oracle-cloud.md.
Build
cargo check --workspace # ~21s cold on a Ryzen 7 5800X
cargo test --workspace
cargo clippy --workspace --all-targets # zero warnings is the gate
unsafe_code = "forbid" across the workspace. This code parses hostile input
from the open internet on port 25; there is no exception worth the risk.
Licence
Apache-2.0. Permissive on purpose: the point is that other people can build
commercial products on top of this, including ones that compete with anything
we might host later. See docs/adr/0002-apache-2.md
for why Apache-2.0 rather than MIT or AGPL.