An open-source, programmable mail server for apps and AI agents. Haraka-based SMTP (MX + submission) and a thin IMAP head, designed around one small HTTP backend contract — run it fully self-hosted, or point the same components at MailKite Cloud and skip the ops.
Status: pre-1.0. The SMTP/IMAP edges here run MailKite's production mail; the reference SQLite backend and web console are new (first public release 2026-08-01, now v0.5.0) and pass the conformance + end-to-end suites.
| Component | What it is |
|---|---|
mta/ |
Inbound MX edge — Haraka + plugins that POST accepted mail to your backend as a webhook, with live anti-open-relay recipient checks |
mta-submit/ |
Submission edge (587/465) — authenticated send with DKIM signing, relayed through your backend |
imap/ |
IMAP4 head (993, implicit TLS) — a stateless protocol daemon on imap-core; all storage lives behind the backend contract |
api-local/ |
Reference REST API: Node + SQLite + file blobs implementing the contract below — zero npm dependencies. Inbound webhooks with signing + retries, and smarthost outbound (SMARTHOST=cloud or any SMTP relay) |
ui/ |
Web console for domains, DNS records, message log, webhooks, and credentials — magic-link sign-in, pluggable providers (local or MailKite Cloud) |
Every component is a dumb protocol head. State lives behind a handful of HMAC-authenticated
HTTP endpoints (/api/imap/{auth,status,list,flags,raw}, an inbound ingest hook, and a
submission inject endpoint). Implement that contract over any store and every edge here
works unchanged — the reference SQLite backend and MailKite Cloud are just two
implementations of it. One MX edge can even serve several backends at once, routing
each recipient domain to its owner — see docs/multi-backend.md.
See docs/contract.md and docs/app-passwords.md
(mailbox credentials: one domain, an address pattern, IMAP and/or API access); the conformance suite
in api-local/test/ is its executable form, and scripts/e2e-imap.mjs proves the
full stack (signed ingest → backend → the real IMAP daemon → a TLS IMAP client).
Runs on any Node ≥ 22.5 host — VPS (systemd), Docker, Fly.io, Railway. Serverless (Workers/Vercel) is intentionally out of scope: those runtimes can't hold SQLite state or raw-TCP mail ports, and the hosted backend for that style is MailKite Cloud.
- Quick start:
docker compose up -d→ backend + web console on:8787(compose.yaml;--profile edgesadds the MX edge) - Hosted:
deploy/fly.md·deploy/railway.md - Bare VPS (full mail stack incl. IMAP/submission):
docs/self-hosting.md— DNS records, TLS provisioning, and systemd units. Short version: one VPS, three daemons, your backend URL in one env var.
Don't want to run mail infrastructure? MailKite Cloud is the hosted backend + dashboard, with deliverability, retention, and support handled for you.
Code is licensed under AGPL-3.0-only — see LICENSE.
The MailKite name and logo are not covered by the code license; see
TRADEMARK.md and brand-assets/. Forks must use their
own name and branding.
Contributions require a signed CLA — see CONTRIBUTING.md.