Simple mailing list software with IMAP mailbox backend, web interface, and multiple list modes.
Project description
CastMail2List
CastMail2List is a lightweight, self-hosted mailing list application. It polls standard IMAP mailboxes for incoming messages, distributes them to subscribers, and provides a web interface for list management. No MTA configuration, no complex server setup — just point it at one or more IMAP accounts and go.
Why CastMail2List?
Compared to plain email forwarding:
- Subscriber management with a web UI and REST API
- Two list modes: broadcast (newsletters/announcements) and group (discussion lists)
- Sender authorization via allowed-sender lists or password-based authentication
- Automatic bounce detection
- Duplicate message prevention
- Per-list IMAP accounts — each list can use its own mailbox
- Message logs, delivery tracking, and rejection notifications
Compared to Mailman 3 or similar:
- Minimal dependencies — runs on Python 3.10+, SQLite, and any IMAP/SMTP provider
- No MTA integration required — works with any email provider that offers IMAP and SMTP
- Simple YAML-based configuration
- Hierarchical list support via nested lists (lists can subscribe to other lists)
- Easy to deploy on shared hosting (Uberspace natively supported) or as a container
- Single process, small footprint - suitable for personal use or small communities
CastMail2List is not a replacement for Mailman in large-scale or enterprise setups. It's designed for people who want mailing list functionality without the operational overhead of running a full mail server stack.
Features
- Broadcast mode — one-to-many distribution (newsletters, announcements). Only authorized senders can post.
- Group mode — many-to-many discussion lists with reply-to-list behavior.
- Web interface — manage lists, subscribers, messages, and delivery logs.
- REST API — programmatic subscriber management with API key authentication.
- IMAP-based — polls mailboxes on a configurable interval; no MTA hooks needed.
- Bounce handling — detects bounced messages and tracks per-subscriber bounce counts.
- Sender authorization — allowed-sender lists and/or password-in-address authentication.
- Rejection notifications — optionally notify senders when their message is rejected.
- Nested lists — lists can include other lists as subscribers for hierarchical distribution.
- Internationalization — UI available in English and German; extensible via standard gettext.
- Database migrations — schema changes handled automatically via Alembic/Flask-Migrate.
Installation
From PyPI
pip install castmail2list
From source
git clone https://github.com/mxmehl/castmail2list.git
cd castmail2list
uv sync --no-dev
Quick start
-
Create a configuration file:
cp config.example.yaml config.yaml
-
Edit
config.yamlwith your IMAP/SMTP credentials, database path, and other settings. Seeconfig.example.yamlfor all available options. -
Run the application:
For production (using gunicorn as WSGI server):
castmail2list --config config.yaml
For development and admin commands (using Flask directly):
castmail2list-cli --config config.yaml --debug
-
Access the web interface at
http://localhost:2278and log in with the credentials set in your configuration.
Run castmail2list --help or castmail2list-cli --help for all available options.
Configuration
CastMail2List is configured via a YAML file. Key settings include:
| Setting | Description |
|---|---|
DATABASE_URI |
SQLAlchemy database URI (default: SQLite in XDG config dir) |
SECRET_KEY |
Flask secret key for session security |
DOMAIN |
Domain shown in list headers |
IMAP_DEFAULT_* |
Default IMAP connection settings for new lists |
SMTP_* |
SMTP server settings (shared across all lists) |
POLL_INTERVAL_SECONDS |
How often to check mailboxes (default: 60) |
CREATE_LISTS_AUTOMATICALLY |
Auto-create lists from incoming mail (default: false) |
See config.example.yaml for the full reference.
Documentation
- Mailing list modes and headers — how broadcast and group modes differ
- Sender authorization — controlling who can send to a list
- API documentation — REST API for subscriber management
- Contributing — development setup, testing, and translation guide
Contributing
Contributions and translations are welcome! See CONTRIBUTING.md for development setup, testing, and translation guidelines.
Copyright and Licensing
This project is mainly licensed under the Apache License 2.0, copyrighted by Max Mehl.
It also contains files from different copyright holders and under different licenses. As the project follows the REUSE best practices, you can find the according information for each individual file.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file castmail2list-0.7.2.tar.gz.
File metadata
- Download URL: castmail2list-0.7.2.tar.gz
- Upload date:
- Size: 396.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7447e0f93d1119d4cd8b920b745aff87d9375fc6b69c01113d02e67248b13f3
|
|
| MD5 |
1321fa3c2a7056ff011f094d31922358
|
|
| BLAKE2b-256 |
5c74d4b876e6a0180eab38929bb62f7a462325b0b1371e644e0ceb312d6a1f6c
|
Provenance
The following attestation bundles were made for castmail2list-0.7.2.tar.gz:
Publisher:
publish.yaml on mxmehl/castmail2list
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
castmail2list-0.7.2.tar.gz -
Subject digest:
c7447e0f93d1119d4cd8b920b745aff87d9375fc6b69c01113d02e67248b13f3 - Sigstore transparency entry: 1357214852
- Sigstore integration time:
-
Permalink:
mxmehl/castmail2list@880c991cf9db298381ec71d650558e63e45944bd -
Branch / Tag:
refs/tags/v0.7.2 - Owner: https://github.com/mxmehl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@880c991cf9db298381ec71d650558e63e45944bd -
Trigger Event:
release
-
Statement type:
File details
Details for the file castmail2list-0.7.2-py3-none-any.whl.
File metadata
- Download URL: castmail2list-0.7.2-py3-none-any.whl
- Upload date:
- Size: 450.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0367cfc2950b30b9ec7670bf1017815ac81adfd9fa6958ba10262115f98d3c5
|
|
| MD5 |
63b7015902f67bbdd3d4bc5fe281e209
|
|
| BLAKE2b-256 |
e43db1cf0ce9452ea7c33c0b26c8d349ee5eb19cb5b6c41933fe95a48a80c571
|
Provenance
The following attestation bundles were made for castmail2list-0.7.2-py3-none-any.whl:
Publisher:
publish.yaml on mxmehl/castmail2list
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
castmail2list-0.7.2-py3-none-any.whl -
Subject digest:
d0367cfc2950b30b9ec7670bf1017815ac81adfd9fa6958ba10262115f98d3c5 - Sigstore transparency entry: 1357214855
- Sigstore integration time:
-
Permalink:
mxmehl/castmail2list@880c991cf9db298381ec71d650558e63e45944bd -
Branch / Tag:
refs/tags/v0.7.2 - Owner: https://github.com/mxmehl
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@880c991cf9db298381ec71d650558e63e45944bd -
Trigger Event:
release
-
Statement type: