Skip to main content

Email as plain text files with YAML frontmatter

Project description

mdmailbox

Email as plain text files with YAML headers.

What is this?

mdmail treats email as simple text files:

---
from: me@example.com
to: alice@example.com
subject: Quick question
---

Hey Alice,

Are we still on for tomorrow?

Best,
Me

Save this as ~/Mdmailbox/drafts/meeting.md, run mdmailbox send ~/Mdmailbox/drafts/meeting.md, and it's sent.

Why?

  • Plain text - Edit emails in your favorite editor
  • Git-friendly - Track your email history with version control
  • Scriptable - Automate email with simple shell scripts or Python
  • LLM-friendly - Easy for AI tools to read, search, and compose emails
  • No lock-in - It's just files. Move them, grep them, back them up

Installation

pip install mdmailbox

Or with uv:

uv tool install mdmailbox

Quick Start

1. Configure credentials

Create ~/.authinfo with your SMTP credentials:

machine smtp.gmail.com login you@gmail.com password your-app-password
machine smtp.migadu.com login you@migadu.com password your-password

2. Create a draft

mdmailbox new --to friend@example.com --subject "Hello" --from you@gmail.com

This creates ~/Mdmailbox/drafts/hello.md.

3. Edit and send

Edit the draft in your favorite editor, then:

mdmailbox send ~/Mdmailbox/drafts/hello.md

The email is sent and moved to ~/Mdmailbox/sent/.

Commands

Command Description
mdmailbox send <file> Send an email
mdmailbox send --dry-run <file> Validate without sending
mdmailbox import Import emails from Maildir
mdmailbox new Create a new email draft
mdmailbox credentials Show configured SMTP credentials

Send

# Send an email
mdmailbox send ~/Mdmailbox/drafts/hello.md

# Dry run (validate without sending)
mdmailbox send --dry-run ~/Mdmailbox/drafts/hello.md

# Use custom authinfo file
mdmailbox send --authinfo ~/secrets/.authinfo ~/Mdmailbox/drafts/hello.md

Import from Maildir

If you use mbsync or similar tools to sync email locally:

# Import all emails from ~/mail (default)
mdmailbox import

# Import from custom location
mdmailbox import --maildir ~/Maildir

# Import to custom output directory
mdmailbox import -o ~/Mdmailbox/inbox

# Limit number of emails
mdmailbox import -n 100

New Draft

# Create empty draft
mdmailbox new

# Create with fields pre-filled
mdmailbox new --to alice@example.com --subject "Meeting" --from me@gmail.com

# Specify output path
mdmailbox new -o ~/Mdmailbox/drafts/custom-name.md

Credentials

# List all configured credentials
mdmailbox credentials

# Look up credentials for specific email
mdmailbox credentials --email you@gmail.com

File Format

Every email is a text file with YAML frontmatter:

---
from: sender@example.com
to: recipient@example.com
subject: Subject line
cc: optional@example.com
date: 2025-12-08T15:30:00+01:00
message-id: <abc123@mail.example.com>
---

Body content goes here.

Multiple recipients

---
to:
  - alice@example.com
  - bob@example.com
cc: team@example.com
---

Directory Structure

~/Mdmailbox/
├── inbox/              # imported emails
├── drafts/             # work in progress
└── sent/               # successfully sent

Configuration

Credentials via .authinfo

mdmail uses the standard .authinfo format:

# ~/.authinfo
machine smtp.gmail.com login you@gmail.com password your-app-password
machine smtp.migadu.com login you@migadu.com password your-password

# Wildcard domain support (for aliases)
machine smtp.migadu.com login *@yourdomain.com password shared-password

When sending, mdmail looks up credentials by matching the from: address.

Features:

  • Exact match
  • Gmail normalization (dots and +suffix ignored for gmail.com)
  • Wildcard domain matching (*@domain.com)

Set a custom path via environment variable:

export AUTHINFO_FILE=~/secrets/.authinfo

Python API

from mdmailbox import Email
from mdmailbox.smtp import send_email
from pathlib import Path

# Read an email
email = Email.from_file(Path("inbox/message.md"))
print(email.subject)
print(email.body)

# Create and save
email = Email(
    from_addr="me@example.com",
    to=["you@example.com"],
    subject="Hello",
    body="Hi there!"
)
email.save(Path("drafts/hello.md"))

# Send
result = send_email(email)
if result.success:
    print(f"Sent! Message-ID: {result.message_id}")

Development

# Run tests
make test

# Install locally
make local-install

Future Ideas

See docs/adr/001-design.md for the full design document including planned features like IMAP fetch, attachments, and more.

License

MIT

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

mdmailbox-0.1.6.tar.gz (35.6 kB view details)

Uploaded Source

Built Distribution

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

mdmailbox-0.1.6-py3-none-any.whl (12.8 kB view details)

Uploaded Python 3

File details

Details for the file mdmailbox-0.1.6.tar.gz.

File metadata

  • Download URL: mdmailbox-0.1.6.tar.gz
  • Upload date:
  • Size: 35.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"24.11","id":"vicuna","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mdmailbox-0.1.6.tar.gz
Algorithm Hash digest
SHA256 a3540db21261802fc7c651859154f8caa5f6f51fbf4b62734a5a19cf956d7661
MD5 390a66cf4d4a7e4f9048f976f1b4e82b
BLAKE2b-256 ce844eb8ff435fd976898bdb68fb22e05e9f0a4affd0bd91ddff846177adb0fb

See more details on using hashes here.

File details

Details for the file mdmailbox-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: mdmailbox-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 12.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.15 {"installer":{"name":"uv","version":"0.9.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"24.11","id":"vicuna","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mdmailbox-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 db5b257ae4a1098875e8e3e2450e7cedd6f9a9e81e5d81ea7bbb8e37b11af40e
MD5 f0d059c8c357936609dd51452bd48f91
BLAKE2b-256 49b171282b541f2f5cfef5558a5bd38ee8488c3a102ae4716399bc87b84d94cb

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