MCPcopy Index your code
hub / github.com/erooster-mail/erooster

github.com/erooster-mail/erooster @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
538 symbols 1,261 edges 82 files 41 documented · 8%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Erooster

codecov Contributor Covenant

A mail suite written in Rust, meant to be easy to use.

Features

IMAP (ports 143 / 993) - IMAP4rev2 (RFC 9051) and IMAP4rev1 (RFC 3501) compatible - TLS on port 993, STARTTLS on port 143 - Extensions: IDLE, NAMESPACE, UNSELECT, MOVE, ESEARCH, ENABLE, UTF8=ONLY - AUTH=PLAIN over TLS

SMTP (port 25) - STARTTLS - Extensions: PIPELINING, SIZE, 8BITMIME, AUTH LOGIN PLAIN (over TLS), REQUIRETLS, VRFY - DKIM signing on outbound messages (RSA PKCS#1 and PKCS#8) - DKIM and DMARC verification on inbound messages - SPF verification - Optional Rspamd integration for spam filtering

General - Maildir storage - PostgreSQL (default) or SQLite backend - Single binary, stable Rust - Autoconfig endpoint (/mail/config-v1.1.xml) for automatic client setup (Thunderbird etc.) - Optional Sentry error reporting

Non-goals

  • MySQL / MariaDB support
  • POP3
  • Exchange / ActiveSync
  • Every optional extension from every RFC

Getting started

Requirements

  • TLS certificates in PEM format (e.g. from Let's Encrypt)
  • DKIM key pair
  • PostgreSQL database (or SQLite for testing)

Generate DKIM keys

opendkim-genkey \
    --domain=<your-hostname> \
    --subdomains

Save the .private file at the path you set in mail.dkim_key_path and add the generated TXT record to your DNS.

Configuration

Create config.yml in /etc/erooster/ or the working directory:

tls:
  key_path: "./certs/key.pem"
  cert_path: "./certs/cert.pem"
mail:
  maildir_folders: "./maildir"
  hostname: "example.com"
  displayname: "Erooster"
  dkim_key_path: "/etc/erooster/keys/default.private"
  dkim_key_selector: "default"
database:
  url: "postgres://user:password@localhost/erooster"
listen_ips:
  - "0.0.0.0"
  - "[::]"
webserver:
  port: 80
  tls: false
# Optional — remove if not using Rspamd
rspamd:
  address: http://localhost:11333

maildir_folders is the root directory where per-user mail is stored in Maildir format.

Run

cargo run --release

Or with SQLite (testing only):

cargo run --release --no-default-features --features sqlite

Manage users

Use the bundled eroosterctl binary. It reads the same config.yml.

# Create a new user
eroosterctl register

# Change a user's password
eroosterctl change-password

Passwords are stored as Argon2 hashes.

SQLite

SQLite is supported as a compile-time feature (--features sqlite) and is useful for local development and tests. It is not recommended for production — use PostgreSQL instead.

Support

Due to personal constraints, there is no enterprise support for Erooster. Please open GitHub issues instead. Responses are best-effort with no guaranteed time frame.

Error reporting

Erooster does not report errors automatically. A GitHub link is printed on panics. You can optionally configure a Sentry DSN via environment variable for self-hosted error reporting.

Extension points exported contracts — how you extend this code

MailEntry (Interface)
Representation of a Mail entry [1 implementers]
crates/erooster_core/src/backend/storage/mod.rs
Server (Interface)
(no doc) [2 implementers]
crates/erooster_imap/src/lib.rs
AsyncReadWrite (Interface)
(no doc) [1 implementers]
crates/erooster_smtp/src/servers/sending.rs
Database (Interface)
(no doc) [2 implementers]
crates/erooster_core/src/backend/database/mod.rs
MailStorage (Interface)
(no doc) [1 implementers]
crates/erooster_core/src/backend/storage/mod.rs

Core symbols most depended-on inside this repo

contains
called by 39
crates/erooster_imap/src/commands/parsers.rs
as_str
called by 38
crates/erooster_core/src/backend/queue.rs
add_flag
called by 35
crates/erooster_core/src/backend/storage/maildir.rs
get_pool
called by 33
crates/erooster_core/src/backend/database/sqlite.rs
parse
called by 30
crates/erooster_imap/src/commands/mod.rs
exec
called by 28
crates/erooster_imap/src/commands/uid.rs
as_bytes
called by 26
crates/erooster_core/src/config.rs
to_ondisk_path
called by 23
crates/erooster_core/src/backend/storage/maildir.rs

Shape

Function 269
Method 141
Class 91
Enum 32
Interface 5

Languages

Rust100%

Modules by API surface

crates/erooster_core/src/backend/storage/maildir.rs51 symbols
crates/erooster_imap/src/commands/parsers.rs39 symbols
crates/erooster_core/src/config.rs25 symbols
crates/erooster_smtp/src/servers/dane.rs24 symbols
crates/erooster_imap/src/commands/mod.rs21 symbols
crates/erooster_smtp/src/servers/mta_sts.rs18 symbols
crates/erooster_core/src/backend/queue.rs17 symbols
crates/erooster_imap/src/commands/list.rs16 symbols
crates/erooster_core/src/line_codec.rs13 symbols
crates/eroosterctl/src/status.rs12 symbols
crates/erooster_imap/src/commands/search.rs12 symbols
crates/erooster_smtp/src/commands/mod.rs11 symbols

Datastores touched

eroosterDatabase · 1 repos

For agents

$ claude mcp add erooster \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact