Inbox Zero за час: как MCP-сервер привёл порядок в почту — Блог
$ cat .md

Inbox Zero за час: как MCP-сервер привёл порядок в почту

Inbox Zero за час: как MCP-сервер привёл порядок в почту

Переполненный почтовый ящик — знакомая каждому боль. 2672 письма, хаос, потеря важных сообщений. Рассказываю, как мы построили MCP-сервер с матричной классификацией и разобрали завалы за час.

Коротко

За 50 минут и 73 последовательных батча MCP-сервер разобрал 2672 письма из INBOX по четырём папкам. Классификация использовала эвристические сигналы, а письма не удалялись — их можно проверить и обработать вручную.

Результат Значение
Писем в INBOX 2672 → 0
Время обработки около 50 минут
Батчи 73
Удалено писем 0
Папок результата 4

Проблема: 2672 письма и никакого просвета

Яндекс.Почта — мой основной рабочий ящик. Годы подписок, рассылок, уведомлений, регистраций на сайтах. Я не чистил его… никогда.

Когда я запустил первый замер, цифра была отрезвляющей: 3459 писем. После первичной ручной чистки — 2672. И это только INBOX, без учёта спама и социальных сетей.

Проблемы типичные для любого, кто пользуется почтой больше пары лет:

  • Рассылки (Mailchimp, SendGrid, Unisender) — 60%+ всего объёма
  • Уведомления (GitHub, Trello, Jira, Telegram) — ещё 15%
  • Личные письма — теряются в шуме
  • Отписка от каждой рассылки вручную — это часы бессмысленного труда
  • Пропущенные важные письма — когда я всё-таки находил важное письмо, оно было трёхмесячной давности

Нужно было решение. И не очередной «умный» фильтр от почтового провайдера (они не справляются), а инструмент, который работает так, как я хочу.


Идея: мульти-сигнальная классификация

Вместо того чтобы раскидывать письма по папкам вручную, я решил построить систему, которая сама понимает, что за письмо пришло и куда его класть.

Ключевое наблюдение: у каждого письма есть тип отправителя (человек или автоматическая система) и тип контента (промо/маркетинг или транзакционное/личное). Если два этих измерения объединить, получается простая и понятная матрица:

              promo              human
machine  → Newsletters       → Notifications
human    → Need Review Newsl. → Need Review Human

Технически это выглядит как два независимых скора:

Machine Score (0–100) — насколько письмо похоже на автоматическое:

  • List-Unsubscribe +10, Auto-Submitted: auto-generated +12, List-Id +8
  • ESP-домен (Mailchimp, SendGrid…) +9
  • Отправитель no-reply +8
  • Частота (10+ писем от отправителя) +8

Promo Score (0–100) — насколько содержание похоже на маркетинг:

  • Unsubscribe-ссылка +7, UTM-параметры +6
  • Физический адрес в footer +5
  • View in browser +4
  • Ключевые слова в теме (sale, offer, скидка) +3

Пороги: machine ≥15 → автоматическая система, promo ≥10 → промо/маркетинг. Четыре комбинации — четыре действия.


Инструмент: AI Mail MCP

Вся эта логика упакована в MCP-сервер — протокол, который позволяет AI-агентам (Claude, Cursor, любой MCP-клиент) взаимодействовать с внешними сервисами через стандартизированные инструменты.

Сервер предоставляет 14 инструментов, разделённых на две группы:

Read-only (безопасные):

  • Подключение к Yandex/Gmail/custom IMAP
  • Сканирование ящика с классификацией
  • Статистика (топ отправителей, прогноз очистки)
  • Статус папок и ящика

Write-операции:

  • Удаление и перемещение писем
  • Пакетная очистка по матрице
  • Экспорт в .eml и по отправителю

Подключение и первый замер

Вот как выглядит подключение и первый замер:

// MCP tool call
email-cleanup_connect(provider: "yandex", user: "my@yandex.ru", password: "***")
// → {status: "connected", host: "imap.yandex.com", port: 993}

email-cleanup_inbox_stats(limit: 100)
// → {total: 2672, machine_promo: ..., machine_human: ..., human_human: ...}

Перед write-операциями важно сначала проверить классификацию в режиме просмотра, сохранить резервную копию и использовать отдельный пароль приложения. Основной пароль от почты в такие команды передавать нельзя.

Пакетная очистка

Пакетная очистка выполнялась без тела письма — только по заголовкам, чтобы ускорить обработку:

email-cleanup_batch_cleanup(
  machine_promo_action: "move",
  human_promo_action: "move",
  machine_human_action: "move",
  human_human_action: "move",
  dry_run: false,
  limit: 100,
  include_body: false
)

Как мы чистили: 73 батча и никакого волшебства

Yandex IMAP — не самый быстрый протокол. Он throttлит запросы, падает через 3–4 операции, требует переподключения. Поэтому стратегия была простая: маленькие батчи по 30 писем, последовательно, с переподключением на каждый.

Вот как выглядела сессия (сокращённо):

Batch  1: mp=13 mh=0  hp=0  hh=17  INBOX: 2165
Batch 10: mp=0  mh=1  hp=0  hh=29  INBOX: 1895
Batch 20: mp=1  mh=0  hp=0  hh=29  INBOX: 1595
Batch 30: mp=8  mh=1  hp=0  hh=21  INBOX: 1295
Batch 40: mp=6  mh=1  hp=0  hh=23  INBOX: 995
Batch 50: mp=6  mh=0  hp=0  hh=24  INBOX: 695
Batch 60: mp=0  mh=0  hp=0  hh=30  INBOX: 395
Batch 70: mp=0  mh=0  hp=0  hh=30  INBOX: 95
Batch 73: mp=1  mh=0  hp=0  hh=4   INBOX: 0

73 батча, ~50 минут. INBOX: 2672 → 0.

Результат — четыре аккуратные папки:

Папка Писем Содержимое
ai-mail/Newsletters 1121 Рассылки, промо, маркетинг
ai-mail/Notifications 171 Уведомления от сервисов
ai-mail/To Review Human 2199 Личные письма — к прочтению
ai-mail/To Review Newsletters 24 Подозрительные рассылки от людей

Самое приятное: ни одно письмо не потеряно. Всё разложено по папкам, ничего не удалено. Можно спокойно зайти в To Review Human и читать только важное.


Архитектура: что под капотом

Сервер написан на Python, стек минималистичный:

  • FastMCP — фреймворк для MCP-серверов (асинхронный, pydantic-валидация)
  • imap-tools — работа с IMAP (fetch, move, delete, folder management)
  • Pydantic 2 — модели данных (EmailInfo, ClassificationResult)

Классификатор — чистая эвристика, без ML. 12 сигналов для machine score, 8 для promo score. Каждый сигнал — проверка хедера или тела письма.

# Упрощённая логика классификации
def classify(self, email):
    machine_score = self._score_machine(email)
    promo_score = self._score_promo(email)

    if machine_score >= 15 and promo_score >= 10:
        return Classification.MACHINE_PROMO      # → Newsletters
    if machine_score >= 15 and promo_score < 10:
        return Classification.MACHINE_HUMAN       # → Notifications
    if machine_score < 15 and promo_score >= 10:
        return Classification.HUMAN_PROMO         # → To Review Newsletters
    return Classification.HUMAN_HUMAN              # → To Review Human

Важный технический нюанс. imap-tools возвращает значения заголовков как кортежи (tuple), а не строки. Без _extract_header_value() классификация могла бы неверно отправлять письма в human_human.


Итоги и следующий шаг

Что изменилось за один вечер:

  • Inbox Zero — не миф. 50 минут работы MCP-агента = пустая папка «Входящие»
  • Пропущенные письма найдены — в To Review Human оказалось 2199 писем, кучу из которых я не видел
  • Рассылки изолированы — 1121 промо-письмо в двух папках, не отвлекают
  • Потери данных нет — ни одно письмо не удалено, всё доступно

Следующие шаги очевидны:

  1. Добавить ML-классификатор поверх эвристик — чтобы точнее отличать человеческие письма от автоматических
  2. Веб-интерфейс — чтобы видеть статистику и управлять правилами без MCP-клиента
  3. OAuth2 — вместо паролей приложений (сейчас только Yandex App Password)
  4. Email-as-CRM — автоматическое создание задач из писем от клиентов

Но уже сейчас инструмент работает и приносит пользу. Если у вас тоже завал в почте — MCP-сервер справится за час.


Ссылки