Mail Digest MCP Server
by Maksim061994
README.md
# Mail digest — сбор и обработка рабочей почты
Инструмент из двух слоёв:
1. **`fetch_mail.py`** — Python-скрипт. Забирает письма за вчера по IMAP и складывает
в `output/mail_<дата>.json` и `output/mail_<дата>.md`. Никаких LLM, только выгрузка.
2. **Слой обработки (Claude)** — читает свежий `mail_*.json` и делает дайджест,
извлекает задачи и дедлайны, группирует письма и готовит черновики ответов
на письма, которые их требуют. Правила обработки задаются локально и в репозиторий
не входят.
## Быстрый старт
```bash
cd mail_digest
cp config.example.ini config.ini # впиши доступы к почте
python3 fetch_mail.py # заберёт письма за вчера
```
Результат появится в `output/`. Дальше попроси меня в чате:
«разбери почту за вчера» — я прочитаю выгрузку и подготовлю дайджест, задачи и черновики ответов.
## Параметры запуска
```bash
python3 fetch_mail.py # за вчера (по умолчанию)
python3 fetch_mail.py --date 2026-07-06 # за конкретную дату
python3 fetch_mail.py --days 3 # за последние 3 дня
```
## Доступы и безопасность
- Доступы читаются из `config.ini` **или** переменных окружения
(`IMAP_HOST`, `IMAP_PORT`, `IMAP_USER`, `IMAP_PASSWORD`, `IMAP_FOLDER`, `IMAP_SSL`).
Переменные окружения имеют приоритет.
- `config.ini` содержит пароль — **не коммить его, не пересылай**. В `.gitignore` уже добавлен.
- Если у почты включена 2FA, используй **пароль приложения**, а не основной пароль.
- Скрипт открывает ящик в режиме **readonly** — письма не помечаются прочитанными.
## Где взять IMAP-сервер
Посмотри в почтовом клиенте (Outlook/Thunderbird → настройки учётной записи → сервер входящей почты IMAP)
или спроси у ИТ-отдела адрес IMAP-сервера и порт.
## MCP-сервер (интерактивный доступ из Claude Cowork)
`fetch_mail.py` — это пакетная выгрузка. Для **живого** доступа есть отдельный слой
**`mcp_server.py`** — MCP-сервер, к которому Claude Cowork подключается по HTTP и
может сам запрашивать письма и готовить ответы. Он **не меняет** `fetch_mail.py`,
а переиспользует его функции.
### Что умеет (инструменты)
| Инструмент | Что делает |
|---|---|
| `list_emails(period)` | Письма за `hour` / `today` / `day` / `yesterday` / `week` (карточки без полного тела) |
| `get_email(message_id)` | Полный текст одного письма |
| `search_emails(query, days)` | Поиск по отправителю / теме / телу |
| `list_sent(days, limit)` | Твои **отправленные** письма с текстом — чтобы изучить твой стиль |
| `list_folders()` | Список папок ящика (узнать имя «Отправленных» для `SENT_FOLDER`) |
| `reply_email(message_id, body, cc, confirm)` | Ответ: черновик `.eml`, а при `confirm=true` — **реальная отправка** по SMTP |
| `send_email(to, subject, body, cc, confirm)` | Новое письмо: черновик, а при `confirm=true` — **реальная отправка** |
| `mark_read(message_id)` | Пометить письмо прочитанным (флаг `\Seen`) |
| `list_drafts()` | Список готовых черновиков |
⚠️ **Отправка по умолчанию выключена.** `reply_email`/`send_email` без `confirm`
только создают `.eml` в `output/drafts/`. Реальная отправка происходит **лишь при
`confirm=true`** и требует настроенного SMTP (см. `.env.example`). Чтение писем —
readonly; состояние ящика меняет только `mark_read`.
### Запуск на сервере
Сервер поднимают на машине, у которой есть доступ к корпоративному IMAP.
Доступы к почте — те же, что у `fetch_mail.py` (`config.ini` или переменные окружения).
```bash
# Вариант 1: uv сам поставит зависимости (Python 3.10+ подтянется автоматически)
uv run mcp_server.py
# Вариант 2: обычный venv
python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python mcp_server.py
```
Настройки HTTP-сервера (env): `MCP_HOST` (по умолч. `0.0.0.0`),
`MCP_PORT` (`8765`), `MCP_PATH` (`/mcp`).
### Запуск в контейнере (рекомендуется для сервера)
В образ попадают только `fetch_mail.py`, `mcp_server.py` и `requirements.txt`
(см. `.dockerignore`) — пароль и `output/` внутрь **не** запекаются. Доступы к
почте передаются через `.env`, черновики пишутся в `./output` на хосте (том).
```bash
cp .env.example .env # впиши IMAP-доступы (файл не коммитится)
docker compose build # собрать образ
docker compose up -d # запустить в фоне
docker compose logs -f # смотреть логи
docker compose down # остановить
```
По умолчанию порт слушается только на `127.0.0.1:8765` — наружу выставляй через
reverse-proxy/VPN, а не в открытый интернет. Без compose то же самое вручную:
```bash
docker build -t mail-mcp:latest .
docker run -d --name mail-mcp --env-file .env \
-p 127.0.0.1:8765:8765 -v "$PWD/output:/app/output" mail-mcp:latest
```
### Подключение Claude Cowork
Пропиши адрес сервера в конфиг MCP-клиента (см. `mcp.client.example.json`):
```json
{ "mcpServers": { "mail": { "type": "http", "url": "http://АДРЕС-СЕРВЕРА:8765/mcp" } } }
```
## Что дальше (идея автоматизации)
Когда убедимся, что сбор работает, можно повесить ежедневную задачу:
утром скрипт забирает письма за вчера, а я готовлю дайджест + черновики ответов к твоему приходу.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues