
A high-performance Mail Transfer Agent built on powpow.
Written in Nim language
nimble install meowmail
MeowMail is a high-performance, all-in-one mail server written in Nim. It handles SMTP (inbound/outbound), IMAP4rev1, and JMAP for modern clients, all built on powpow's event-driven networking (kqueue/epoll).
It's designed for developers and sysadmins who want to host their own email, from development environments to production deployments.
- Dual-stack IPv4/IPv6 listeners (ports 25, 587, 465; submission ports configurable)
- STARTTLS + implicit TLS (port 465)
- Verified outbound STARTTLS (chain + hostname) with opportunistic mode and per-host skip list
- Fail-fast delivery on NXDOMAIN/null MX, bounded DNS, per-stage timeouts, Happy Eyeballs racing
- AUTH PLAIN / LOGIN with local users or HTTP auth proxy
- DKIM signing (RSA-SHA256) + cryptographic verification with DNS key lookup
- SPF verification inbound and outbound (libspf2)
- Native DMARC evaluation inbound (RFC 7489) with report/quarantine/reject modes
- Joint SPF + DKIM alignment preflight on outbound delivery
- Native DNS via powpow (A/AAAA/MX/TXT with TTL cache, no external processes)
- SIZE extension with 50 MB streaming cap
- Persistent outbound queue with exponential backoff retry + background runner
- Bounce/DSN generation on delivery failure
- Rate limiting (per-IP connections, auth lockout, per-IP and per-user quotas)
- Configurable send policies (default, local-only, internal-only, no-relay)
- Full IMAP4rev1 implementation
- Maildir++ storage format
- UID/UIDVALIDITY persistence
- FETCH: ENVELOPE, BODYSTRUCTURE, BODY[section], partial, RFC822
- STORE, COPY, MOVE, EXPUNGE
- SEARCH (full query language)
- IDLE (poll-based)
- UIDPLUS, CHILDREN, NAMESPACE extensions
- STARTTLS support
- Core/echo
- Mailbox/get, Mailbox/set, Mailbox/query
- Email/get, Email/set, Email/query
- Identity/get
- EmailSubmission/set
- Session discovery (
/.well-known/jmap,/jmap/session)
- Queue management CLI (
queue.list,queue.stats,queue.flush,queue.retry,queue.delete,queue.purge) - Admin HTTP API (health, queue stats, JSON metrics; binds 127.0.0.1 by default, no auth yet)
- Structured logging (text or JSON, rotation, level filtering)
- TOML configuration
- Nim >= 2.2.0
- OpenSSL development libraries
- libspf2 (SPF verification)
macOS (Homebrew):
brew install openssl spf2Debian/Ubuntu:
apt-get install libssl-dev libspf2-devArch Linux:
pacman -S openssl spf2meowmail init meowmail.toml[smtp]
hostname = "mail.example.com"
[smtp.listen.port25]
enabled = true
port = 25
[smtp.listen.submission587]
enabled = true
port = 587
[smtp.listen.smtps465]
enabled = true
port = 465
[smtp.tls]
enabled = true
cert_file = "/etc/ssl/certs/meowmail.crt"
key_file = "/etc/ssl/private/meowmail.key"
[smtp.auth]
required = true
[smtp.auth.users]
"alice@example.com" = "secret-password"
[smtp.auth.dkim]
verify = true
[smtp.auth.dmarc]
mode = "report" # report | quarantine | reject
[smtp.delivery.mx.preflight.spf]
enabled = false
[smtp.delivery.mx.preflight.dmarc]
enabled = false
[smtp.delivery.mx]
helo_name = "mail.example.com"
connect_timeout_ms = 7000
command_timeout_ms = 10000
dns_timeout_ms = 8000
require_starttls = false
starttls_opportunistic = true
tls_skip_domains = []
[maildir]
base = "./maildir"
local_domains = ["example.com"]
[imap]
enabled = true
port = 143
[jmap]
enabled = true
port = 8080
[dkim]
enabled = true
domain = "example.com"
selector = "meowmail"
key_file = "/etc/ssl/private/meowmail-dkim.key"
[logging]
level = "info"
format = "text"
[admin]
enabled = true
port = 8081
host = "127.0.0.1"meowmail start meowmail.tomlswaks --server 127.0.0.1 --port 587 \
--tls \
--auth LOGIN \
--auth-user relay-user@example.com \
--auth-password change-me \
--from relay-user@example.com \
--to bodoti2371@fidhost.com \
--header "Subject: Hello from MeowMail" \
--body "This is a test email."| Command | Description |
|---|---|
meowmail init <path> |
Generate a default config file |
meowmail start <config> |
Start the mail server |
meowmail queue.list <dir> |
List queued messages |
meowmail queue.stats <dir> |
Show queue statistics |
meowmail queue.flush <dir> |
Force delivery of pending messages |
meowmail queue.retry <dir> <id> |
Requeue a specific message |
meowmail queue.delete <dir> <id> |
Remove a message from the queue |
meowmail queue.purge <dir> |
Remove delivered/bounced/failed messages |
meowmail spf <ip4> |
Generate an SPF DNS record |
meowmail dkim <keyfile> |
Generate a DKIM DNS record |
meowmail dmarc <policyfile> |
Generate a DMARC DNS record |
MeowMail uses TOML configuration. See example/meowmail.config.toml for all options.
[smtp] # SMTP server settings
[smtp.auth] # Authentication (local users or HTTP provider)
[smtp.auth.dkim] # Inbound DKIM verification toggle
[smtp.auth.dmarc] # Inbound DMARC mode (report | quarantine | reject)
[smtp.tls] # TLS certificate configuration
[smtp.delivery] # Delivery mode (mx or spool)
[smtp.delivery.mx] # Timeouts, STARTTLS policy, skip list
[smtp.validation] # Sender/recipient domain checks
[smtp.limits] # Per-IP and per-user quotas
[maildir] # Local Maildir storage
[imap] # IMAP server settings
[jmap] # JMAP server settings
[dkim] # DKIM signing
[logging] # Log format, rotation, level filtering
[queue] # Outbound queue settings
[admin] # Admin API endpointSelf-signed (development):
# Generate key + cert in one step
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/meowmail.key \
-out /etc/ssl/certs/meowmail.crt \
-subj "/CN=localhost"Let's Encrypt (production):
# Install certbot
apt install certbot # Debian/Ubuntu
brew install certbot # macOS
# Get a certificate (standalone mode)
certbot certonly --standalone -d mail.example.com
# Certs are at:
# /etc/letsencrypt/live/mail.example.com/fullchain.pem
# /etc/letsencrypt/live/mail.example.com/privkey.pem
# Auto-renew (add to crontab)
0 3 * * * certbot renew --quiet- Generate the self-signed cert (on your server):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/meowmail-example.key \
-out /etc/ssl/certs/meowmail-example.crt \
-subj "/CN=localhost"
- Set the paths in your TOML config:
[smtp.tls]
enabled = true
cert_file = "/etc/ssl/certs/meowmail.crt"
key_file = "/etc/ssl/private/meowmail.key"DKIM key pair:
# Generate RSA key for DKIM signing
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
-out /etc/ssl/private/meowmail-dkim.key
# Extract public key for DNS
openssl rsa -in /etc/ssl/private/meowmail-dkim.key \
-pubout -outform PEM | \
sed -n '/-----BEGIN/,/-----END/p' | tr -d '\n' | \
sed 's/-----BEGIN PUBLIC KEY-----//;s/-----END PUBLIC KEY-----//'
# Paste the output into your DNS TXT record| Variable | Description |
|---|---|
MEOWMAIL_SMTP_PORT |
Override SMTP listen port |
MEOWMAIL_IMAP_PORT |
Override IMAP listen port |
MEOWMAIL_MAILDIR |
Override maildir base path |
MEOWMAIL_LOCAL_DOMAINS |
Comma-separated local domains |
- SMTP server with STARTTLS + implicit TLS
- AUTH PLAIN/LOGIN, send policies, require-TLS-for-auth
- DKIM signing + cryptographic verification (RSA-SHA256, DNS key lookup)
- SPF inbound + outbound (libspf2)
- Native DMARC evaluation inbound + joint alignment preflight outbound
- Native DNS via powpow (A/AAAA/MX/TXT); Happy Eyeballs connection racing
- IMAP4rev1 with Maildir++
- JMAP server (Core, Mailbox, Email, Submission)
- Persistent outbound queue with retry + background runner
- Fail-fast delivery on NXDOMAIN/null MX + bounded DNS + per-stage timeouts
- Outbound TLS: verified STARTTLS (chain + hostname), opportunistic mode with plaintext fallback, skip list
- Configurable submission/SMTPS ports
- Bounce/DSN generation
- Rate limiting + quotas + brute-force protection
- Queue management CLI
- Admin API (health, queue, JSON metrics)
- Structured logging (JSON, rotation)
- JMAP EmailSubmission delivery wiring (submissions are queued, SMTP handoff pending)
- AUTH CRAM-MD5 / XOAUTH2
- Custom CA bundle path for outbound TLS verify (system store is used today)
- ARC (Authenticated Received Chain)
- MTA-STS (RFC 8461)
- DANE/TLSA
- SMTPUTF8 (RFC 6531)
- Prometheus-format metrics, admin web dashboard, admin auth
- Found a bug? Create an issue
- Want to contribute? Fork and open a PR
MIT license. Made by Humans from OpenPeeps.
Copyright OpenPeeps and Contributors. All rights reserved.