Skip to main content
Glama
BigCactusLabs

dead-letter

dead-letter

PyPI package Python versions License: PolyForm Noncommercial

Ваши файлы .eml заслуживают второй жизни.

dead-letter преобразует экспортированные письма в чистый Markdown с YAML front matter — разбивает цепочки, удаляет подписи, извлекает вложения, разбирает календари. Один файл или десять тысяч.

✨ Возможности

  • Преобразование с полной точностью — очистка HTML, сегментация цепочек Gmail/Outlook, обработка встроенных изображений и сводки событий календаря

  • CLI — укажите файл или каталог — и готово

  • Локальный веб-интерфейс — тёмная командная панель с перетаскиванием файлов, режимом наблюдения, значками оценки преобразования, историей обработки и диагностикой по каждой задаче

  • Рабочий процесс Inbox/Cabinet — поместите файлы .eml в Inbox, и dead-letter организует пакеты Markdown в Cabinet

  • Проверка установки — dead-letter doctor проверяет ваше окружение

  • Отчёт о преобразовании — опциональный JSON-отчёт с диагностикой по каждому файлу, включая счётчики прикреплённых/сохранённых вложений для автоматизации и аудита

  • MCP-сервер — интеграция с Claude Desktop, Claude Code, Codex и другими MCP-клиентами

  • Плагин для Claude — установка одной командой в Claude Code или Cowork с четырьмя слэш-командами (/dead-letter:convert, /dead-letter:summarize, /dead-letter:triage, /dead-letter:cabinet)

  • Python API — from dead_letter import convert — и вперёд

Related MCP server: DingusMail

🧠 Создан для LLM-пайплайнов

Сырые файлы .eml — шумный вход для downstream LLM и retrieval-пайплайнов: MIME-заголовки, границы multipart, дублированные HTML/plain тела и закодированные вложения — всё смешивается в текстовом пути.

dead-letter нормализует это в Markdown с YAML front matter, так что текст сообщения и метаданные готовы к чанкованию или индексации без MIME-парсинга или очистки base64. По умолчанию convert() и convert_dir() записывают один .md на сообщение и сохраняют имена вложений в front matter.

Если вы хотите также разделить артефакты файловой системы, рабочие процессы bundle и Cabinet записывают message.md плюс сохранённые декодированные файлы в attachments/. Markdown готов для текстовой обработки, а PDF, электронные таблицы, файлы календаря и другие сохранённые бинарные вложения остаются чисто отделёнными для любого downstream-парсера, который вы уже используете.

Для прямой интеграции с LLM MCP-сервер позволяет Claude Desktop, Claude Code, Codex и другим MCP-клиентам вызывать инструменты преобразования dead-letter без обращения к оболочке.

📊 Бенчмарки стоимости токенов

Ценность dead-letter не в меньшем количестве токенов, чем у любой альтернативы — это точность на токен: самое дешёвое представление, которое сохраняет письмо целым. Измерено на синтетическом корпусе HTML-цепочек, вложений и рассылок (токенизатор o200k_base, медианы):

  • ~88% меньше токенов, чем сырой .eml — одно письмо с PDF-вложением — это ~126k токенов в сыром виде против ~180 после преобразования.

  • Единственное представление, которое сохраняет письмо целиком — структура цепочки, атрибуция отправителя по каждому сообщению, ссылки и метаданные вложений — всё сохраняется. Наивное извлечение текста дешевле именно потому, что отбрасывает их (0/2 вложений сохранено против 2/2 у dead-letter).

Бенчмарк честно признаёт, где проигрывает: наивное извлечение даёт меньше токенов, если вам не жалко выбрасывать вложения, ссылки и структуру цепочки. Полный метод, полная таблица (включая эти строки), раскрытие токенизатора и воспроизведение одной командой — в benchmarks/.

📦 Установка

С Homebrew на Apple silicon macOS:

brew tap BigCactusLabs/tap
brew install dead-letter

Формула Homebrew устанавливает только основной CLI: dead-letter convert и dead-letter doctor. Она намеренно не включает опциональные зависимости веб-интерфейса или MCP-сервера.

С pip:

pip install dead-letter            # core + CLI
pip install dead-letter[cli]       # + watchfiles (used by backend/UI watch mode)
pip install dead-letter[ui]        # + web UI, API server, and watch mode
pip install dead-letter[mcp]       # + MCP server

Используйте pipx для изолированной установки UI или MCP:

pipx install 'dead-letter[ui]'    # installs dead-letter and dead-letter-ui
pipx install 'dead-letter[mcp]'   # installs dead-letter and dead-letter-mcp

Из исходников:

git clone https://github.com/BigCactusLabs/dead-letter.git
cd dead-letter
uv sync --extra dev     # all extras
uv sync --extra ui      # UI only
uv sync --extra mcp     # MCP only

🚀 Быстрый старт

CLI — преобразование одного файла:

dead-letter convert message.eml

Преобразование всего каталога:

dead-letter convert inbox/ --output out/

Создание JSON-отчёта о преобразовании рядом с выводом:

dead-letter convert inbox/ --output out/ --report

С --output отчёт записывается в указанный выходной каталог как .dead-letter-report.json. Без --output при преобразовании файлов отчёт записывается рядом с исходным сообщением, а при преобразовании каталогов — в корень входного каталога.

Проверка окружения:

dead-letter doctor

Преобразование каталога рекурсивно сканирует файлы .eml, сопоставляет суффикс без учёта регистра, пропускает символические ссылки, чьи разрешённые цели выходят за пределы запрошенного входного дерева, и дедуплицирует псевдонимы символьных ссылок внутри дерева, которые указывают на один и тот же файл сообщения.

Веб-интерфейс — запуск локального сервера:

dead-letter-ui --host 127.0.0.1 --port 8765

Откройте http://127.0.0.1:8765 — при первом запуске появится подсказка с предложением папок Inbox и Cabinet по умолчанию. Настройте или пропустите, чтобы начать преобразование. Импортируйте файлы .eml перетаскиванием или через выбор файлов. Импорт одного файла использует файловый режим, а перетаскивание нескольких файлов создаёт одно пакетное задание в режиме каталога. Смешанные перетаскивания запрашивают подтверждение перед пропуском файлов, не являющихся .eml. Бэкенд ограничивает импорт 100 МБ на файл как для одиночных, так и для пакетных загрузок.

Из исходного кода добавьте префикс uv run:

uv run dead-letter convert message.eml
uv run --extra ui dead-letter-ui --host 127.0.0.1 --port 8765

🐍 Python API

from dead_letter import convert

result = convert("message.eml")
print(result.subject, result.sender)
print(result.output)  # path to the generated .md

С опциями:

from dead_letter import convert, ConvertOptions

result = convert("message.eml", options=ConvertOptions(
    strip_signatures=True,
    strip_quoted_headers=True,
))

Удаление изображений подписей (логотипы, иконки соцсетей) и пикселей отслеживания:

result = convert("message.eml", options=ConvertOptions(
    strip_signature_images=True,
    strip_tracking_pixels=True,
))

При включении эти фильтры удаляют соответствующие изображения из отображаемого Markdown и исключают удалённые встроенные активы подписей/отслеживания из вывода пакета вложений.

Пакетное преобразование (Markdown + вложения + исходник в одном каталоге):

from dead_letter import convert_to_bundle

bundle = convert_to_bundle("message.eml", bundle_root="cabinet/", source_handling="copy")
print(bundle.markdown)     # cabinet/message/message.md
print(bundle.attachments)  # retained extracted files under cabinet/message/attachments/

source_handling="copy" сохраняет исходный .eml на месте. Если опущено, convert_to_bundle() по умолчанию использует source_handling="move" и перемещает исходное сообщение в пакет.

Имена сохранённых извлечённых вложений нормализуются до безопасных базовых имён перед записью в attachments/.

Диагностика качества включает счётчики прикреплённых/сохранённых вложений, когда сообщение имеет вложения, подлежащие сохранению, так что отброшенные артефакты можно обнаружить машинно. См. Диагностика качества.

Пакетная обработка:

from dead_letter import convert_dir

for r in convert_dir("inbox/", output="out/"):
    print(f"{'✓' if r.success else '✗'} {r.source.name}")

🔌 MCP-сервер

dead-letter поставляется с MCP-сервером, чтобы LLM-клиенты могли преобразовывать файлы .eml напрямую, без обращения к оболочке.

Установка и запуск:

pip install dead-letter[mcp]
dead-letter-mcp

Из исходного кода:

uv run --extra mcp dead-letter-mcp

Claude Desktop — добавьте в claude_desktop_config.json:

{
  "mcpServers": {
    "dead-letter": {
      "command": "uv",
      "args": ["--directory", "/path/to/dead-letter", "run", "--extra", "mcp", "dead-letter-mcp"]
    }
  }
}

Claude Code или Cowork (рекомендуется — плагин Claude):

/plugin marketplace add BigCactusLabs/bigcactuslabs-plugins
/plugin install dead-letter

Плагин включает MCP-сервер (через uvx, без pip install — нужен только uv в PATH) и добавляет четыре слэш-команды: /dead-letter:convert, /dead-letter:summarize, /dead-letter:triage, /dead-letter:cabinet. Содержимое писем, обрабатываемое через плагин, считается ненадёжными данными, а не инструкциями, поэтому запросы на использование инструментов, учётные данные и эксфильтрацию, встроенные в сообщения, не выполняются. Исходный код в plugin/.

Маркетплейс закрепляет каждый опубликованный тег и коммит плагина. Автоматизация релизов обновляет этот указатель только после того, как точная версия PyPI встроенного MCP-сервера становится доступной, так что Claude Code и Cowork разрешают один и тот же воспроизводимый релиз.

Claude Code (ручное добавление MCP — альтернатива):

claude mcp add dead-letter -- uv run --extra mcp dead-letter-mcp

Codex:

codex mcp add dead-letter -- uv run --extra mcp dead-letter-mcp
codex mcp list

Команда codex mcp add регистрирует локальный MCP-сервер dead-letter, а codex mcp list проверяет его доступность.

Инструменты

Инструмент

Обязательные аргументы

Возвращает

convert_eml

eml_path

Текст Markdown. Также записывает файл, если указан output_path.

convert_eml_to_bundle

eml_path, bundle_root

JSON с bundle_path, markdown_path, attachment_paths. Только копирование: исходный .eml никогда не перемещается и не удаляется.

convert_directory

directory, output_directory

JSON-сводка. Ограничено 50 файлами .eml за вызов.

get_diagnostics

eml_path

JSON качества и структуры. Ничего постоянного не записывает.

Все четыре принимают preset (default, clean, verbose, raw) и переопределения по флагам. Полный контракт, включая ограничения только для MCP и таблицу текстов ошибок: docs/reference/v4-runtime-contracts.md.

🗂 Структура проекта

src/dead_letter/
├── core/           # conversion pipeline (MIME, HTML, threads, rendering)
├── backend/        # CLI, API server, job runner, watch mode, MCP server
└── frontend/       # static web UI (Alpine.js ES modules + vanilla fetch)
tests/
├── core/           # conversion pipeline tests with .eml fixtures
├── backend/        # API, job, and watch tests
├── plugin/         # Claude plugin manifest, skill, and command tests
└── frontend/       # JS unit tests

🧪 Тестирование

uv run pytest -q tests/core        # conversion pipeline
uv run pytest -q tests/backend     # API and job runner
uv run pytest -q tests/plugin      # Claude plugin manifest, skill, and command surfaces
node --test tests/frontend/*.test.js     # frontend

CI запускает все четыре на PR и на пушах в ветки main или feat/** с теми же командами, плюс npx --yes @anthropic-ai/claude-code@2.1.145 plugin validate plugin/ и node --check src/dead_letter/frontend/static/app.js.

📚 Документация

🔧 Инструменты, которые мы любим

  • MarkEdit — TextEdit для Markdown, нативный macOS, ~4 МБ. Открывает вывод dead-letter так, будто он всегда должен был там жить.

  • mo — локальный просмотрщик Markdown, который рендерит файлы в браузере с живой перезагрузкой. Укажите на ваш Cabinet и читайте преобразованные письма как ленту.

⚠️ Известные ограничения

  • Только локально — нет удалённого сервера, нет аутентификации

  • Реестр заданий в памяти (состояние сбрасывается при перезапуске)

  • Однопользовательский, одна машина

Лицензия

PolyForm Noncommercial 1.0.0 — бесплатно для личного, образовательного и некоммерческого использования. Коммерческое использование требует отдельной лицензии от Big Cactus Labs.

Available Tools

5 tools
convert_directoryConvert email folderA

Batch convert all .eml files in a directory to Markdown.

Recursively finds .eml files (at most 50 per call; larger directories are rejected before any conversion). output_directory is required: Markdown is written there, mirroring subfolders, and source .eml files are left in place. Returns a JSON summary with total, successes, failures, output_paths, and errors. Each errors entry contains file and error_code (defaulting to conversion_error), never raw exception text.

Use convert_eml to retrieve individual converted file content.

NameRequiredDescriptionDefault
presetNodefault
dry_runNo
directoryYes
thread_modeNolatest
thread_orderNooldest-first
include_raw_htmlNo
output_directoryYes
strip_signaturesNo
strip_disclaimersNo
embed_inline_imagesNo
include_all_headersNo
no_calendar_summaryNo
strip_quoted_headersNo
strip_tracking_pixelsNo
strip_signature_imagesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the annotations: the 50-file cap with pre-conversion rejection, that source .eml files are left in place, that subfolders are mirrored into output_directory, and that errors carry a file plus a sanitized error_code rather than raw exception text. That is exactly the operational context an agent needs before spending a large batch run.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action, then constraints, then output contract, then the sibling pointer — each sentence carries distinct information with no filler. Length is proportionate to a 15-parameter batch tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists, and the description still usefully summarizes the JSON summary shape, so return values are covered. However, for a tool with 15 options and an enum-based preset system, the complete absence of guidance on how the conversion options interact (preset vs individual strip_* flags) leaves a real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 15 parameters, so the description carries the full burden — but it only explains output_directory (required, receives Markdown, mirrors subfolders). The 12 conversion flags and 3 enums (preset, thread_mode, thread_order) are entirely undocumented, so an agent cannot tell what 'clean' vs 'verbose' preset or 'structured' thread_mode does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource: 'Batch convert all .eml files in a directory to Markdown,' which immediately separates it from the single-file convert_eml. It does not explicitly contrast with convert_mbox or convert_eml_to_bundle, so sibling differentiation is only partial.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage context (recursive .eml discovery, hard cap of 50 files with upfront rejection) and routes the agent to convert_eml for reading back individual converted content. It stops short of stating when-not to use it, e.g. for mbox archives, which is left to inference from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_emlConvert emailA

Convert a .eml email file to Markdown with YAML front matter.

Returns the full Markdown content (front matter + body). When output_path is provided, also writes the file to disk.

Attachments are listed in the front matter but not written to disk; use convert_eml_to_bundle to save the decoded attachment files.

thread_mode="structured" adds a section per earlier reply or forwarded message. Gmail HTML forwards and unquoted plain-text forwards are kept in latest mode too; a plain-text forward inside ">" quoting is not.

Presets bundle common flag combinations:

  • default: strips signatures, tracking pixels, signature images

  • clean: default + strips disclaimers and quoted headers

  • verbose: includes all headers and raw HTML

  • raw: no stripping, preserves everything

Individual flags override the preset when provided.

NameRequiredDescriptionDefault
presetNodefault
eml_pathYes
output_pathNo
thread_modeNolatest
thread_orderNooldest-first
include_raw_htmlNo
strip_signaturesNo
strip_disclaimersNo
embed_inline_imagesNo
include_all_headersNo
no_calendar_summaryNo
strip_quoted_headersNo
strip_tracking_pixelsNo
strip_signature_imagesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses the file-writing side effect of output_path, that attachments are listed but not written, the per-preset stripping behavior, and that individual flags override presets. The described write behavior is consistent with readOnlyHint=false and destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the primary behavior, then organized into short paragraphs and a bulleted preset list that is genuinely useful given the empty schema descriptions. Slightly verbose on the forward-quoting edge case, but nothing extraneous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the entity, the output shape, the disk side effect, and the preset/flag interaction, and an output schema exists so return-value detail is not owed. The remaining gap is semantics for the unlisted boolean flags in a 14-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the param burden and it partially does: all four preset values and both thread_mode values are given meaning, and output_path behavior is stated. However, thread_order, no_calendar_summary, embed_inline_images, and several strip_* flags are never characterized, leaving half the surface to title-only inference.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource plus the exact output format ('Convert a .eml email file to Markdown with YAML front matter'). It also names the sibling convert_eml_to_bundle and the distinct condition that selects it, so an agent can separate the two without reading schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes attachment-saving use cases to convert_eml_to_bundle and explains the thread_mode and preset choices in operational terms. It does not address when convert_directory or convert_mbox should be preferred over this single-file tool, leaving the batch-vs-single decision implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_eml_to_bundleConvert email to bundleA

Convert a .eml file to a self-contained bundle with markdown and attachments.

Creates a directory containing the converted markdown, extracted attachments, and optionally the original .eml source.

source_handling only accepts 'copy' over MCP: the original .eml is copied into the bundle and left untouched. The 'move' and 'delete' modes are rejected here — use the CLI or the Python API for those.

Returns JSON with bundle_path, markdown_path, attachment_paths, and optional diagnostics.

NameRequiredDescriptionDefault
presetNodefault
eml_pathYes
bundle_rootYes
thread_modeNolatest
thread_orderNooldest-first
source_handlingNocopy
include_raw_htmlNo
strip_signaturesNo
strip_disclaimersNo
embed_inline_imagesNo
include_all_headersNo
no_calendar_summaryNo
strip_quoted_headersNo
strip_tracking_pixelsNo
strip_signature_imagesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=false and readOnlyHint=false, and the description usefully adds that the original .eml is copied and left untouched, plus that unsupported modes are rejected rather than silently downgraded. It lists the returned fields, giving concrete expectations. No contradiction with annotations; only missing detail is failure behavior (e.g., existing bundle directory).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The output artifact is described first, then the source_handling caveat, then the return shape — a sensible front-loaded order. Paragraph breaks are used well. Minor redundancy: the return JSON is listed despite an output schema existing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the return-value recap is not strictly needed, and the description covers artifact creation and the source-preservation contract. But with 15 parameters at 0% schema coverage and no mention of the preset/thread options that materially change output, an agent cannot choose parameters confidently from this definition alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 15 parameters, and the description documents only source_handling. The four enums (preset, thread_mode, thread_order, source_handling) and the ten boolean knobs (strip_signatures, embed_inline_images, include_all_headers, etc.) are left entirely to name inference, so the description does not compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource — convert a .eml file into a self-contained bundle of markdown plus extracted attachments — and clarifies what the output artifact is. It does not explicitly distinguish itself from sibling convert_eml, so the caller must infer the difference from the 'bundle' vs. single-conversion wording.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states the MCP-level constraint: source_handling only accepts 'copy' here, and 'move'/'delete' must go through the CLI or Python API. That is a genuine when/when-not statement. It stops short of routing between this tool and convert_eml/convert_directory/convert_mbox, which is the remaining gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_mboxConvert MBOX archiveA

Convert one flat .mbox archive (e.g. Gmail Takeout) to Markdown files.

Bounded: the archive must be at most 256 MiB, and conversion stops after 1000 messages (the response then has truncated=true; use the dead-letter CLI for larger archives). Compressed archives and Apple Mail .mbox directories are rejected. output_directory is required; one .md per message (or one bundle directory when bundles=true) is written there with a collision-safe JSON report. The source archive is never modified.

Returns a JSON summary (processed, converted, skipped, failed, truncated, report_path, and at most 20 failure entries), never message content. Cancellation is not supported; byte/message caps are not a time limit.

NameRequiredDescriptionDefault
pathYes
presetNodefault
bundlesNo
dry_runNo
thread_modeNolatest
thread_orderNooldest-first
include_raw_htmlNo
output_directoryYes
strip_signaturesNo
strip_disclaimersNo
embed_inline_imagesNo
include_all_headersNo
no_calendar_summaryNo
strip_quoted_headersNo
strip_tracking_pixelsNo
strip_signature_imagesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond annotations: hard 256 MiB and 1000-message caps, the truncated=true signal, the requirement that output_directory be supplied, one .md per message vs bundle directories, a collision-safe report, and the guarantee that the source archive is never modified. It also clarifies negative behavior (no cancellation, caps are not a time limit), which is exactly the kind of trap an agent would otherwise fall into.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose in the first sentence, then groups constraints, output behavior, and return shape into short paragraphs. Dense but every sentence carries information an agent needs; no filler or restatement of the name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Limits, rejection cases, side effects, and return shape are all covered, and an output schema exists so return values need no further explanation. The gap is the undocumented parameter surface: an agent can call this correctly with defaults, but cannot make informed use of the 14 optional formatting toggles.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 16 parameters, so the description carries the full burden, yet it only touches output_directory (already marked required in schema) and bundles=true. Fourteen parameters — preset, dry_run, thread_mode, thread_order, include_raw_html, embed_inline_images, no_calendar_summary, and all the strip_* toggles — get no explanation of what they change or when to set them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Convert one flat .mbox archive ... to Markdown files') with its scope ('one flat', example Gmail Takeout). The distinction from siblings is implicit but strong: convert_directory handles directories, which the description explicitly rejects, and the format (.mbox vs .eml) separates it from convert_eml.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-not conditions (compressed archives and Apple Mail .mbox directories are rejected) and a named alternative for out-of-scope work ('use the dead-letter CLI for larger archives'). It does not explicitly route between convert_eml/convert_directory, but the input-format constraint makes the choice unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_diagnosticsGet conversion diagnosticsA
Read-only

Inspect email quality and structure without writing permanent files.

Use this to assess conversion quality before committing, or to troubleshoot problematic .eml files.

Always returns JSON with: state (normal/degraded/review_recommended), selected_body, segmentation_path, client_hint, confidence, fallback_used, and warnings. Two keys are conditional: stripped_images appears only when images were removed, and attachments only when the message had attachments eligible for retention.

NameRequiredDescriptionDefault
presetNodefault
eml_pathYes
thread_modeNolatest
thread_orderNooldest-first
include_raw_htmlNo
strip_signaturesNo
strip_disclaimersNo
embed_inline_imagesNo
include_all_headersNo
no_calendar_summaryNo
strip_quoted_headersNo
strip_tracking_pixelsNo
strip_signature_imagesNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Consistent with readOnlyHint=true and openWorldHint=false, and adds value beyond them by stating no permanent files are written and enumerating the return-state vocabulary (normal/degraded/review_recommended) plus conditional keys. Falls short of disclosing limits, cost, or when 'degraded' should trigger a re-run.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then usage, then return contract; no filler. The long enumeration of return keys is slightly heavy given an output schema exists, but it is organized and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Return values are well covered even though an output schema exists, and safety context is adequate. However, for a tool with 13 parameters and zero schema descriptions, omitting any parameter guidance leaves a genuine gap an agent would hit when deciding preset/thread/strip behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Thirteen parameters with 0% schema description coverage, and the description explains none of them — preset, thread_mode, thread_order, and the eight strip_*/include_* flags are opaque. The only indirect hint is stripped_images appearing conditionally when images were removed, which barely signals the stripping flags.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Inspect email quality and structure') and differentiates from the convert_* siblings by noting it does not write permanent files. A clear read-only inspection tool, though it doesn't name the siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives two concrete situations: assess conversion quality before committing, or troubleshoot problematic .eml files. This implicitly routes agents away from convert_eml when they only want inspection, but no alternative is named outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.4.5
    • Changedconvert_directory4 fields changed
      • removedInput schema / properties / output_directory / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • removedInput schema / properties / output_directory / default
        Removed value: -null
      • addedInput schema / properties / output_directory / type
        Added value: +"string"
      • changedInput schema / required
        Previous value: -[
        -  "directory"
        -]New value: +[
        +  "directory",
        +  "output_directory"
        +]
    • Addedconvert_mbox
  2. 4 tool updatesv0.2.4
    • First observedconvert_directory
    • First observedconvert_eml
    • First observedconvert_eml_to_bundle
    • First observedget_diagnostics

TDQS

A4/5.0

Scored across 5 tools

Disambiguation4/5

convert_eml and convert_eml_to_bundle are closely related but differentiated by bundle/attachment output, while convert_directory and convert_mbox are separated by input type. get_diagnostics is clearly distinct, leaving only minor ambiguity between single-file conversion variants.

Naming Consistency5/5

All tool names use consistent snake_case and are verb-led, with the convert_* family forming a predictable group and get_diagnostics fitting naturally as a read-only operation. The extra preposition in convert_eml_to_bundle is still clear and consistent.

Tool Count5/5

Five tools form a well-scoped surface for email conversion: single-file, bundle, directory batch, mbox batch, and diagnostics. Each tool has a clear reason to exist without obvious bloat.

Completeness4/5

The surface covers the core conversion workflows, including attachments via bundles and quality inspection via diagnostics. Minor gaps remain around reading back already-converted outputs, and some archive modes are deliberately rejected and deferred to the CLI/API.

Maintenance

ActivityActive
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A local MCP server that provides LLM clients with read/write access to email and calendar data from Gmail, iCloud, and generic IMAP providers. It runs entirely on your machine, keeping data private while enabling email management, calendar operations, and task handling through natural language.
    39
    1
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    MCP server for parsing .eml email files, extracting metadata, content, and attachments with smart organization into folders. Enables AI to read and handle email files offline without triggering trackers.
    2
    2
    AGPL 3.0
  • F
    license
    Not graded
    quality
    B
    maintenance
    A private, single-user MCP server that unifies Gmail, Microsoft 365/Outlook, and IMAP mailboxes for LLMs to search and read emails live, without storing or caching mailbox contents.
    -
  • A
    license
    C
    quality
    D
    maintenance
    A local-first Python MCP server that turns Gmail, Outlook/Microsoft 365, iCloud Mail, and generic IMAP/SMTP mailboxes into a synchronized, searchable OKF knowledge layer, exposing 38 tools and four resources for mailbox actions, synchronization, retrieval, attachments, and optional semantic search while keeping the provider mailbox authoritative.
    38
    1
    MIT