
dead-letter
io.github.BigCactusLabs由 GitHub 账号 BigCactusLabs 发布v0.4.10更新于 Oct 30, 2026
Convert .eml and .mbox email to clean Markdown for RAG, LLM pipelines, and local knowledge bases
概览
把 .eml 和 .mbox 邮件导出转换为带 YAML front matter 的整洁 Markdown,便于助手在本地读取和索引邮件。
- 可以做什么
- 把单个 .eml 文件转换为 Markdown 文本,可选写入指定文件
- 把一封邮件转换为包含 Markdown 与提取附件的 bundle 目录,源文件只复制不移动
- 批量转换整个目录中的 .eml 文件,每次调用上限 50 个文件
- 转换单个扁平 .mbox 导出,每次调用上限 256 MiB 和 1000 封邮件
- 查看某封邮件的质量与结构诊断信息,不产生永久写入
- 所有工具都支持 preset(default、clean、verbose、raw)及逐项参数覆盖
- 适用场景
- 当你已把邮件导出为 .eml 或 .mbox,并希望转成可读的 Markdown 用于 RAG、LLM 流水线、本地知识库或可移植归档,而不想把原始 MIME 和 base64 塞进上下文窗口时使用。
- 运行要求
- 作为本地 stdio 进程在用户机器上运行;桌面客户端需在 PATH 中有 uv/uvx,或安装 PyPI 包、Claude Desktop 的 .mcpb 扩展包或容器镜像。首次使用可能下载 Python 和依赖。无需账号、API 密钥或环境变量。
安装
在 SourceWeft 中
- 打开 控制台中的 dead-letter,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
dead-letter
[PyPI package] [Python versions] [License: PolyForm Noncommercial]
Turn .eml email exports into clean, local, LLM-ready Markdown.
dead-letter converts .eml email exports into clean Markdown with YAML front matter — threads split, signatures stripped, attachments extracted, calendars parsed. One file or ten thousand.
Use it to build a readable email archive, move messages into Markdown-based knowledge systems, or prepare email for RAG and LLM pipelines without feeding raw MIME and base64 into your context window. No account, upload, or API key required.
⚡ Try it
If you already have uv, run dead-letter without installing it globally:
Or install with Homebrew or pip below. Agents and MCP clients can use the client-specific setup in llms-install.md.
🎯 Common use cases
- Email → Markdown archives — turn exported
.emlcollections into readable, portable Markdown with structured metadata - RAG and LLM ingestion — normalize message text, thread structure, links, and attachment metadata before chunking or indexing
- Agent workflows — expose conversion and diagnostics directly to Claude, Codex, and other MCP clients
- Knowledge bases — move email into Markdown-first systems such as Obsidian, static archives, or local search pipelines
- Digital preservation — retain human-readable content and useful message structure without depending on one mail client
✨ Features
- Full-fidelity conversion — HTML sanitization, Gmail/Outlook thread segmentation, inline image handling, and calendar event summaries
- CLI — point it at a file or a directory and go
- Local web UI — dark command-center interface with drag-and-drop import, watch mode, conversion grade badges, processing history, and per-job diagnostics
- Inbox/Cabinet workflow — drop
.emlfiles into an Inbox, let dead-letter organize the Markdown bundles into a Cabinet - Install validation —
dead-letter doctorchecks your runtime environment - Conversion report — opt-in JSON report with per-file diagnostics, including attachment referenced/retained counts for automation and audit
- MCP server — integrate with Claude Desktop, Claude Code, Codex, and other MCP clients
- Claude plugin — marketplace install in Claude Code or Cowork with five slash commands (
/dead-letter:convert,/dead-letter:summarize,/dead-letter:triage,/dead-letter:cabinet,/dead-letter:mbox) - Portable Agent Skill — teaches skill-aware agents when and how to convert
.emlfiles - Python API —
from dead_letter import convertand you're off
🧠 Built for LLM Pipelines
Raw .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.
To separate the filesystem artifacts 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 clients call dead-letter's conversion tools without shelling out. Conversion is local; your chosen MCP host may still send returned email text to a remote model.
📊 Token-cost benchmarks
dead-letter's value isn't fewer tokens than every alternative — it's fidelity per token: keeping useful email structure without carrying raw MIME into context. Measured across an 11-message synthetic corpus of HTML threads, attachments, and newsletters (tokenizer o200k_base, structured thread mode):
- ~88% fewer tokens than the raw
.emlin the reported aggregate comparison — the attachment category's median is ~126k tokens raw vs ~180 converted. - Structure survives — thread structure, per-message sender attribution, links, and attachment metadata remain readable. The tested naive baselines are often cheaper because they discard information (0/2 attachment names retained vs dead-letter's 2/2).
Those counts measure the Markdown representation, not the contents of retained binary attachments or downstream answer quality. The shipping default is latest-message mode; the benchmark uses structured mode for a same-thread comparison.
The benchmark is honest about where it loses: naive extraction is fewer tokens when you don't mind throwing away metadata, links, and thread structure. Full method, the complete table (including those rows), tokenizer disclosure, and a one-command reproduce are in benchmarks/.
📦 Install
Pick one route. The distribution map explains how the channels fit together; installing all of them is not necessary.
With Homebrew on Apple silicon macOS:
The Homebrew formula installs the CLI (dead-letter convert, dead-letter doctor).
Formulas for 0.4.7 and later also install the dead-letter-mcp server; the
optional web UI is not included.
With pip:
Use pipx for an isolated UI or MCP install:
Or run individual entrypoints without a global package install using uvx:
uv caches tools/dependencies and may download Python on first use. These unpinned trial commands do not promise a fresh latest version on every run; see version pinning for a reviewed deployment.
From source:
Agent Skill (any host)
Install the portable Agent Skill into whichever agent you use:
Needs gh 2.90 or newer. The skill is independent of the Claude plugin. Pin a
reviewed skill tag/commit for reproducibility; the default latest release can
also be a plugin release. For exact pin syntax, other hosts, manual installation,
and discovery metadata, see Agent Discovery.
🚀 Quick Start
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 those folders before importing or starting jobs. Skipping dismisses the prompt but leaves those actions gated until setup is completed. 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; browser batches also have aggregate-size and file-count limits.
From a source checkout, prefix with uv run:
🐍 Python API
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:
🔌 MCP Server
dead-letter ships an MCP server so LLM clients can convert .eml files directly without shelling out.
VS Code, Cursor, and Cline:
Install in VS Code · Install in Cursor
Requires uv/uvx on the desktop client's PATH. These links configure a local
stdio server using the published PyPI package; no catalog admission is needed.
First use may download Python and dependencies. Review the command, scope, and
tool permissions before accepting. Cline setup, manual JSON examples, and
verification: Client installation.
Launch it directly with uvx:
Or install it first (from 0.4.7 the MCP SDK is a core dependency; [mcp] is
kept as a compatibility extra):
From a source checkout:
Claude Desktop (extension bundle):
Download the .mcpb file and its .sha256 sidecar from a published package release (vX.Y.Z) on the releases page. Plugin-only releases do not contain this bundle. Verify the bytes before installation:
Replace X.Y.Z with the selected package version. In a compatible Claude Desktop build, double-click the downloaded bundle, drag it onto the window, or use Settings > Extensions > Advanced settings > Install Extension. Check that the extension connects and exposes the tools below (five from 0.4.5; convert_mbox is absent in 0.4.0 and earlier), then convert a synthetic message.
The bundle uses a managed uv runtime and an exact package pin. First launch may download Python and dependencies. A checksum or command-line smoke test is not proof of a successful GUI installation on your client version. For hosts without MCPB support, use manual stdio setup below.
Claude Desktop (manual claude_desktop_config.json — alternative):
Merge the entry rather than replacing existing client settings. VS Code and other hosts can use different schemas; see the agent install guide.
Claude Code or Cowork (recommended — Claude plugin):
On Claude Code 2.1.275 or later, /plugin install dead-letter --marketplace BigCactusLabs/bigcactuslabs-plugins does both in one step.
The plugin adds five slash commands: /dead-letter:convert, /dead-letter:summarize, /dead-letter:triage, /dead-letter:cabinet, /dead-letter:mbox. Local Claude Code needs uv on PATH; see plugin/ for runtime-specific setup and updates. Email content is treated as untrusted data, not instructions: embedded requests for tool use, credentials, or exfiltration are not followed.
The marketplace pins the plugin tag and commit, and the plugin pins an exact published Python package in its uv project and lock. Plugin releases after 0.4.13 launch with uv run --frozen --isolated from the shipped uv.lock, which fixes dependency versions and checks their hashes. Plugin 0.4.13 and earlier use uvx, which resolves compatible transitive versions itself. Claude Code and Cowork keep separate installed copies; update and verify each client.
Claude Code (manual MCP add — alternative):
Codex:
mcp list confirms registration, not a successful tool call. Connect through the target client, confirm the tools below, and convert a synthetic fixture before treating the installation as verified.
Troubleshooting
Why does uv's cache keep growing? uvx and uv cached environments are not
removed automatically. Close MCP clients, then run uv cache prune to remove
unused cached data. See uv cache management.
Tools
All five take a preset (default, clean, verbose, raw) and per-flag overrides. Full contract, including the MCP-only constraints and the error-text table: docs/reference/v4-runtime-contracts.md.
🗂 Project Structure
The agent guide maps bundle, container, skill, and maintainer tooling without turning this README into a file inventory.
🧪 Testing
CI also validates plugin/skill schemas, frontend syntax, maintained Markdown links, and cross-platform packaging. Full commands and the distinction between offline contracts and real client tests are in Contributing.
📚 Docs
- Docs Index — choose by task, not by filename
- Distribution map — CLI, UI, MCPB, plugin, container, and skill choices
- Agent install guide — client-specific setup and verification
- Runtime Contracts — full API and core behavior spec
- Frontend State Model
- Quality Diagnostics
- Publishing — tagging, channel order, and recovery
- Brand & Style Guide
- Changelog
- Contributing
- Agent Guide — operational guide for AI coding agents working in this repo
🔧 Tools We Love
- MarkEdit — TextEdit for Markdown, native macOS, ~4 MB. Opens dead-letter output like it was always meant to live there.
- mo — local Markdown viewer that renders files in the browser with live reload. Point it at your Cabinet and read converted mail like a feed.
⚠️ Known Limitations
- CLI/Python accept
.eml, flat.mboxexports, and (from 0.4.5) ZIP/TGZ Takeout downloads; see the Takeout guide. The web UI imports.emlfiles and, from 0.4.10, one flat.mboxby local path. Unreleased source adds.zip,.tgzand.tar.gzinput by path or browser upload, with a 1 GiB staging/output free-space reserve, and resumes stopped web imports in their job folder. Its watch and file-import flows stay EML-only. From 0.4.5 the MCP server adds a boundedconvert_mboxtool for one flat.mbox. PST, MSG and live-mailbox connections are unsupported. An opt-in resumable MBOX import (--mbox-resume, CLI/Python) is available from 0.4.6; see the resume contract. - Local-only, single-user, single-machine; no remote server or authentication service. An MCP host may send results to its model provider.
- In-memory job registry: state resets on restart. Unreleased source keeps a stopped archive import resumable across restarts. Retained binary attachments need a separate parser for text indexing.
License
PolyForm Noncommercial 1.0.0 — free for personal, educational, and nonprofit use. Commercial use requires a separate license from Big Cactus Labs.
来源:README.md,提交 4ff528a
工具
0版本历史
9- v0.4.10最新Oct 29, 2026
- v0.4.9Oct 22, 2026
- v0.4.8Oct 9, 2026
- v0.4.7Oct 9, 2026
- v0.4.6Oct 6, 2026
- v0.4.5Sep 29, 2026
- v0.4.0Sep 20, 2026
- v0.3.1Sep 19, 2026
- v0.2.5Sep 16, 2026
评分
已满足适用检查项的 40%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分
请在仓库或注册中心条目中声明许可证。