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.pyLOCAL_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サーバーとワーカーは完全に分離された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'))
);

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

ログファイルは5MBでローテーションされ、最新の3ファイル(worker.logworker.log.1worker.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通のメールが原因でパイプラインがクラッシュすることはありません

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