Skip to main content
Glama
Shubby98

email-insights

by Shubby98

email-insights

一个为 Claude Desktop 提供电子邮件信号分析的 MCP 服务器,包含用于定时异步提取任务的后台工作进程和结构化日志记录。

项目结构

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 中。它每 10 秒轮询一次 SQLite,并自动获取任何待处理或已到期的定时任务。

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 服务器从不等待提取完成 — 它只是创建一个任务记录并立即返回。工作进程负责对 jobsfailed_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'))
);

jobsfailed_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 MB 时轮转,并保留最后 3 个文件(worker.logworker.log.1worker.log.2)。

代码学习要点

mcp_server/server.py

  • FastMCP("email-insights") — 创建带有显示名称的服务器实例

  • @mcp.tool() — 将装饰后的函数注册为可调用的 MCP 工具

  • 文档字符串很重要 — Claude 读取它们以决定何时以及如何调用每个工具

  • 类型提示 — FastMCP 使用它们来构建 Claude 接收的 JSON 输入模式

  • mcp.run() — 启动 stdio 循环;Claude Desktop 通过 stdin/stdout 进行通信

mcp_server/tools.py

  • 与 MCP 完全分离 — 返回 JSON 字符串的普通 Python 函数

  • 参数化 SQL 查询可防止注入:WHERE topic LIKE ? 使用 params

  • sqlite3.Row 工厂允许按名称访问列:row["topic"]

  • _ensure_jobs_tables() 使用 CREATE TABLE IF NOT EXISTS — 在每次工具调用时调用都是安全的

worker/job_runner.py

  • 每 10 秒轮询一次 SQLite — 无需消息代理,只需共享数据库

  • 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 保留给 MCP 的 JSON-RPC 协议使用

ingestion/fetch_emails_imap.py

  • imaplib.IMAP4_SSL — 连接到任何 IMAP 服务器;凭据从 .env 加载

  • mail.search(None, "ALL") 返回所有消息 ID;反转以实现最近优先顺序

  • tqdm 进度条显示实时抓取和 SQLite 存储状态,并以当前主题作为后缀

  • 通过 db.raw_emails 存储到 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

  • 去除 LLM 可能在其 JSON 响应周围包裹的 markdown 代码块

  • 如果解析失败,则回退到安全默认值 — 管道永远不会因为一封坏邮件而崩溃

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