
japan-opendata-lab/correlation-discovery-mcp
Developer toolsSub-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 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:
- Hallucinated table/column names or syntax errors in complex SQL queries.
- Cartesian explosion (Many-to-Many JOIN traps) when joining entity-level tables with facility/transaction-level tables.
- Spurious correlations where variables appear correlated simply because of population or entity scale.
- 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.csvfiles inDATA_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=Trueand locks down the engine withenable_external_access=falseandlock_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.
- Connects to external DuckDB databases strictly with
✨ 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:
- MCP Companion Server:
japan-data-mcp— Search, inspect, and fetch normalized records across 162 official government datasets (Demographics, Official Land Prices, GEPS Procurement, Medical/DPC Hospitals, Vacant Houses, Renewable Energy, Crime/Safety, etc.). - Official Python SDK:
japan-official-data-megabank - Cloud API Hub (RapidAPI): Japan Official Data Megabank API on RapidAPI
- Sample Parquet Datasets (Hugging Face):
japan-opendata-lab/japan-official-data-megabank
Example Workflow: Local LLM (Qwen3-8B) + correlation-discovery-mcp + japan-data-mcp
- Discover Drivers (
find_drivers): Ask “What factors drive official land prices (land_prices_official) across Japanese municipalities?” →correlation-discovery-mcpscans 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$,demographicstaxable income $r=+0.71$) and negative drivers (surveillance_cameras$r=-0.77$,ski_resorts$r=-0.72$). - Inspect Regression Outliers (
pair): Verifydemographics(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σ). - Fetch Entity Details (
japan-data-mcp): Pass the discovered outliermunicipality_codetojapan-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スコアによる外れ値抽出)を書かせると、以下の課題が頻発します。
- カラム名・テーブル名のハルシネーションや複雑な SQL 構文エラー
- **多対多 JOIN による直積爆発(Cartesian Explosion)**と計算時間の肥大化
- **人口規模や企業規模による「見せかけの相関(擬似相関)」**の見落とし
- **外れ値(回帰直線から大きく外れた異常値レコード)**の算出漏れ
correlation-discovery-mcp は、これらの課題を単一の統合ツール discover_correlations で解決するオープンソースの高速統計探索エンジンです。
4大特徴
- スキーマ自動検出(ハードコード完全ゼロ)
- 接続先の DuckDB (
.duckdb) / Parquet (.parquet) / CSV (.csv) 群から、「結合可能な共通キー(municipality_code,prefecture,corporate_number,year, または任意の同名ID列)」と「数値型カラム」を動的に自動検出します。 - データセットが今後何百個増えても、また独自業務データ(売上・顧客・センサー・金融データ等)に差し替えても、コード変更ゼロで即座に自動対応します。
- 接続先の DuckDB (
- 0.2秒以内の超高速一括算出
- DuckDB のカラムナ集計とデータソース署名(SHA-256)に基づく自動ベクトルキャッシュにより、160テーブル超・900カラム超の総当たりスキャンでも 0.005秒〜0.15秒(200ms未満) で応答します。
- 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つの分析視点(外れ値の深掘り、逆因果・交絡因子の検討、最下位グループの共通点分析、次の検証アクション)をメタデータとして自動付与。
- 厳格なセキュリティ&サンドボックス設計
- DuckDB 接続時は
read_only=Trueおよびenable_external_access=false/lock_configuration=trueを徹底し、単一SELECT文のみを許可。 - ファイル出力時は
Path.resolve()により指定ディレクトリ外のパストラバーサル(../)を厳格に検知・拒否し、ファイル削除機能は一切持ちません。 - 外部由来のテキストはプロンプトインジェクション対策として
...データ境界タグで囲み、システム命令として解釈されないよう無害化します。
- DuckDB 接続時は
🛠 セットアップと 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)
japan-data-mcp: 日本の公的オープンデータ(全162データセット・1,150万件超)を自然言語・標準フィルタ・SQLで検索できる公式 MCP サーバーjapan-official-data-megabank: 公式 Python SDK & スターターキット- RapidAPI Hub — Japan Open Data Lab: クラウド API サブスクリプション(無料 BASIC プランあり)
- Hugging Face Datasets: サンプル Parquet データセット公開ページ
License
MIT License — Copyright © 2026 Japan Open Data Lab ([email protected])
Install
This server does not publish a one-line install command.
Open the repository installation guideConfiguration
{
"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"
}
}
}
}