JO

japan-opendata-lab/correlation-discovery-mcp

Developer tools
0 stars 0 forks Quality 83 Trend 20MIT

Sub-200ms Automated Correlation, Driver Discovery & Outlier Detection MCP Server for any DuckDB, Parquet, or CSV datasets

Overview

When connecting local LLMs (such as , , or via LM Studio / Ollama) or cloud AI agents (Claude Desktop, Cursor, Windsurf, Cline) to large tabular datasets, asking the LLM to write multi-table statistical SQL (JOIN, GROUP BY, corr(), regr_slope(), residual Z-scores) often leads to: 1. or syntax errors in complex SQL queries. 2. when joining entity-level tables with facility/transaction-level tables. 3. where variables appear correlated simply because of population or entity scale. 4. taking dozens of seconds per prompt. solves all of these problems in a single, zero-configuration MCP tool (discover_correlations): - : Automatically scans any .duckdb, .parquet, or .csv files in DATA_SOURCE_DIR, dynamically detecting shared join keys (municipality_code, prefecture, corporate_number, year, region_code, customer_id, etc.) and numeric metric columns. Add 100+ new Parquet files and it adapts with .

README

correlation-discovery-mcp

Sub-200ms Automated Correlation, Driver Discovery & Regression Outlier Detection MCP Server for any DuckDB, Parquet, or CSV Datasets
あらゆる DuckDB / Parquet / CSV データソースから「相関係数 ($r$値)」「目的変数に対する要因ランキング」「回帰からの外れ値(異常値)」を0.2秒で一括算出する汎用 MCP サーバー

English | 日本語ドキュメント


🌍 English Documentation

Why correlation-discovery-mcp?

When connecting local LLMs (such as Qwen3-8B, Llama-3, or Mistral via LM Studio / Ollama) or cloud AI agents (Claude Desktop, Cursor, Windsurf, Cline) to large tabular datasets, asking the LLM to write multi-table statistical SQL (JOIN, GROUP BY, corr(), regr_slope(), residual Z-scores) often leads to:

  1. Hallucinated table/column names or syntax errors in complex SQL queries.
  2. Cartesian explosion (Many-to-Many JOIN traps) when joining entity-level tables with facility/transaction-level tables.
  3. Spurious correlations where variables appear correlated simply because of population or entity scale.
  4. Slow iterative trial-and-error taking dozens of seconds per prompt.

correlation-discovery-mcp solves all of these problems in a single, zero-configuration MCP tool (discover_correlations):

  • Zero-Hardcoding Dynamic Schema Introspection: Automatically scans any .duckdb, .parquet, or .csv files in DATA_SOURCE_DIR, dynamically detecting shared join keys (municipality_code, prefecture, corporate_number, year, region_code, customer_id, etc.) and numeric metric columns. Add 100+ new Parquet files and it adapts with zero code changes.
  • Sub-200ms Statistical Execution: Pre-aggregates key-level vectors with automatic signature caching to compute exact Pearson $r$, $R^2$, linear regression slopes/intercepts, top/bottom 5 records, and top 5 regression outliers (anomalies with residual Z-scores) in 0.01s – 0.15s.
  • Per-Capita Normalization (normalize_by): Eliminates spurious correlations caused by population or company size in a single parameter (normalize_by="population").
  • Analytical Perspective Prompts (include_perspective_prompts): Automatically attaches structured reasoning prompts (outlier deep-dive, reverse causality & confounder check, bottom-tier structural commonality) grounded in the actual computed records.
  • Enterprise-Grade Security & Sandboxing:
    • Connects to external DuckDB databases strictly with read_only=True and locks down the engine with enable_external_access=false and lock_configuration=true (SELECT-only execution).
    • Confines cache file writes strictly within the designated directory using Path.resolve() path-traversal verification (../ rejected) with zero file-deletion capabilities.
    • Wraps untrusted/external text labels in ... boundary tags to prevent prompt injection.

✨ Three Unified Exploration Modes (discover_correlations)

Mode Purpose Required / Key Parameters What It Returns in <0.2s
"pair" Verify a Specific Pair & Detect Anomalies table_x, column_x, table_y, column_y Exact Pearson $r$, $R^2$, sample size $n$, regression slope/intercept, Top 5 & Bottom 5 records, and Top 5 Regression Outliers (actual vs. predicted $Y$ and residual Z-score).
"find_drivers" Exhaustive Driver Ranking Scan target_table, target_column Scans all joinable tables and numeric columns against your target variable, returning ranked Top Positive Drivers, Top Negative Drivers, and each driver’s #1 outlier.
"serendipity" Cross-Domain Unexpected Discovery (None — just mode="serendipity") Cross-references tables across different semantic categories to surface unexpected strong correlations ($|r| \ge 0.5$) and notable anomalies when you don’t have a hypothesis yet.

🚀 Quick Start

1. Installation

git clone https://github.com/japan-opendata-lab/correlation-discovery-mcp.git
cd correlation-discovery-mcp
pip install -e .

2. Configure in LM Studio (~/.lmstudio/mcp.json) or Claude Desktop / Cursor

Point DATA_SOURCE_DIR to any directory containing .parquet / .csv / .duckdb files, or directly to a .duckdb database file:

{
  "mcpServers": {
    "correlation-discovery-mcp": {
      "command": "python",
      "args": [
        "-X",
        "utf8",
        "./oss_mcp/correlation-discovery-mcp/server.py"
      ],
      "env": {
        "PYTHONIOENCODING": "utf-8",
        "DATA_SOURCE_DIR": "./data/platform_dist/global_megabank.duckdb;./data/dist"
      }
    }
  }
}

🔗 Synergy with japan-data-mcp & Japan Official Data Megabank (RapidAPI)

While correlation-discovery-mcp works with any custom DuckDB / Parquet / CSV dataset worldwide, it becomes an instant socioeconomic intelligence engine when paired with the 162+ standardized Japanese & Global datasets from Japan Open Data Lab:

Example Workflow: Local LLM (Qwen3-8B) + correlation-discovery-mcp + japan-data-mcp

  1. Discover Drivers (find_drivers): Ask “What factors drive official land prices (land_prices_official) across Japanese municipalities?” → correlation-discovery-mcp scans 900+ numeric columns across 160+ datasets in 0.05 seconds, revealing top positive drivers (building_construction $r=+0.98$, daily_traffic_volume $r=+0.90$, demographics taxable income $r=+0.71$) and negative drivers (surveillance_cameras $r=-0.77$, ski_resorts $r=-0.72$).
  2. Inspect Regression Outliers (pair): Verify demographics (taxable income) vs. land_prices_official ($r=+0.7105, n=1,354$) and immediately spot municipalities whose land prices significantly outperform or underperform their income trend line (residual_z_score > +3.0σ).
  3. Fetch Entity Details (japan-data-mcp): Pass the discovered outlier municipality_code to japan-data-mcp (search_japan_official_data) to inspect specific infrastructure, procurement contracts, or hospital facilities in that exact municipality.

🇯🇵 日本語ドキュメント

なぜ correlation-discovery-mcp が必要なのか?

LM Studio 上のローカルLLM(Qwen3-8B 等)や Claude Desktop / Cursor などの AI エージェントに DuckDB や Parquet データを分析させる際、LLM 自身に複雑な統計 SQL(複数テーブルの JOIN、キー別事前集約、corr()、regr_slope()、残差 Zスコアによる外れ値抽出)を書かせると、以下の課題が頻発します。

  1. カラム名・テーブル名のハルシネーションや複雑な SQL 構文エラー
  2. **多対多 JOIN による直積爆発(Cartesian Explosion)**と計算時間の肥大化
  3. **人口規模や企業規模による「見せかけの相関(擬似相関)」**の見落とし
  4. **外れ値(回帰直線から大きく外れた異常値レコード)**の算出漏れ

correlation-discovery-mcp は、これらの課題を単一の統合ツール discover_correlations で解決するオープンソースの高速統計探索エンジンです。

4大特徴

  1. スキーマ自動検出(ハードコード完全ゼロ)
    • 接続先の DuckDB (.duckdb) / Parquet (.parquet) / CSV (.csv) 群から、「結合可能な共通キー(municipality_code, prefecture, corporate_number, year, または任意の同名ID列)」と「数値型カラム」を動的に自動検出します。
    • データセットが今後何百個増えても、また独自業務データ(売上・顧客・センサー・金融データ等)に差し替えても、コード変更ゼロで即座に自動対応します。
  2. 0.2秒以内の超高速一括算出
    • DuckDB のカラムナ集計とデータソース署名(SHA-256)に基づく自動ベクトルキャッシュにより、160テーブル超・900カラム超の総当たりスキャンでも 0.005秒〜0.15秒(200ms未満) で応答します。
  3. 1ツール・3モード統合 + 擬似相関除去 & 分析視点プロンプト付与
    • mode="pair"(指定ペア検証): 2つのテーブル・数値カラム間のピアソン相関係数 ($r$値)、決定係数 ($R^2$)、サンプル数 $n$、上位/下位5件、および回帰直線から最も離れた**「外れ値(異常値レコード5件・残差Zスコア付き)」**を正確に算出。
    • mode="find_drivers"(要因総当たりスキャン): 指定した1つの目的変数(例:公示地価、空き家率、売上など)に対し、共通キーで結合可能な他の全テーブル・全数値カラムを総当たりスキャンし、正の相関・負の相関が強い順にランキング形式で返却。
    • mode="serendipity"(未知の相関発掘): 分析テーマが決まっていない時の探索モード。異なるカテゴリのテーブル同士を掛け合わせ、偶然強い相関($|r| \ge 0.5$)や顕著な外れ値が出ている異種ペアを自動発掘。
    • normalize_by(任意): 人口(population)等で割った「1人あたり(Per Capita)」で正規化し、都市規模等による見せかけの相関(擬似相関)を除外。
    • include_perspective_prompts(デフォルト True): 算出された実データの外れ値名や相関係数を埋め込んだ4つの分析視点(外れ値の深掘り、逆因果・交絡因子の検討、最下位グループの共通点分析、次の検証アクション)をメタデータとして自動付与。
  4. 厳格なセキュリティ&サンドボックス設計
    • DuckDB 接続時は read_only=True および enable_external_access=false / lock_configuration=true を徹底し、単一 SELECT 文のみを許可。
    • ファイル出力時は Path.resolve() により指定ディレクトリ外のパストラバーサル(../)を厳格に検知・拒否し、ファイル削除機能は一切持ちません。
    • 外部由来のテキストはプロンプトインジェクション対策として ... データ境界タグで囲み、システム命令として解釈されないよう無害化します。

🛠 セットアップと LM Studio / Claude Desktop 登録方法

1. インストールと単体テストの実行

git clone https://github.com/japan-opendata-lab/correlation-discovery-mcp.git
cd correlation-discovery-mcp
pip install -e ".[dev]"
pytest -v

2. LM Studio (~/.lmstudio/mcp.json) への登録例

{
  "mcpServers": {
    "correlation-discovery-mcp": {
      "command": "python",
      "args": [
        "-X",
        "utf8",
        "./oss_mcp/correlation-discovery-mcp/server.py"
      ],
      "env": {
        "PYTHONIOENCODING": "utf-8",
        "DATA_SOURCE_DIR": "./data/platform_dist/global_megabank.duckdb;./data/dist"
      }
    }
  }
}

💡 任意の独自データで使いたい場合:
環境変数 DATA_SOURCE_DIR にご自身の .duckdb ファイルや .parquet / .csv が入ったフォルダパスを指定するだけで、共通ID列と数値カラムを自動検出して即座に分析可能です。


📊 出力サンプル (mode="pair")

{
  "status": "success",
  "mode": "pair",
  "join_key": "municipality_code",
  "aggregation": "AVG",
  "normalized_by": null,
  "pair": {
    "table_x": "demographics",
    "column_x": "capital_amount_jpy",
    "category_x": "demographics_population",
    "table_y": "land_prices_official",
    "column_y": "capital_amount_jpy",
    "category_y": "real_estate_housing"
  },
  "statistics": {
    "pearson_r": 0.7105,
    "r_squared": 0.5048,
    "sample_size_n": 1354,
    "regression_slope": 0.341285,
    "regression_intercept": -984120.5,
    "strength_interpretation": "strong_positive"
  },
  "top_5_records": [
    { "key": "13101", "label": "千代田区, 東京都", "x_value": 10065653.0, "y_value": 5495833.3333 },
    { "key": "13102", "label": "中央区, 東京都", "x_value": 7598445.0, "y_value": 5178378.3784 }
  ],
  "outliers": [
    {
      "key": "13102",
      "label": "中央区, 東京都",
      "x_value": 7598445.0,
      "y_value": 5178378.3784,
      "predicted_y": 1609114.2,
      "residual": 3569264.18,
      "residual_z_score": 14.82,
      "direction": "above_trend"
    }
  ],
  "perspective_prompts": [
    {
      "perspective": "outlier_anomaly_deep_dive",
      "title": "回帰外れ値(異常値レコード)の固有要因分析 / Outlier Deep-Dive",
      "prompt": "回帰直線から最も大きく乖離している筆頭外れ値 中央区, 東京都 (key=13102) に着目してください..."
    }
  ],
  "elapsed_seconds": 0.0052
}

🌐 関連エコシステム(Japan Open Data Lab)


License

MIT License — Copyright © 2026 Japan Open Data Lab ([email protected])

View this README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide

Configuration

{ "mcpServers": { "correlation-discovery-mcp": { "command": "python", "args": [ "-X", "utf8", "./oss_mcp/correlation-discovery-mcp/server.py" ], "env": { "PYTHONIOENCODING": "utf-8", "DATA_SOURCE_DIR": "./data/platform_dist/global_megabank.duckdb;./data/dist" } } } }