Disclaimer
Is this project open source? Yes (MIT)
Is this project completely free? Yes
Does this project use AI beyond the author’s ability to comprehend how it works? No. It contains no model and makes no network calls.
I keep a fair amount of correspondence in my vault: job applications, client threads, anything with a decision in it. Getting a mail in there used to be copy, paste, and retype the metadata by hand.
So I wrote a small command line tool for it. One .eml in, one .md out:
mail2md Mail.eml
---
created: 2026-06-15T09:41
from: "Jane Doe <[email protected]>"
to: "Anton Fillmann <[email protected]>"
via:
subject: "Project inquiry"
attachments:
---
Hallo Anton,
...
The point of the frontmatter is that the note becomes queryable. You can sort by created, filter by from, or list every mail that carried an attachment. Most converters I found write that same information into the prose instead, as a heading plus a bullet list, which reads fine and answers no questions.
A few details that took the longest to get right:
createdis rendered in your local time, not the sender’s timezone, so it sorts correctly next to the rest of your notes.- Quoted reply chains stay in one file. Earlier versions split a thread into one note per message, and I removed that again: interleaved replies have no clean boundary, quote separators are client- and language-specific, and no RFC defines them. A converter that guesses there produces confident garbage. Splitting is a judgment call, so it belongs to whoever knows the context.
- Nothing is overwritten silently. An existing target with identical content is skipped, one that differs aborts unless you pass
--force. - Attachments are listed in the frontmatter and can be extracted with
--extract-attachments. Inline images are deliberately not treated as attachments, since a named inline image is a signature logo or a tracking pixel far more often than a file someone meant to send.
How it compares. Postbox ( GitHub - istefox/Postbox: Obsidian plugin to import and manage .eml email files in your vault · GitHub ) is the closest thing I know of, and parts of it are better than mine: it renders inline cid: images, keeps HTML tables, reads .msg, and de-duplicates by Message-ID. It is a plugin, so it is desktop-only and Obsidian has to be running. mail2md is the better fit when the conversion should happen without Obsidian in the loop, in a shell pipeline, a cron job, or a Makefile. Several EML viewer plugins exist too, but they render the mail rather than convert it, and the file stays an .eml.
Install (macOS 13+):
brew install antonfill/tap/mail2md
The formula builds from source against Swift 6.0, so Xcode 16 or newer has to be installed. There is no prebuilt binary yet, and that is the honest catch: if there is no Xcode on your Mac at all, this is a large download for a small tool.
MIT licensed, source at GitHub - AntonFill/mail2md: Convert .eml files to Markdown with YAML frontmatter. A local-first CLI for macOS. · GitHub . JSON output and stdin/stdout piping are on the roadmap.
There is a companion tool in the same family, realdate ( GitHub - AntonFill/RealDate: A CLI tool that extracts dates from filenames, sets macOS file timestamps, and cleans up filenames for better file system sorting. · GitHub ), which takes the date out of a filename like 2026.06.07 Invoice.pdf and writes it into the file’s timestamps. Both are local-first: no account, no cloud, no network access.
I would like to know how other people handle this. What do you do today with mail you want to keep in your vault, and which part of it annoys you enough that you have thought about it more than once?