Simple SMTP Server for debugging
Project description
dsmptd: A debugger SMTP server for Humans
dsmtpd is a small tool to help the developer without an smtp server
Python Support: Python 3.10, 3.11, 3.12, 3.13, 3.14
Usage
$ dsmtpd -p 1025 -i 127.0.0.1 2013-01-13 14:00:07,346 INFO: Starting SMTP server at 127.0.0.1:1025
Installation
For the installation, we recommend to use a virtualenv, it’s the easy way if you want to discover this package:
virtualenv ~/.envs/dsmtpd source ~/.envs/dsmtpd/bin/activate pip install dsmtpd
Command-Line Options
- -p PORT, --port PORT
Specify the port to listen on. Default: 1025
- -i INTERFACE, --interface INTERFACE
Specify the network interface to bind to. Default: 127.0.0.1 (loopback)
- -d DIRECTORY, --directory DIRECTORY
Specify a Maildir directory to save incoming emails. Default: current directory
- -s SIZE, --max-size SIZE
Maximum message size in bytes. Use 0 for no limit. Default: 33554432 (32 MiB)
- --disable-smtputf8
Disable SMTPUTF8 extension for legacy SMTP client compatibility. Default: enabled
- --version
Show program version and exit
- -h, --help
Show help message and exit
Usage Examples
Start server with default settings (port 1025, localhost):
dsmtpd
Start server on custom port:
dsmtpd -p 2525
Bind to all interfaces:
dsmtpd -i 0.0.0.0 -p 25
Save emails to specific Maildir:
dsmtpd -d /path/to/maildir
Limit message size to 10 MB:
dsmtpd --max-size 10485760
Disable UTF-8 support for legacy clients:
dsmtpd --disable-smtputf8
Send a test email with swaks:
swaks --from sender@example.com --to recipient@example.com --server localhost --port 1025
Features
SMTPUTF8 Support
dsmtpd has built-in support for SMTPUTF8 (RFC 6531), which allows email addresses and content to contain UTF-8 characters. This feature is enabled by default and requires no configuration.
SMTPUTF8 enables:
Email addresses with international characters (e.g., 用户@例え.jp)
UTF-8 encoded message headers and body content
Full Unicode support in SMTP transactions
Example usage with UTF-8 email addresses:
swaks --from user@example.com --to 用户@例え.jp --server localhost --port 1025
This functionality is provided by the underlying aiosmtpd library and works transparently with all standard SMTP clients that support the SMTPUTF8 extension.
Disabling SMTPUTF8
If you need to test compatibility with legacy SMTP clients or reproduce encoding issues, you can disable SMTPUTF8:
dsmtpd --disable-smtputf8
When disabled, the server will not advertise SMTPUTF8 support and will only accept ASCII email addresses and content.
Exit Codes
dsmtpd uses specific exit codes to indicate the result of its execution.
Code |
Meaning |
Example |
|---|---|---|
0 |
Success |
Normal shutdown (e.g. user pressed Ctrl+C) or clean termination. |
2 |
Invalid Maildir directory |
The given path exists but does not contain the required subfolders: tmp, new, and cur. |
Contributing
Clone the repository:
git clone git://github.com/matrixise/dsmtpd.git cd dsmtpd
Development
The project includes a Makefile to simplify development tasks. It automatically manages a virtual environment and dependencies using Python from asdf or mise.
Quick Start
Set up your development environment:
make install-dev
This creates a .venv virtual environment and installs all development dependencies.
Available Make Targets
Development Workflow:
make install-dev - Set up development environment (creates venv and installs dependencies)
make test - Run tests with pytest (automatically installs dependencies if needed)
make lint - Check code quality with ruff linter
make lint-fix - Auto-fix linting issues and format code with ruff
make format - Format code with ruff format
make typecheck - Run mypy type checking
Build and Release:
make build - Build distribution packages
make check-dist - Verify distribution package integrity
Cleanup:
make clean - Remove all build artifacts and virtual environment
make clean-build - Remove only build artifacts (dist/, build/)
make clean-venv - Remove only the virtual environment
Workflow Tips
The Makefile uses smart dependency tracking. Running make test multiple times will only reinstall dependencies if requirements-dev.txt or setup.cfg have changed, making repeated test runs much faster.
To force a fresh installation of dependencies:
make install-dev
Running Tests
After setting up the development environment:
make test
Or directly with pytest:
.venv/bin/pytest
Code Quality & Pre-commit Hooks
The project uses prek to simplify pre-commit hook setup.
After installing development dependencies, set up pre-commit hooks:
prek install
This automatically installs git hooks that will:
Run ruff linter with auto-fix
Run ruff format for code formatting
Run mypy for type checking
You can also run quality checks manually:
make lint # Check code quality make lint-fix # Auto-fix linting issues make format # Format code make typecheck # Run mypy type checking
The pre-commit hooks ensure code quality before commits, catching issues early and maintaining consistent code standards across all contributions.
Copyright 2013 (c) by Stephane Wirtel
dsmtpd Changelog
Here you can see the full list of changes between each dsmtpd release.
Version 1.2.0
Released on January 7th 2026.
Features:
Document SMTPUTF8 support (RFC 6531) - enabled by default via aiosmtpd (#32)
SMTPUTF8 allows UTF-8 email addresses, headers, and message content
Add --disable-smtputf8 CLI option to disable SMTPUTF8 extension for legacy client compatibility (#34)
Development improvements:
Add test coverage reporting with pytest-cov (#29)
Add code quality tools: ruff (linting/formatting) and mypy (type checking) (#29)
Add pre-commit hooks with prek for automated code quality checks (#31)
New make targets: lint, lint-fix, format, typecheck (#29)
Enhanced Makefile with automatic virtual environment management
Add smart dependency tracking to avoid unnecessary reinstallations during development
New make targets: install-dev, clean, clean-build, clean-venv
Makefile now uses Python from asdf/mise for consistent development environments
Significantly faster repeated test runs with timestamp-based dependency tracking
Add comprehensive tests for the debugging SMTP server (#8)
New integration tests for email reception, storage, and multipart email handling
Add tests for --version flag and --max-size option (#29)
Add test for SMTPUTF8 support verification (#32)
Add support for Python 3.14 (#25)
Replace deprecated license classifiers with SPDX license expression (#24)
GitHub Actions workflow now includes linting and type checking jobs (#29)
Version 1.1
Released on September 13th 2025.
Lower Python version requirement from 3.12 to 3.10 (#17)
Fix crash when directory exists but is not yet a valid Maildir with proper validation and repair functionality (#18)
Add exit codes documentation to README
Code formatting improvements with ruff
Version 1.0
Release on May 20th 2025.
Migration to aiosmtpd to Support Python >= 3.12 (#11, patch by Sebastian Wagner)
Add minimal tests for maildir check and importability
Add systemd service file (by Sebastian Wagner)
Version 0.3
Release on May 26th 2021.
Maildir capture: added early check (patch by Bernhard E. Reiter)
Remove the support of Docopt
Remove the support of Python 2.x (dead in 2020)
Support Python 3.6+
Improve the classifiers for PyPI
Migrate to PEP 517
Fix License into setup.py
Add tests for the CLI using argparse instead of docopt
Version 0.2
Release on January 21st 2013.
Allow to store the incoming emails in a maildir via the ‘-d’ argument
Version 0.1
Release on January 14th 2013.
Implement a basic server
Show the message in the log
Project details
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 dsmtpd-1.2.0.tar.gz.
File metadata
- Download URL: dsmtpd-1.2.0.tar.gz
- Upload date:
- Size: 13.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56f4a7584a6184104b626192eef8d159cf014c2db67bc4ed3f184971da705afa
|
|
| MD5 |
5338a76154be7a1e16fb8e51fb473554
|
|
| BLAKE2b-256 |
1a1fe08b5b99c673bb2a4d82bda7e403f6e7d2a17203c7ba288f1ff07e0697b6
|
Provenance
The following attestation bundles were made for dsmtpd-1.2.0.tar.gz:
Publisher:
publish.yml on matrixise/dsmtpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dsmtpd-1.2.0.tar.gz -
Subject digest:
56f4a7584a6184104b626192eef8d159cf014c2db67bc4ed3f184971da705afa - Sigstore transparency entry: 802246457
- Sigstore integration time:
-
Permalink:
matrixise/dsmtpd@6b037189a795aa980fca4631f448c5539fae2992 -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/matrixise
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6b037189a795aa980fca4631f448c5539fae2992 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dsmtpd-1.2.0-py3-none-any.whl.
File metadata
- Download URL: dsmtpd-1.2.0-py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6838520ac1480fb1324f71c8a68b3d544dfcd3332b15e1c5417944634e080f5e
|
|
| MD5 |
440ef2b605a365c4b8c808567a2553a7
|
|
| BLAKE2b-256 |
cad841f9f47f9eb968d10775e2c615576c63349860986717445640b5d1c2e448
|
Provenance
The following attestation bundles were made for dsmtpd-1.2.0-py3-none-any.whl:
Publisher:
publish.yml on matrixise/dsmtpd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dsmtpd-1.2.0-py3-none-any.whl -
Subject digest:
6838520ac1480fb1324f71c8a68b3d544dfcd3332b15e1c5417944634e080f5e - Sigstore transparency entry: 802246500
- Sigstore integration time:
-
Permalink:
matrixise/dsmtpd@6b037189a795aa980fca4631f448c5539fae2992 -
Branch / Tag:
refs/tags/v1.2.0 - Owner: https://github.com/matrixise
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6b037189a795aa980fca4631f448c5539fae2992 -
Trigger Event:
push
-
Statement type: