Convert .eml exports into structured Markdown with metadata, separated threads, extracted attachments, and parsed calendar events.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent โ or use 1-click editor setup below.
We ran the install command below but it didn't respond within our test window โ this can mean a slow first-time install rather than a real problem.
npx -y --yesNo response to initialize.
This is an experimental automated check and can have false negatives โ missing environment variables, a slow cold install, etc. It doesnโt necessarily mean somethingโs wrong. Last checked 4d ago.
๐ก Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Dead Letter.
convert_emlMarkdown text. Also writes a file when `output_path` is given.
convert_eml_to_bundleJSON with `bundle_path`, `markdown_path`, `attachment_paths`. Copy-only: the original `.eml` is never moved or deleted.
convert_directoryJSON summary. Capped at 50 `.eml` files per call.
get_diagnosticsQuality and structure JSON. Writes nothing permanent.
Your .eml files deserve a second life.
dead-letter converts email exports into clean Markdown with YAML front matter โ threads split, signatures stripped, attachments extracted, calendars parsed. One file or ten thousand.
.eml files into an Inbox, let dead-letter organize the Markdown bundles into a Cabinetdead-letter doctor checks your runtime environment/dead-letter:convert, /dead-letter:summarize, /dead-letter:triage, /dead-letter:cabinet)from dead_letter import convert and you're offRaw .eml files are noisy input for downstream LLM and retrieval pipelines โ MIME headers, multipart boundaries, duplicated HTML/plain bodies, and encoded attachments all get mixed into the text path.
dead-letter normalizes that into Markdown with YAML front matter, so message text and metadata are ready for chunking or indexing without MIME parsing or base64 cleanup. Default convert() and convert_dir() runs write a single .md per message and keep attachment names in front matter.
If you want the filesystem artifacts separated too, bundle and Cabinet workflows write message.md plus retained decoded files under attachments/. The Markdown is ready for text ingestion, while PDFs, spreadsheets, calendar files, and other retained binary attachments stay cleanly split out for whatever downstream parser you already use.
For direct LLM integration, the MCP server lets Claude Desktop, Claude Code, Codex, and other MCP clients call dead-letter's conversion tools without shelling out.
dead-letter's value isn't fewer tokens than every alternative โ it's fidelity per token: the cheapest representation that keeps the email intact. Measured across a synthetic corpus of HTML threads, attachments, and newsletters (tokenizer o200k_base, medians):
.eml โ a single email with a PDF attachment is ~126k tokens raw vs ~180 converted.The benchmark is honest about where it loses: naive extraction is fewer tokens when you don't mind throwing away attachments, links, and thread structure. Full method, the complete table (including those rows), tokenizer disclosure, and a one-command reproduce are in benchmarks/.
With Homebrew on Apple silicon macOS:
The Homebrew formula installs the core CLI only: dead-letter convert and
dead-letter doctor. It intentionally does not bundle the optional web UI or
MCP server dependency stacks.
With pip:
Use pipx for isolated UI or MCP installs:
From source:
CLI โ convert a single file:
Convert a whole directory:
Generate a JSON conversion report alongside the output:
With --output, the report is written to that output directory as
.dead-letter-report.json. Without --output, file conversions write the
report next to the source message and directory conversions write it to the
input directory root.
Check your runtime environment:
Directory conversion scans recursively for .eml files, matches the suffix
case-insensitively, skips symlinked files whose resolved targets escape the
requested input tree, and deduplicates in-tree symlink aliases that resolve to
the same message file.
Web UI โ start the local server:
Open http://127.0.0.1:8765 โ on first launch, a setup prompt suggests default Inbox and Cabinet folders. Configure or skip to start converting. Import .eml files with drag and drop or the file picker. Single-file imports use file mode, while multi-file drops create one directory-mode batch job. Mixed drops ask for confirmation before skipping non-.eml files.
The backend enforces a 100 MB per-file import limit for both single and batch
uploads.
From a source checkout, prefix with uv run:
With options:
Strip signature images (logos, social icons) and tracking pixels:
When enabled, these filters remove matched images from rendered Markdown and omit stripped inline signature/tracking assets from bundle attachment output.
Bundle conversion (Markdown + attachments + source in one directory):
source_handling="copy" preserves the original .eml in place. If omitted,
convert_to_bundle() defaults to source_handling="move" and moves the source
message into the bundle.
Retained extracted attachment filenames are normalized to safe basenames before
they are written under attachments/.
Quality diagnostics include referenced/retained attachment counts when a message has attachments eligible for retention, so dropped artifacts are machine-detectable. See Quality Diagnostics.
Batch:
dead-letter ships an MCP server so LLM clients can convert .eml files directly without shelling out.
Install and launch:
From a source checkout:
Claude Desktop โ add to claude_desktop_config.json:
Claude Code or Cowork (recommended โ Claude plugin):
The plugin bundles the MCP server (via uvx, no pip install needed โ just uv on PATH) and adds four slash commands: /dead-letter:convert, /dead-letter:summarize, /dead-letter:triage, /dead-letter:cabinet. Email content handled through the plugin is treated as untrusted data, not instructions, so tool-use, credential, and exfiltration requests embedded in messages are not followed. Source under plugin/.
The marketplace pins each published plugin tag and commit. Release automation updates that pointer only after the bundled MCP server's exact PyPI version is live, so Claude Code and Cowork resolve the same reproducible release.
Claude Code (manual MCP add โ alternative):
Codex:
Factual signals from GitHub, npm, and our automated checks โ not a rating.
No reviews yet โ be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/bigcactuslabs-dead-letter)<a href="https://allmcps.com/mcp/bigcactuslabs-dead-letter"><img src="https://allmcps.com/api/badge/bigcactuslabs-dead-letter?style=directory" alt="Dead Letter on AllMCPs" /></a>