Skip to main content

SMTP でメールを受け取り Maildir / JSON に保存するだけの開発用メール受信ツール

Project description

maildirsink

A tiny tool that receives mail over SMTP and just saves it to a file. Like a development mail sink such as mailpit, but with no UI and no forwarding — it sticks to one job: receive and store.

日本語版は README-ja.md を参照してください。

Why

In the find-job project, notification mail was written directly into a Maildir by a shell script. maildirsink extracts just that "store mail locally" part into a general-purpose tool.

It commits to standard Maildir as the storage target, so it slots straight into Maildir-native MUAs (mutt / neomutt) and existing Maildir tooling (procmail, mbsync, and friends).

What it does

  1. On startup, listens as an SMTP server on the given port.
  2. On receiving a message, stores it in the given directory in the given format.
  3. Nothing else — no forwarding, no web UI.

Storage formats

  • maildir — standard Maildir. Incoming mail is written to tmp/ and then moved into new/ (the unread-mail spool). Filenames follow the standard uniqueness-guaranteeing scheme (time.Ppid.hostname). mutt / neomutt scan new/ directly, so no extra setup is needed.

  • json — one JSON file per message:

    {
      "subject": "...",
      "from": "...",
      "to": "...",
      "date": "...",
      "message_id": "...",
      "body": "..."
    }
    

Note: Direct delivery to Thunderbird is intentionally out of scope. Thunderbird keeps a .msf summary cache and won't notice mail written into a Maildir from outside until you "Repair Folder". Maildir-native MUAs like mutt don't have this problem and pick up mail dropped into new/ immediately.

Install

pip install .
# or, for development:
pip install -e ".[dev]"

Usage

maildirsink [--port PORT] [--host HOST] [--format maildir|json] [--dir DIR]
Option Meaning Default
--port SMTP listen port 1025
--host Listen host localhost
--format Storage format (maildir / json) maildir
--dir Storage directory ./mail

Exposing on a LAN

The default localhost only accepts mail sent from the same host. To receive from another host (a container, a find-job instance on the LAN, etc.), listen on all interfaces:

maildirsink --host 0.0.0.0 --port 1025

Warning: There is no authentication and no TLS. Use it only within a trusted LAN. Do not expose it directly to the internet.

Reading mail (mutt / neomutt)

Just point your MUA at the Maildir that maildirsink writes to. Because there is no index cache like .msf, no repair step is ever needed.

set mbox_type = Maildir
set folder    = "/path/to/maildir"
set spoolfile = "+."
mailboxes     = "/path/to/maildir"

# Pick up mail that arrives while mutt is running
set mail_check = 5      # seconds
set timeout    = 10

Once mail lands in new/, mutt reflects it automatically.

Implementation notes

  • Written in Python.
    • SMTP server: aiosmtpd (the stdlib smtpd was removed in Python 3.12).
    • Maildir writing: the stdlib mailbox.Maildir. Maildir.add() handles the tmp/new/ sequence and filename uniqueness for you (reference/maildir-delivery.sh is a hand-written example of the same).
  • Character sets: MIME-encoded headers (=?UTF-8?B?...?=) are decoded.

Tests

pytest

License

MIT — see LICENSE.

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

maildirsink-0.1.0.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

maildirsink-0.1.0-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file maildirsink-0.1.0.tar.gz.

File metadata

  • Download URL: maildirsink-0.1.0.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for maildirsink-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0f827eac2fc29a6a4043e2e0b94f5ab2e4b5667bf4ae3974f8ba5eee7093a057
MD5 299ac1c67d0cf56f695ef0a2c72cc38b
BLAKE2b-256 542ae68bb2298833ee8d28c14e17e0415c272bf120fea4ae624b4a6827b8512b

See more details on using hashes here.

File details

Details for the file maildirsink-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: maildirsink-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for maildirsink-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5cec864e49398ea50908e4b6247857189247d33b42af11c6463d88095f1f3ddf
MD5 ffa1cb0bcb7aa1e42a033a421f42772a
BLAKE2b-256 05b8acff2218afd6cfb59b74bb7e6578d828d7cf7db8baa72e4f4b31c2c3c65f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page