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 INBOXGmailの場合は、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サーバーとワーカーは完全に分離された2つのプロセスであり、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ログファイルは5MBでローテーションされ、最新の3ファイル(worker.log、worker.log.1、worker.log.2)が保持されます。
コードから学ぶべきこと
mcp_server/server.py
FastMCP("email-insights")— 表示名を持つサーバーインスタンスを作成@mcp.tool()— デコレートされた関数を呼び出し可能なMCPツールとして登録Docstringの重要性 — Claudeはこれらを読み取って、いつどのツールを呼び出すかを決定します
型ヒント — FastMCPはこれを使用して、Claudeが受け取るJSON入力スキーマを構築します
mcp.run()— stdioループを開始。Claude Desktopはstdin/stdout経由で通信します
mcp_server/tools.py
MCPとは完全に分離されており、JSON文字列を返す純粋なPython関数です
パラメータ化されたSQLクエリによりインジェクションを防止:
paramsを使用したWHERE topic LIKE ?sqlite3.Rowファクトリにより、row["topic"]のように名前で列にアクセス可能_ensure_jobs_tables()はCREATE TABLE IF NOT EXISTSを使用しており、ツール呼び出しごとに安全に実行可能
worker/job_runner.py
10秒ごとにSQLiteをポーリング。メッセージブローカーは不要で、共有DBのみを使用
PRAGMA journal_mode=WALにより、ワーカーが書き込んでいる間もMCPサーバーが読み取り可能リトライロジック:タイムアウトや不正なJSONの場合は1回再試行し、その後
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レスポンスを囲む可能性のあるマークダウンコードブロックを除去します
解析に失敗した場合は安全なデフォルト値にフォールバックするため、1通のメールが原因でパイプラインがクラッシュすることはありません
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