Dbecho について
dbechoはPostgreSQL分析向けのMCPサーバーです。AIエージェントを使う開発者やデータチームが、自然言語で複数のデータベースを探索・比較できます。読み取り専用クエリに加え、プロファイリング、トレンド、異常の分析を提供し、ローカルでstdio経由で動作します。
主な機能
- 01複数のPostgreSQLデータベースへの接続と比較
- 02スキーマ、関連、サンプル行の探索
- 03読み取り専用SQLの実行と実行計画の確認
- 04分布、トレンド、異常の分析
- 05データベースリソースとガイド用プロンプト
- 06タイムアウト、行数制限、機密値のマスキング
活用シーン
- 01環境間でクエリ結果を比較
- 02月次の登録数や売上の傾向を分析
- 03テーブルのNULL、外れ値、重複を確認
MCP 対応
クライアントによるデータベース探索と読み取り専用分析向けに、14個の分析ツール、3つのMCPリソース、3つのMCPプロンプトを提供します。stdio経由で動作し、複数のPostgreSQLデータベースに接続できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
dbecho
AI を通じて PostgreSQL データベースと対話できます。ダッシュボードも BI ツールも不要で、質問と回答だけです。
dbecho は、AI エージェント(Claude Code、Cursor、Windsurf、または任意の MCP クライアント)に PostgreSQL データベースへの読み取り専用アクセスを提供する MCP サーバーです。データベースを接続して、平易な言葉で質問すれば、すぐに分析結果を得られます。
You: What are my most popular blog posts and why?
Claude: [runs schema → query → analyze → trend across 29 tables]
Here's what the data shows...
何ができますか?
分析ワークフロー全体をカバーする14 個のツールがあります。
| ツール | 用途 |
|---|---|
list_databases | 接続されているすべてのデータベースを表示します |
health | 接続状態、PostgreSQL のバージョン、データベースのサイズを確認します |
schema | スキーマ全体を表示します:テーブル、カラム、型、主キー、行数、サイズ |
describe | 1 つのテーブルの詳細を表示します:カラム、主キー、インデックス、サイズ。schema より低コストです |
find | すべてのデータベースを一度に検索し、名前の部分一致でテーブルやカラムを特定します |
query | 読み取り専用 SQL(SELECT、WITH、EXPLAIN、SHOW)を実行します。オフセットによるページ分割と JSON 出力に対応しています |
explain | 推定コストと行数を含むクエリプランを表示し、実行前にクエリを評価できます |
analyze | テーブルをプロファイリングします:NULL、カーディナリティ、分布、上位の値 |
compare | 複数のデータベースで同じクエリを実行し、並べて比較します |
summary | テーブル数、合計行数、最大のテーブルの概要を表示します |
trend | 時系列データを日/週/月/年ごとにグループ化して件数や平均値を表示します。JSON 出力に対応しています |
anomalies | データ品質を確認します:NULL が多い値、外れ値、重複、未来の日付 |
sample | 任意のテーブルの行をプレビューします |
erd | エンティティ関係図を表示します:主キーと外部キー |
さらに、3 つの MCP リソース(データベースごとのスキーマ/概要)と、3 つの MCP プロンプト(ガイド付きの探索、データベース間の比較、データ品質監査)があります。
パーティション化されたテーブルは、子テーブルの集まりではなく親テーブルとして報告されます。
schema、find、summary、erd はパーティションの子テーブルを非表示にし、親に
[partitioned] のマークを付けます。また、パーティションツリー全体の行数の推定値とサイズを合算します(親テーブル自体にはデータが保存されないため、カタログの生データではデータベース内で最大のテーブルが空として表示されてしまいます)。親テーブルをクエリすれば、PostgreSQL がパーティションをプルーニングします。パーティション名を明示すれば、describe <child> は引き続き利用できます。
dbecho を選ぶ理由
問題: 複数のプロジェクトに PostgreSQL データベースがあります。答えを得るには、psql、pgAdmin、または BI ツールに切り替え、SQL を記述し、結果を整形してから、得られた知見を会話に持ち帰る必要があります。
解決策: dbecho は AI エージェントのワークフロー内で動作します。エージェントは会話を離れることなく、スキーマを調べ、SQL を記述し、テーブル間の情報を照合して分析を行います。設定ファイル 1 つで済み、コンテキストの切り替えは不要です。
エージェントに接続文字列を渡すだけの場合との違い:
- マルチデータベース対応。 1 つでも 20 個でもデータベースに接続できます。ツールを 1 回呼び出すだけで、データベース間を比較できます。
- デフォルトで安全。 読み取り専用接続、クエリのタイムアウト、行数制限、SQL インジェクション対策に対応しています。誤って
DROP TABLEを実行することはありません。 - エージェントに最適化された出力。 スキーマ、統計情報、クエリ結果は、生の psql ダンプではなく、LLM が効率よく解析できる形式で出力されます。
- インフラ不要。 コンテナも Web UI もバックグラウンドプロセスも必要ありません。stdio 経由で MCP を利用する Python パッケージです。
セッション例
You: Show me what's in the database
Claude: [calls list_databases → schema → summary]
Database: ecommerce (12 tables, 847 MB)
Largest: orders (2.1M rows), products (45K rows), users (128K rows)
You: How are sales trending this quarter?
Claude: [calls trend on orders table, grouped by week]
Week | orders | total_revenue
2026-01-06 | 3,241 | $482,100
2026-01-13 | 3,892 | $571,340
2026-01-20 | 2,107 | $298,500 ← 46% drop
...
Significant drop in week of Jan 20. Let me check what happened.
[calls query to investigate, then anomalies on orders table]
Found: 89% of orders that week have status='cancelled'.
The cancellation spike correlates with a payment gateway outage
(payments table shows 0 successful transactions Jan 19-21).
You: Any data quality issues I should worry about?
Claude: [calls anomalies on each table]
Found 4 issues:
- users.email: 342 possible duplicates
- orders.shipped_at: 127 dates in the future
- products.price: 23 outliers (IQR: $5..$89, found items at $0 and $9,999)
- events.user_id: 94.2% NULL (missing user attribution)
会話は 1 つだけで、コンテキストの切り替えは不要です。エージェントが適切なツールを自動的に選択します。
クイックスタート
1. インストール
pip install dbecho
ソースからインストールする場合:
git clone https://github.com/ginkida/dbecho.git
cd dbecho
pip install .
Python 3.10 以降と PostgreSQL 12 以降が必要です。
2. 設定する
プロジェクトディレクトリに dbecho.toml を作成します。
[databases.myapp]
url = "postgres://user:pass@localhost:5432/myapp"
description = "Main application"
[databases.analytics]
url = "postgres://user:pass@localhost:5432/analytics"
description = "Analytics warehouse"
[settings]
row_limit = 500 # max rows returned per query (default: 500)
query_timeout = 30 # seconds before query is killed (default: 30)
max_profile_rows = 5000000 # refuse analyze/anomalies above this row count
redact_sensitive = true # redact password/token/secret-like columns in output
環境変数は ${VAR} 構文で使用できます。
[databases.production]
url = "${DATABASE_URL}"
description = "Production (read replica)"
アプリがテーブルを public 以外に配置している場合は、schema を設定します(デフォルトは "public"、小文字の識別子です)。すべてのメタデータツール(schema、describe、analyze など)がこのスキーマを対象とし、search_path の先頭に配置されるため、生クエリでテーブル名を修飾せずに使用できます。
[databases.events]
url = "${EVENTS_DATABASE_URL}"
schema = "analytics"
MCP クライアントを接続する前に、設定と接続を検証します。
dbecho --check # validate config + ping every database
dbecho --version # print "dbecho <version>"
dbecho --help # usage and flags
--check はデータベースごとに [OK]/[FAIL] <name>: … の行を出力し、すべてのデータベースから応答があった場合にのみ 0 で終了します(それ以外は 0 以外で終了するため)、CI やヘルスチェックのスクリプトにそのまま組み込めます。
終了コード:0 は成功、1 は設定または起動の失敗(--check の失敗も含む)、2 は使用方法のエラーです。認識されない引数は無視されず、拒否されるため、--verison のようなタイプミスで、何もせずにサーバーが起動してしまうことはありません。
3. MCP クライアントに接続する
Claude Code(プロジェクトレベル、推奨):
プロジェクトのルートに .mcp.json を作成します。
{
"mcpServers": {
"dbecho": {
"command": "dbecho",
"args": ["--config", "/path/to/dbecho.toml"]
}
}
}
Claude Code(グローバル):
~/.claude.json に追加します。
{
"mcpServers": {
"dbecho": {
"command": "dbecho"
}
}
}
--config が指定されていない場合、dbecho は次の順に設定を検索します。
./dbecho.toml(現在のディレクトリ)~/.config/dbecho/config.toml~/.dbecho.toml
その他の MCP クライアント(Cursor、Windsurf など):クライアントの MCP サーバー設定で、同じコマンドと引数を使用します。
4. 質問する
Show me a summary of all my databases
How many users signed up each month this year?
Compare order counts between staging and production
Find data quality issues in the events table
What's the relationship between users, orders, and products?
Which columns have the most nulls?
Show me the trend of daily revenue for the last 90 days
エージェントが適切なツールを自動的に選択します。ツール名を知っておく必要はありません。
安全性
dbecho は、本番環境を含むあらゆるデータベースに接続しても安全なように設計されています。
- 読み取り専用接続。 すべての接続で、PostgreSQL レベルの
default_transaction_read_only=onを設定します。悪意のある SQL が作られた場合でも、データベースが書き込みを拒否します。 - クエリの許可リスト。 許可されるのは
SELECT、WITH、EXPLAIN、SHOW文のみです。さらに、バリデーターはデータを変更する CTE(WITH x AS (DELETE ...) SELECT ...)、SELECT INTO、書き込み文に対するEXPLAIN ANALYZEも個別に拒否するため、読み取り専用接続だけには頼りません。 - 禁止関数。 トランザクションが読み取り専用であっても、ファイルシステム、大規模オブジェクト、
dblink、set_configの各関数を拒否します。これらはデータ流出や制限回避に悪用されるおそれがあります。 - SQL インジェクションの防止。 すべてのテーブル名・カラム名の識別子には、
psycopg.sql.Identifier()によるパラメーター化を使用します。ユーザー入力は^[a-zA-Z_][a-zA-Z0-9_]*\Z($ではなく\Zを使用するため、末尾の改行文字で検証をすり抜けることはできません)に照らして検証されます。Identifier()の外に置かれる、識別子の形をした唯一の値は、データベースごとのschema設定オプションです。これは接続のsearch_pathに埋め込まれ、接続が作成される前の設定読み込み時に、同じ形式(小文字のみ)に照らして検証されます。 - クエリのタイムアウト。 デフォルトは 30 秒です。
statement_timeoutを使い、複数のクエリを実行するツール全体で共有される予算として適用します。また、すべての接続でセッションレベルのタイムアウトも予備的に設定します。 - 行数の上限。 クエリあたりのデフォルトは 500 行です。エージェントがテーブル全体をコンテキストに取り込むのを防ぎます。テーブル全体のプロファイリング(
analyze/anomalies)では、さらにmax_profile_rowsを超えるテーブルを拒否します。5,000 万行を超えるデータの正確な統計を低コストで取得することはできないため、ここでは拒否し、その上限を引き上げる設定名をメッセージに明記します。 - カラム数の上限。
analyze/anomaliesが調べるカラムは最大 80 個です(各カラムで個別にクエリが必要です)。それよりカラム数の多いテーブルは拒否せず、一部のみをプロファイリングします。プロファイルが完全に見えてしまうよりは、結果にスキップしたカラム数とその名前を必ず示すほうが適切です。 - 機密カラムの値のマスキング。 シークレットと思われるカラム(
password、token、api_key、secretなど)の値は、query/sample/analyzeの出力で<redacted>に置き換えられます(デフォルトで有効。無効にするにはredact_sensitive = falseを設定します)。これはカラム名に基づく被害軽減策であり、完全な封じ込めを保証するものではありません。queryは設計上、自由に読み取り可能な経路です。 - エラーのサニタイズ。 接続失敗は、
authentication failed、connection refusedなどの大まかな分類としてエージェントに報告されます。詳細はサーバーログにのみ記録されるため、ホスト名やユーザー名が会話に漏れることはありません。 - ローカルのみ。 ネットワーク呼び出しも、テレメトリーも、クラウドもありません。データはお使いのマシンから外に出ません。
本番データベースで最も安全性の高い構成は、引き続き最小権限のロールです。公開したいテーブル/ビューに対する SELECT 権限のみを持つ PostgreSQL ユーザーを使用してください。dbecho の各層は、操作ミスやプロンプトインジェクションを受けたエージェントから保護しますが、最終的な権限の決定権はデータベース自体の GRANT にあります。
アーキテクチャ
src/dbecho/
config.py TOML config loading, env var expansion, validation
db.py DatabaseManager: connections, SQL validation, schema, queries, stats, trends, anomalies
server.py FastMCP server: 14 tools, 3 resources, 3 prompts
Python のコードは合計約 2,700 行です。mcp と psycopg 以外にフレームワークは使用していません。
開発
git clone https://github.com/ginkida/dbecho.git
cd dbecho
pip install -e ".[dev]"
pytest -v
テストはすべてモックを使用しており、PostgreSQL のインスタンスは不要です。CI は Python 3.10~3.13 で実行されます。
coverage run --branch -m pytest -q
coverage report --show-missing --include='src/*'
テストスイートはサーバーに一切接続しないため、カタログレベルの SQL(パーティションツリー、pg_stat_user_tables の結合、インデックスの調査)は、取り込む前に使い捨てインスタンスに対して手動で確認してください。たとえば、次のように実行します。
docker run --rm -d -e POSTGRES_HOST_AUTH_METHOD=trust -p 55434:5432 postgres:16
その後、テスト用の dbecho.toml からそのインスタンスに接続します。モックで確認できるのは配線部分までです。クエリが正しいかを判断できるのは、実際のサーバーだけです。
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。