Skip to main content

nMdmail: Send emails written in Markdown

Fork of https://github.com/yejianye/mdmail, which looks dead.

PyPI version Tests pre-commit.ci status codecov Code style: black Ruff

nMdmail sends emails written in Markdown. It could be used as a standalone command-line script or as a python module. The features includes

  • Have a sane default CSS style and support CSS customization
  • Support local images as inline images

Screenshot of an email sent via nmdmail viewed in Google Inbox

To install nmdmail

$ python -m pip install nmdmail

Send Email in Command-line

When sending emails from command-line, the body of the email could be read from a file or stdin.

Email headers such as subject, from/to, cc etc could be specified at the beginning of the markdown file, Or be specified in command-line arguments.

Here is an example of Markdown file with email headers

Subject: Sample Email
From: foo@xyz.com
To: bar@xyz.com
Cc: baz@xyz.com

# Sample Email

-

![Embed local image](../assets/image.jpg)

To send this email with nmdmail

$ nmdmail sample_email.md

Here is an example of specifying subject, from/to in command-line

$ nmdmail --from=foo@xyz.com --to=bar@xyz.com --subject='Sample' sample_email.md

To read email content from stdin,

$ echo '# Sample Email' | nmdmail --from=foo@xyz.com --to=bar@xyz.com --subject='Sample'

SMTP server configurations are read from the following environment variables

export MDMAIL_HOST="" # default: localhost
export MDMAIL_PORT="" # default: 25
export MDMAIL_USE_TLS="" # default: false
export MDMAIL_USE_SSL="" # default: false
export MDMAIL_USERNAME="" # default: None
export MDMAIL_PASSWORD="" # default: None
export MDMAIL_DEFAULT_SENDER="" # default: None

Full help of nmdmail command-line script

usage: nmdmail [-h] [--subject SUBJECT] [--from FROM_] [--to TO] [--cc CC]
               [--bcc BCC] [--reply-to REPLY_TO] [--css CSS] [--print-only]
               [file]

Send email written in Markdown.

positional arguments:
  file                  Markdown file for email content. Default to STDIN.

optional arguments:
  -h, --help            show this help message and exit
  --subject SUBJECT, -s SUBJECT
                        Subject line
  --from FROM, -f FROM
                        From address
  --to TO, -t TO        To addresses, separated by comma
  --cc CC, -c CC        CC address, separated by comma
  --bcc BCC, -b BCC     Bcc address, separated by comma
  --reply-to REPLY_TO, -r REPLY_TO
                        Reply-to address
  --css CSS             Use a custom CSS file
  --print-only, -p      Only print out rendered html

Send Email in Python Code

Sending emails in python is straight-forward.

import nmdmail

email="""
# Sample Email

- Python is awesome
- Markdown is cool

![Embed local image](../assets/image.jpg)
"""

nmdmail.send(email, subject='Sample Email',
            from_email='foo@example.com', to_email='bar@example.com')

By default, it will use SMTP server on localhost. You could specify a SMTP server as well.

# Specify SMTP server
smtp = {
  'host: 'my-mailserver.com',
  'port': 25,
  'tls': False,
  'ssl': False,
  'user: '',
  'password': '',
}

nmdmail.send(content,
             subject='Sample Email',
             from_email='foo@example.com',
             to_email='bar@example.com',
             smtp=smtp)

API documentation nmdmail.send

  • email (str/obj): A markdown string or EmailContent object
  • subject (str): subject line
  • from_email (str): sender email address
  • to_email (str/list): recipient email addresses
  • cc (str/list): CC email addresses (string or a list)
  • bcc (str/list): BCC email addresses (string or a list)
  • reply_to (str): Reply-to email address
  • headers (dict): Arbitrary headers
  • smtp (dict): SMTP configuration with following keys
    • host (str): SMTP server host. Default: localhost
    • port (int): SMTP server port. Default: 25
    • tls (bool): Use TLS. Default: False
    • ssl (bool): Use SSL. Default: False
    • user (bool): SMTP login user. Default empty
    • password (bool): SMTP login password. Default empty

Use nmdmail with Vim and Emacs

Since nmdmail can read from stdin and support email headers such as subject/from/to in the markdown file itself, integrating nmdmail with Vim, Emacs or other text editors is easy.

To use nmdmail in Vim, just write a markdown email with headers, and then execute w !nmdmail command, which will send current buffer as stdin to nmdmail.

In Emacs, you could write a small function to do the same thing

(defun nmdmail-send-buffer ()
  (interactive)
  (shell-command-on-region (point-min) (point-max) "nmdmail"))

Then M-x nmdmail-send-buffer will send current buffer to nmdmail.

Metadata

Release files for nmdmail 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nmdmail 0.8.0
File Size Uploaded
nmdmail-0.8.0.tar.gz 6.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nmdmail 0.8.0
File Interpreter ABI Platform
nmdmail-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.8 kB

Release files / nmdmail-0.8.0.tar.gz

Download URL nmdmail-0.8.0.tar.gz
Size 6.1 kB
Tags Source
SHA-256 checksum
How to use checksums
fb18e5aa6f38835bb2dc101062f8b713aa9639e1a76ca909291b1547396e83f7
BLAKE2b-256 checksum
How to use checksums
799e7751a623ac49e644da05eed28f20a52af48bb20dcc41e9de544f4cd166a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 26, 2026.

Transparency log

Release files / nmdmail-0.8.0-py3-none-any.whl

Download URL nmdmail-0.8.0-py3-none-any.whl
Size 7.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
488bc81fabb6eb81997092dd781527784a0c4e95c010a5ea820ca4e6feaa97e5
BLAKE2b-256 checksum
How to use checksums
967e5f40f1a2a8d30a340438136409c601711d375adee603b5969f4dd06fa3ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page