Skip to main content
Glama
Shubby98

email-insights

by Shubby98

email-insights

MCP-сервер, предоставляющий аналитику сигналов электронной почты для Claude Desktop, с фоновым рабочим процессом для запланированных асинхронных задач извлечения и структурированным логированием.

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

email-insights/
├── data/
│   └── emails.csv              # Raw email data (id, from, subject, body, date)
├── database/
│   └── signals.db              # SQLite database (created after running ingestion)
├── db/
│   ├── connection.py           # Single source of truth for SQLite connections
│   ├── schema.py               # DDL for all tables (idempotent CREATE IF NOT EXISTS)
│   ├── signals.py              # Read/write for signals table
│   ├── raw_emails.py           # Read/write for raw_emails table
│   └── jobs.py                 # Read/write for jobs and failed_extractions tables
├── ingestion/
│   ├── fetch_emails_imap.py    # Fetch emails via IMAP → store raw in SQLite
│   ├── parse_csv.py            # Step 1: Load emails from CSV
│   ├── extract_signals.py      # Step 2: Call local LLM to extract signals
│   └── store_signals.py        # Step 3: Write signals to SQLite (run this)
├── logs/
│   └── worker.log              # Rotating log file (auto-created, 5 MB max, 3 backups)
├── mcp_server/
│   ├── server.py               # MCP server: registers tools and starts listening
│   └── tools.py                # SQLite query functions + job scheduling tools
├── utils/
│   └── logger.py               # Shared structured logger (stderr + rotating file)
├── worker/
│   └── job_runner.py           # Background worker: polls SQLite and runs extraction jobs
├── requirements.txt
└── README.md

Related MCP server: io.github.p-w-4-z/inbox-mcp

Настройка

1. Установка зависимостей

pip install -r requirements.txt

2. Настройка учетных данных IMAP

Скопируйте .env.example в .env и введите свои учетные данные:

IMAP_HOST=imap.gmail.com
IMAP_USER=you@gmail.com
IMAP_PASSWORD=your-app-specific-password
IMAP_PORT=993          # optional, default 993
IMAP_MAILBOX=INBOX     # optional, default INBOX

Для Gmail создайте пароль приложения на странице myaccount.google.com/apppasswords.

3. Загрузка писем в SQLite

Получите все письма из вашего почтового ящика и сохраните их в таблице raw_emails:

python ingestion/fetch_emails_imap.py

Индикатор выполнения показывает статус получения и сохранения в реальном времени. Опции:

# Fetch only the 50 most recent emails
python ingestion/fetch_emails_imap.py --limit 50

# Also export a CSV backup
python ingestion/fetch_emails_imap.py --output data/backup.csv

# Count emails in a date range (no fetch)
python ingestion/fetch_emails_imap.py --count --start-date 2025-01-01 --end-date 2025-03-01

4. Запуск LM Studio

  • Откройте LM Studio и загрузите любую модель, следующую инструкциям (Llama 3, Mistral и т. д.)

  • Запустите локальный сервер: Local Server → Start Server

  • URL по умолчанию: http://127.0.0.1:10101

  • Скопируйте строку идентификатора модели и вставьте ее в ingestion/extract_signals.py как LOCAL_MODEL

5. Запуск извлечения сигналов

python ingestion/store_signals.py

Этот скрипт считывает data/emails.csv, отправляет каждое письмо в вашу локальную LLM для извлечения сигналов и сохраняет результаты в database/signals.db.

6. Запуск фонового рабочего процесса

Рабочий процесс — это отдельный процесс, который опрашивает систему на наличие запланированных задач извлечения. Запустите его в отдельном терминале:

python worker/job_runner.py

Рабочий процесс записывает всю активность в logs/worker.log и в stderr. Он опрашивает SQLite каждые 10 секунд и автоматически подхватывает любые ожидающие или запланированные задачи.

7. Подключение Claude Desktop

Добавьте этот сервер в конфигурацию Claude Desktop:

Mac: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "email-insights": {
      "command": "python",
      "args": ["/absolute/path/to/email-insights/mcp_server/server.py"]
    }
  }
}

Перезапустите Claude Desktop. Вы должны увидеть email-insights в списке инструментов.

Инструменты MCP

Инструменты запросов

Инструмент

Описание

get_email_signals_tool

Запрос сигналов с дополнительными фильтрами по дате/теме/тону

get_topic_distribution_tool

Количество писем по категориям тем

get_sender_patterns_tool

Разбивка по типу отправителя со статистикой срочности

search_signals_tool

Поиск сигналов по ключевым словам

Инструменты планирования задач

Инструмент

Описание

schedule_extraction_tool

Создание задачи извлечения — выполняется сейчас, в запланированное время или в полночь

check_job_status_tool

Получение прогресса задачи в реальном времени (обновляется после каждого письма)

retry_failed_emails_tool

Повторная постановка в очередь только тех писем, которые не удалось обработать в предыдущей задаче

Все инструменты планирования возвращают результат немедленно. Извлечение выполняется асинхронно в рабочем процессе.

Режимы работы schedule_extraction_tool

run_mode

Поведение

scheduled_time

"now"

Рабочий процесс подхватывает задачу при следующем опросе (по умолчанию)

не используется

"scheduled"

Выполняется в определенное время

"HH:MM" или "YYYY-MM-DD HH:MM"

"midnight"

Выполняется сегодня в 00:00:00

не используется

Архитектура

Claude Desktop ──stdio──▶ mcp_server/server.py
                                  │
                          mcp_server/tools.py
                                  │
                           SQLite signals.db
                                  │
                        worker/job_runner.py  ◀── runs separately
                                  │
                          LM Studio (local LLM)

MCP-сервер и рабочий процесс — это два полностью независимых процесса, которые совместно используют только базу данных SQLite. MCP-сервер никогда не ждет завершения извлечения — он создает запись о задаче и немедленно возвращает результат. Рабочий процесс отвечает за все записи в таблицах jobs и failed_extractions (обновления статуса, прогресс, ошибки); MCP-сервер только считывает статус задачи.

Схема SQLite

CREATE TABLE raw_emails (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    email_id     TEXT    UNIQUE,    -- SHA-256(date|sender_name|sender_email)[:16]
    date         TEXT,              -- ISO format from email Date header
    sender_name  TEXT,
    sender_email TEXT,
    subject      TEXT,
    body         TEXT,
    fetched_at   TEXT DEFAULT (datetime('now'))
);

CREATE TABLE signals (
    id              INTEGER PRIMARY KEY AUTOINCREMENT,
    email_id        TEXT    UNIQUE,
    topic           TEXT,       -- job application | recruiter outreach | rejection | interview | networking | other
    tone            TEXT,       -- positive | neutral | negative
    sender_type     TEXT,       -- recruiter | company HR | networking contact | university | other
    urgency         TEXT,       -- high | medium | low
    requires_action INTEGER,    -- 0 or 1
    date            TEXT        -- ISO format: YYYY-MM-DD
);

CREATE TABLE jobs (
    job_id           INTEGER PRIMARY KEY AUTOINCREMENT,
    schema_id        INTEGER,
    status           TEXT NOT NULL DEFAULT 'pending',  -- pending | scheduled | running | completed | failed
    run_at           TEXT,       -- ISO datetime; NULL means run immediately
    total_emails     INTEGER DEFAULT 0,
    processed_emails INTEGER DEFAULT 0,
    created_at       TEXT DEFAULT (datetime('now')),
    completed_at     TEXT,
    error_message    TEXT,
    retry_of_job_id  INTEGER     -- set for retry jobs; links back to source job
);

CREATE TABLE failed_extractions (
    id            INTEGER PRIMARY KEY AUTOINCREMENT,
    job_id        INTEGER NOT NULL,
    email_id      TEXT NOT NULL,
    error_message TEXT,
    created_at    TEXT DEFAULT (datetime('now'))
);

Таблицы jobs и failed_extractions создаются автоматически при первом использовании — ручная миграция не требуется.

Структурированное логирование

Вся активность рабочего процесса записывается в logs/worker.log (создается автоматически) и в stderr.

Формат лога:

[2026-03-05 14:22:01] [INFO] Worker started, polling every 10 seconds
[2026-03-05 14:22:11] [INFO] Job 1 picked up: schema_id=None, 10 emails to process
[2026-03-05 14:22:13] [INFO] [1/10] email_id=e001 extracted: topic=recruiter outreach, tone=positive
[2026-03-05 14:22:14] [WARNING] [2/10] email_id=e002 retrying after error: JSONDecodeError
[2026-03-05 14:22:16] [ERROR] [2/10] email_id=e002 failed after retry, saved to failed_extractions
[2026-03-05 14:22:45] [INFO] Job 1 completed in 34.2s: 9 success, 1 failed

Файл лога ротируется при достижении 5 МБ, сохраняются последние 3 файла (worker.log, worker.log.1, worker.log.2).

Что можно узнать из кода

mcp_server/server.py

  • FastMCP("email-insights") — создает экземпляр сервера с отображаемым именем

  • @mcp.tool() — регистрирует декорированную функцию как вызываемый инструмент MCP

  • Docstrings имеют значение — Claude читает их, чтобы решить, когда и как вызывать каждый инструмент

  • Подсказки типов (Type hints) — FastMCP использует их для построения схемы входных данных JSON, которую получает Claude

  • mcp.run() — запускает цикл stdio; Claude Desktop взаимодействует через stdin/stdout

mcp_server/tools.py

  • Полностью отделены от MCP — обычные функции Python, возвращающие строки JSON

  • Параметризованные SQL-запросы предотвращают инъекции: WHERE topic LIKE ? с params

  • Фабрика sqlite3.Row позволяет обращаться к столбцам по имени: row["topic"]

  • _ensure_jobs_tables() использует CREATE TABLE IF NOT EXISTS — безопасно вызывать при каждом вызове инструмента

worker/job_runner.py

  • Опрашивает SQLite каждые 10 секунд — брокер сообщений не нужен, достаточно общей БД

  • PRAGMA journal_mode=WAL позволяет MCP-серверу читать данные, пока рабочий процесс их записывает

  • Логика повторных попыток: одна попытка при тайм-ауте или неверном JSON, затем запись в failed_extractions

  • processed_emails обновляется после каждого письма, поэтому check_job_status_tool всегда отражает текущий прогресс

utils/logger.py

  • get_logger(name) идемпотентен — безопасно вызывать из любого модуля, без дублирования обработчиков

  • RotatingFileHandler предотвращает бесконечный рост размера файла на диске

  • Использует sys.stderr для обработчика потока — sys.stdout зарезервирован для протокола JSON-RPC MCP

ingestion/fetch_emails_imap.py

  • imaplib.IMAP4_SSL — подключается к любому IMAP-серверу; учетные данные загружаются из .env

  • mail.search(None, "ALL") возвращает все ID сообщений; порядок обратный (сначала самые новые)

  • Индикаторы выполнения tqdm показывают статус получения и сохранения в SQLite в реальном времени с текущей темой в качестве суффикса

  • Сохраняет в таблицу raw_emails через db.raw_emails — идемпотентно (INSERT OR REPLACE)

  • --output является необязательным: CSV записывается только при явном указании

ingestion/extract_signals.py

  • OpenAI(base_url="http://127.0.0.1:10101/v1") — направляет клиент на LM Studio

  • Низкий temperature=0.1 — более детерминированный вывод, лучше подходит для структурированного JSON

  • Удаляет маркеры кода Markdown, в которые LLM может обернуть свой JSON-ответ

  • Возвращается к безопасным значениям по умолчанию, если парсинг не удался — конвейер никогда не падает из-за одного плохого письма

F
license - not found
-
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Provider-agnostic email MCP server that connects any IMAP mailbox to AI assistants, enabling email management through natural language.
    8
    AGPL 3.0
  • A
    license
    -
    quality
    B
    maintenance
    An MCP server that receives emails on your domain and allows AI assistants to search, read, and manage them via natural language queries.
    1,276
    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

View all related MCP servers

Related MCP Connectors

  • Shipmail MCP server for AI agent custom-domain email inboxes with REST API and webhooks.

  • Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.

  • Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Shubby98/email-insights'

If you have feedback or need assistance with the MCP directory API, please join our Discord server