A2db について
A2dbは、AIエージェントにPostgreSQL、SQLite、MySQL、Oracle、SQL Serverへの読み取り専用アクセスを提供するCLIおよびローカルMCPサーバーです。名前付きクエリの一括実行、スキーマ探索、簡潔なTSV結果、事前設定済み接続に対応します。
主な機能
- 015種類の対応データベースへのクエリ
- 021回の呼び出しで名前付きクエリを一括実行
- 03SQLGlot解析による読み取り専用SQLの強制
- 04詳細度を選べるテーブルと列の探索
- 05クエリメタデータ付きの簡潔なTSV出力
- 06環境変数による接続シークレットの管理
活用シーン
- 011回のエージェント要求で複数の分析クエリを実行
- 02クエリ前にデータベースのテーブルと列を確認
- 03エージェントに本番データの読み取りのみを許可
- 04自動化処理でCLIからデータベースを照会
MCP 対応
ローカルのstdio MCPサーバーとして動作し、接続管理、一括実行、スキーマ検索のツールをMCPクライアントに提供します。接続は起動時に登録でき、認証情報には環境変数参照を使用します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
🗄️ a2db
エージェントからデータベースへ
AI エージェントにデータベースへの安全な読み取り専用アクセスを提供します。1 回の呼び出しで複数のクエリを実行し、すっきりした結果を得られます。
5 種類のデータベース · バッチクエリ · 事前設定済みの接続 · SQLGlot による読み取り専用
クイックスタート · MCP ツール · セキュリティ · 比較 · セットアップ
Agent: "Show me active users and their recent orders"
↓
a2db execute → 2 queries, 1 call, structured results
↓
Agent: "Got it — 847 active users, avg order $42.50"
a2db を選ぶ理由
多くのデータベース MCP サーバーでは、クエリを一度に 1 つずつ実行し、呼び出しごとに接続情報を繰り返し指定する必要があり、結果は JSON 文字列内に二重エンコードされて返されます。a2db はこれらすべてを解決します。
- 事前設定済みの接続 —
--registerを使って.mcp.jsonでデータベースを定義すれば、エージェントはすぐにクエリを実行できます - バッチクエリ — 1 回のツール呼び出しで、名前付きの複数のクエリを実行できます
- デフォルト接続 — 接続を一度設定すれば、バッチ内のすべてのクエリで使用できます
- すっきりした出力 — コンパクトな TSV データとクエリごとの実行時間を含む、構造化された JSON エンベロープを返します(TSV を使う理由を参照)
- 読み取り専用を強制 — SQLGlot の AST 解析ですべての書き込み操作をブロックします
- すべてのドライバーを同梱 —
pip install a2dbを実行すれば完了です - シークレットは環境変数に保持 — DSN 内の
${DB_PASSWORD}は接続時にのみ展開されます
サポート対象のデータベース
| データベース | ドライバー | 非同期 |
|---|---|---|
| PostgreSQL | asyncpg | ネイティブ |
| SQLite | aiosqlite | ネイティブ |
| MySQL / MariaDB | mysql-connector-python | ラッパー |
| Oracle | oracledb | ラッパー |
| SQL Server | pymssql | ラッパー |
クイックスタート
pip install a2db
MCP サーバーとして(推奨)
Claude Code(事前設定済みの接続を使用):
claude mcp add -s user a2db -- a2db-mcp \
--register myapp/prod/main 'postgresql://user:${DB_PASSWORD}@host/mydb'
Claude Code(最小構成 — エージェントが必要に応じて login を呼び出します):
claude mcp add -s user a2db -- a2db-mcp
Claude Desktop / Cursor / 任意の MCP クライアント(.mcp.json):
{
"mcpServers": {
"a2db": {
"command": "uvx",
"args": [
"a2db-mcp",
"--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/mydb"
],
"env": {
"DB_PASSWORD": "your-password-here"
}
}
}
}
複数のデータベース:
{
"args": [
"a2db-mcp",
"--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/maindb",
"--register", "myapp/prod/analytics", "postgresql://user:${DB_PASSWORD}@host/analytics"
]
}
--register はサーバー起動時に接続を事前登録するため、エージェントはすぐにクエリを実行できます。パスワードには ${ENV_VAR} 構文を使用し、接続時に展開されます。平文で保存されることはありません。
CLI として
# Save a connection (validates immediately)
a2db login -p myapp -e prod -d main 'postgresql://user:${DB_PASSWORD}@localhost/mydb'
# Query
a2db query -p myapp -e prod -d main "SELECT * FROM users LIMIT 10"
# JSON output
a2db query -p myapp -e prod -d main -f json "SELECT * FROM users LIMIT 10"
# Explore schema
a2db schema -p myapp -e prod -d main tables
a2db schema -p myapp -e prod -d main columns -t users
# List / remove connections
a2db connections
a2db logout -p myapp -e prod -d main
MCP ツール
| ツール | 説明 |
|---|---|
login | 接続を保存します。最初に接続して検証します |
logout | 保存済みの接続を削除します |
list_connections | 接続を一覧表示します(シークレットは公開されません) |
execute | ページネーション付きで名前付きのバッチクエリを実行します |
search_objects | スキーマ(テーブル、列)を詳細レベルを指定して調べます |
execute — 中核となるツール
デフォルト接続を使う名前付きディクショナリ(推奨):
{
"connection": {"project": "myapp", "env": "prod", "db": "main"},
"queries": {
"active_users": {"sql": "SELECT id, name FROM users WHERE active = true"},
"recent_orders": {"sql": "SELECT id, total FROM orders ORDER BY created_at DESC LIMIT 5"}
}
}
リスト形式(q1、q2、... と自動で名前が付けられます):
{
"connection": {"project": "myapp", "env": "prod", "db": "main"},
"queries": [
{"sql": "SELECT COUNT(*) AS cnt FROM users"},
{"sql": "SELECT AVG(total) AS avg_order FROM orders"}
]
}
レスポンス(TSV 形式 — デフォルト):
{
"active_users": {
"data": "id\tname\n1\tAlice\n2\tBob\n3\tCharlie",
"rows": 3,
"truncated": false,
"time_ms": 12
},
"recent_orders": {
"data": "id\ttotal\n501\t129.00\n500\t49.99",
"rows": 2,
"truncated": false,
"time_ms": 8
}
}
::text によるキャストは不要です。整数、浮動小数点数、タイムスタンプ、配列、NULL はすべてそのまま使用できます。
エラーコンテキスト
クエリで列エラーが発生すると、a2db はエラーメッセージに情報を追加します。
column "nme" does not exist
Did you mean: name?
Available columns: id (integer), name (text), email (text), active (integer)
TSV を使う理由
LLM のコンテキストウィンドウは高コストです。JSON の行データは冗長で、各行で列名をすべて繰り返し、さらに中括弧、カンマ、引用符が追加されます。TSV はフラットなグリッドで、ヘッダー行の後はタブ区切りの値だけです。
100 行、5 列の結果セットの場合、TSV では通常、JSON の行形式と比べてトークン数を40~60%削減できます。構造化された JSON のエンベロープには引き続きメタデータ(行数、切り捨ての状態)が含まれ、TSV になるのは行のペイロードだけです。
各行に列名を含む完全な構造化出力が必要な場合は、format="json" を設定してください。
セキュリティ
読み取り専用の強制
すべてのクエリは、実行前に SQLGlot で解析されます。
- ブロック対象: INSERT、UPDATE、DELETE、DROP、TRUNCATE、ALTER、CREATE、GRANT、REVOKE
- 回避耐性: 複数ステートメント攻撃やコメントで囲まれた書き込みは、キーワード照合だけでなく AST レベルで検出されます
- 許可対象: SELECT、UNION、EXPLAIN、SHOW、DESCRIBE、PRAGMA
これは多層防御です。読み取り専用のデータベースユーザーも使用してください。ただし、ユーザーに書き込み権限があっても、a2db は書き込みを許可しません。
書き込みサポートはコアに実装されていますが、まだ MCP 経由では公開されていません。今後の予定:人間のオペレーターが明示的に有効にする、接続ごとの書き込み権限。TODO.md を参照してください。
認証情報の保存
接続情報は TOML ファイルとして ~/.config/a2db/connections/ に保存されます。
${DB_PASSWORD}構文 — 環境変数への参照はそのまま保存され、接続時にのみ展開されます。シークレットはディスク上ではなく、環境内に保持されます。- 一覧出力にシークレットなし —
list_connectionsでは、プロジェクト/環境/データベースとデータベースの種類が表示されます。DSN やパスワードは表示されません。 - 接続ファイルはローカルマシン上に保存され、リポジトリ内には置かれません。
デプロイの範囲
現在、a2db はローカル stdio MCP サーバーとして動作します。起動したプロセス(シェル、Claude Code、Docker)から環境変数を継承します。これはローカル MCP サーバーの標準的なモデルで、DBHub、Google Toolbox なども同じ方式を採用しています。
今後の予定: MCP 仕様に準拠した、OAuth 2.1 を使うリモート HTTP トランスポート。現時点では、Docker で実行する場合、コンテナの実行時に環境変数を使ってシークレットを渡してください。
比較
| 機能 | a2db | DBHub | Google Toolbox | PGMCP | Supabase MCP |
|---|---|---|---|---|---|
| データベース | 5(PG、SQLite、MySQL、Oracle、MSSQL) | 5(PG、MySQL、MSSQL、MariaDB、SQLite) | 40 以上(クラウド+OSS) | PG のみ | PG(Supabase) |
| バッチクエリ | 名前付き辞書+リスト | セミコロン区切り | なし | なし | なし |
| デフォルト接続 | 一度設定すればすべてに使用 | クエリごと | 該当なし | 単一 DB | 単一プロジェクト |
| 読み取り専用 | SQLGlot AST(強制) | キーワードチェック(設定) | ヒント/注釈 | 読み取り専用トランザクション+正規表現 | 設定フラグ |
| 書き込みサポート | 予定(接続ごと) | 設定フラグ | ツール定義経由 | なし | 設定フラグ |
| 出力 | JSON+TSV データ | 構造化テキスト | MCP プロトコル | テーブル/JSON/CSV | JSON |
| スキーマ検出 | 詳細度 3 段階 | 専用ツール | 事前構築済みツール | NL-to-SQL 経由 | 専用ツール |
| 事前設定 | MCP 設定で --register | 設定ファイル | YAML 設定 | 環境変数 | クラウド管理 |
| 認証情報 | DSN 内の ${ENV_VAR} | DSN 文字列 | 環境変数+GCP IAM | 環境変数 | OAuth 2.1 |
| 同梱ドライバー | すべて同梱 | すべて同梱 | 構成による | 組み込み | マネージド |
| CLI | あり | なし | あり | あり | なし |
| エラーコンテキスト | 列の候補+型 | なし | なし | なし | なし |
| ライセンス | Apache 2.0 | MIT | Apache 2.0 | Apache 2.0 | Apache 2.0 |
用途別の選び方:
- a2db — 出力が明快な複数 DB のバッチクエリ、エージェントファーストの設計、迅速なセットアップ
- DBHub — TOML 設定によるカスタムツール、ウェブワークベンチ UI
- Google Toolbox — GCP エコシステム、IAM 統合、40 以上のソース
- PGMCP — PostgreSQL 向け自然言語から SQL への変換(OpenAI キーが必要)
- Supabase MCP — Supabase プラットフォーム全体の管理(エッジ関数、ブランチ、ストレージ)
環境別のセットアップ
ローカル(macOS / Linux)
pip install a2db
# CLI
a2db login -p myapp -e dev -d main 'postgresql://user:pass@localhost/mydb'
# Or add as MCP server (see Quick Start)
Docker
FROM python:3.12-slim
RUN pip install a2db
CMD ["a2db-mcp", "--register", "myapp/prod/main", "postgresql://user:${DB_PASSWORD}@host/mydb"]
docker run -e DB_PASSWORD=secret -i my-a2db-image
シークレットは実行時に環境変数として注入されます。イメージに埋め込まれることはありません。
CI / 自動化
pip install a2db
# Pre-configured — no login needed
a2db-mcp --register myapp/ci/main "postgresql://ci_user:${CI_DB_PASSWORD}@db-host/mydb"
# Or use CLI directly
a2db login -p myapp -e ci -d main "postgresql://ci_user:${CI_DB_PASSWORD}@db-host/mydb"
a2db query -p myapp -e ci -d main "SELECT COUNT(*) FROM migrations"
開発
make bootstrap # Install deps + hooks
make check # Lint + test + security (full gate)
make test # Tests with coverage (90% minimum)
make lint # Lint only (never modifies files)
make fix # Auto-fix + lint
ライセンス
Apache 2.0
🗄️ 2025年から、エージェントファーストのデータベースアクセスを提供しています。
Denis Tomilin が開発
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。