email-insights
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.mdRelated MCP server: io.github.p-w-4-z/inbox-mcp
设置
1. 安装依赖
pip install -r requirements.txt2. 配置 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-014. 启动 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 工具
查询工具
工具 | 描述 |
| 使用可选的日期/主题/语气过滤器查询信号 |
| 每个主题类别的电子邮件计数 |
| 按发件人类型分类并提供紧急程度统计 |
| 按关键字搜索信号 |
任务调度工具
工具 | 描述 |
| 创建提取任务 — 立即运行、在指定时间运行或在午夜运行 |
| 获取任务的实时进度(每封邮件处理后更新) |
| 仅重新排队之前任务中失败的电子邮件 |
所有调度工具都会立即返回。提取过程在工作进程中异步运行。
schedule_extraction_tool 运行模式
| 行为 |
|
| 工作进程在下一次轮询时获取(默认) | 不使用 |
| 在特定时间运行 |
|
| 今晚 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 MB 时轮转,并保留最后 3 个文件(worker.log、worker.log.1、worker.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 ?使用paramssqlite3.Row工厂允许按名称访问列:row["topic"]_ensure_jobs_tables()使用CREATE TABLE IF NOT EXISTS— 在每次工具调用时调用都是安全的
worker/job_runner.py
每 10 秒轮询一次 SQLite — 无需消息代理,只需共享数据库
PRAGMA journal_mode=WAL允许 MCP 服务器在工作进程写入时进行读取重试逻辑:超时或 JSON 错误时重试一次,然后记录到
failed_extractionsprocessed_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 代码块
如果解析失败,则回退到安全默认值 — 管道永远不会因为一封坏邮件而崩溃
This server cannot be installed
Maintenance
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
- AlicenseBqualityDmaintenanceA 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.39MIT
- AlicenseAqualityDmaintenanceProvider-agnostic email MCP server that connects any IMAP mailbox to AI assistants, enabling email management through natural language.8AGPL 3.0
- Alicense-qualityBmaintenanceAn MCP server that receives emails on your domain and allows AI assistants to search, read, and manage them via natural language queries.1,276MIT
- AlicenseAqualityDmaintenanceMCP 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.22AGPL 3.0
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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