Multi Database MCP Server について
Multi Database MCP Serverは、共通のMCPインターフェースを通じて、AIクライアントを複数のMySQL、PostgreSQL、SQLite、Oracle、TimescaleDBに接続します。SQL操作、スキーマ確認、トランザクション、性能分析用のツールをデータベースごとに生成し、安全制限も設定できます。
主な機能
- 01複数データベースへの同時接続
- 02データベース別ツールの自動生成
- 03SQLクエリとデータ変更
- 04トランザクションとスキーマ操作
- 05クエリ性能の分析
- 06読み取り専用、マスキング、タイムアウト制限
活用シーン
- 011つのクライアントから複数の設定済みDBを照会
- 02スキーマ確認とクエリ性能の分析
- 03書き込みとモデル結果の機密データを制限
MCP 対応
クエリ、ステートメント、トランザクション、スキーマ確認、性能分析のためのデータベース別ツールを提供するMCPサーバーです。クライアントはSTDIOまたは実験的なStreamable HTTPで接続でき、旧式のSSEは明示的な有効化が必要です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
マルチデータベース MCP サーバー
Model Context Protocol(MCP)を実装した強力なマルチデータベースサーバーです。AI アシスタントがデータベースに構造化された方法でアクセスできるようにします。
概要
DB MCP サーバーは、AI モデルが複数のデータベースと同時にやり取りするための標準化された方法を提供します。FreePeak/cortex フレームワークを基盤とし、統一されたインターフェースを通じて、AI アシスタントがさまざまなデータベースシステムで SQL クエリを実行し、トランザクションを管理し、スキーマを調査し、パフォーマンスを分析できるようにします。
コアコンセプト
マルチデータベース対応
従来のデータベースコネクターとは異なり、DB MCP サーバーは複数のデータベースに同時に接続し、やり取りできます。
{
"connections": [
{
"id": "mysql1",
"type": "mysql",
"host": "localhost",
"port": 3306,
"name": "db1",
"user": "user1",
"password": "password1"
},
{
"id": "postgres1",
"type": "postgres",
"host": "localhost",
"port": 5432,
"name": "db2",
"user": "user2",
"password": "password2"
},
{
"id": "oracle1",
"type": "oracle",
"host": "localhost",
"port": 1521,
"service_name": "XEPDB1",
"user": "user3",
"password": "password3"
}
]
}
動的なツール生成
接続された各データベースに対して、サーバーは専用のツールを自動的に生成します。
// For a database with ID "mysql1", these tools are generated:
query_mysql1 // Execute SQL queries
execute_mysql1 // Run data modification statements
transaction_mysql1 // Manage transactions
schema_mysql1 // Explore database schema
performance_mysql1 // Analyze query performance
クリーンアーキテクチャ
サーバーは、次のレイヤーで構成されるクリーンアーキテクチャの原則に従っています。
- ドメインレイヤー:コアとなるビジネスエンティティとインターフェース
- リポジトリレイヤー:データアクセスの実装
- ユースケースレイヤー:アプリケーションのビジネスロジック
- デリバリーレイヤー:外部インターフェース(MCP ツール)
機能
- 複数データベースの同時対応:複数の MySQL、PostgreSQL、SQLite、Oracle データベースに同時に接続
- 遅延読み込みモード:初回使用時まで接続の確立を延期します。10 以上のデータベースを使用する構成に最適です(
--lazy-loadingフラグで有効化) - データベース固有のツール生成:接続された各データベース向けの専用ツールを自動作成
- クリーンアーキテクチャ:関心事を明確に分離したモジュール設計
- OpenAI Agents SDK との互換性:シームレスな AI アシスタント連携を実現する完全な互換性
- 動的なデータベースツール:クエリの実行、ステートメントの実行、トランザクションの管理、スキーマの調査、パフォーマンスの分析
- 統一インターフェース:さまざまなデータベースタイプで一貫した操作パターンを提供
- 接続管理:複数のデータベース接続を簡単に設定
- ヘルスチェック:起動時にデータベースの接続状態を自動検証
- 本番環境向けの安全対策:データベースごとの
read_only適用(query_*とexecute_*の両方のツールで書き込みをブロック)、max_rowsによる結果の切り詰めと明示的な通知、クエリごとのタイムアウト
本番環境向けガードレール
暴走するクエリや誤った書き込みからエージェントセッションを保護します。
| 設定 | スコープ | 効果 |
|---|---|---|
"read_only": true | データベースごと | クエリツールと実行ツールの両方を通じた書き込みステートメント(INSERT、UPDATE、DELETE、DDL、データを変更するCTE、連続した書き込み)をブロックし、PostgreSQL/TimescaleDB(default_transaction_read_only=on)およびMySQL(transaction_read_only=1)ではデータベースエンジン自体でも拒否を強制します。SQLiteはmode=roで開きます。分類時にはコメントと文字列リテラルを除去し、認識できないステートメントはデフォルトで拒否します。 |
"max_rows": 1000 | データベースごと | 結果セットをN行で切り捨て、明示的な[Truncated]通知を追加します。これにより、モデルはコンテキストを失うのではなく、クエリを絞り込む必要があるとわかります。0(デフォルト)は無制限を意味します。 |
"masking_rules": [...] | データベースごと | サーバーから送信する前に、ルールの正規表現に名前が一致する結果列の値をマスキングします。SELECT *を含むあらゆる形式のクエリに適用されます。方式は"fixed_string"(valueに置き換え)、"null"、および"partial"(末尾のkeep_last文字を表示し、それより短い値はすべてマスキング)です。最初に一致したルールが適用されます。無効なパターンや不明な方式がある場合、設定の読み込みを中止します(フェイルクローズ)。マスキングされたセル数は結果のフッターに報告されます。列名をエイリアスで変更すると、設計上、名前による一致を回避できます。docs/design/column-masking-scoping.mdを参照してください。 |
"mask_pii": true | データベースごと | 列名だけでなく、コンテンツの形式に基づいてクエリ結果のPIIを秘匿します。メールアドレス、電話番号、クレジットカード番号(Luhnアルゴリズムで検証)、SSN、IPv4アドレス、19桁以上の識別子を、ルールでカバーされないフリーテキスト列の中も含め、出現箇所すべてで[EMAIL]/[PHONE]/[CREDIT_CARD]/[SSN]/[IP_ADDRESS]/[LONG_NUMBER]に置き換えます。email/card_number/ibanなどの列名は、列全体が秘匿されます。オペレーターが制御します。一度設定すると、エージェントはこれを無効にできません(クエリ単位のmask_piiパラメーターで追加することはできますが、解除はできません)。masking_rulesと組み合わせて使用できます。 |
"query_timeout": 30 | データベースごと | タイムアウト(秒)を超えたステートメントをキャンセルします。すべてのツール(クエリ、ステートメント、トランザクション、説明、スキーマ検査)に対し、リポジトリ層で適用されます。未設定時はデフォルトで30秒です。-1で無効になります。環境変数のみで設定するデプロイでは、明示的な値のない接続にQUERY_TIMEOUT_SECONDSを設定できます(JSONが優先されます)。 |
| DB_MCP_AUDIT_LOG=/path/audit.jsonl | プロセス | 実行したステートメントごとに、タイムスタンプ、操作(query/execute/tx_*)、データベース、ステートメント(最大10k文字)、所要時間、エラーを含むJSONLレコードを追記します。読み取り専用データベースに対する拒否された試行も記録します。ベストエフォートの書き込みのため、クエリが失敗することはありません。ファイルは0600で作成されます。 |
多層防御:読み取り専用は、アプリケーションの分類器、エンジンのセッションデフォルト、そして(推奨される)最小権限のデータベースユーザーという3つの層で適用されます。Oracleでは現在、分類器とユーザー権限に依存しています。
対応データベース
| データベース | ステータス | 機能 |
|---|---|---|
| MySQL | ✅ 完全サポート | クエリ、トランザクション、スキーマ分析、パフォーマンス分析 |
| PostgreSQL | ✅ 完全サポート(v9.6-17) | クエリ、トランザクション、スキーマ分析、パフォーマンス分析 |
| SQLite | ✅ 完全サポート | ファイルベースおよびインメモリのデータベース、SQLCipherの暗号化に対応 |
| Oracle | ✅ 完全サポート(10g-23c) | クエリ、トランザクション、スキーマ分析、RAC、クラウドウォレット、TNS |
| TimescaleDB | ✅ 完全サポート | 時系列クエリ、ハイパーテーブルの検出(書き込みポリシーはSQL経由) |
デプロイとトランスポートの状況
最も安全なローカル統合方式はSTDIOです。HTTPトランスポートは引き続き強化中のため、現在のサーバーを共有ネットワークに直接公開しないでください。
個人/ローカルの STDIO(推奨)
# Build from the audited source revision
make build
# Use a private, single-connection config
./bin/server -t stdio -c /absolute/path/to/config.local.json
Cursor では、実際のビルド出力をクライアントに指定し、絶対パスを使用してください。
{
"mcpServers": {
"local-db": {
"command": "/absolute/path/to/db-mcp-server/bin/server",
"args": ["-t", "stdio", "-c", "/absolute/path/to/config.local.json"]
}
}
}
個人用の PostgreSQL/MySQL 接続には、読み取り専用のデータベースアカウントと上限を設定した query_timeout を使用してください。SQLite では、エージェントがデータの確認のみを行う場合、絶対パスの database_path と "read_only": true を使用してください。
レガシー SSE(互換性のためのみ)
従来の Cortex SSE トランスポートには、組み込みの認証機能がありません。デフォルトでは無効になっており、信頼できるプライベートリバースプロキシの背後で、明示的に有効化した場合に限り使用してください。
./bin/server -t sse -h 127.0.0.1 -p 9092 \
-allow-insecure-sse -c /absolute/path/to/config.local.json
共有デプロイでは、このモードを使用しないでください。レガシーエンドポイントでは DB_MCP_API_KEY は適用されません。TLS、認証、ネットワークポリシーはプロキシで終端してください。今後のリリースでは、保守されている Streamable HTTP 実装に置き換える予定です。
Streamable HTTP(実験的)
streamable エンドポイントは、保守されている Go MCP SDK を基盤としており、ステートフルセッション、JSON または SSE レスポンス、通知、GET/DELETE によるセッションライフサイクル、JSON-RPC ディスパッチをサポートしています。このプロセスは DB_MCP_API_KEY が設定されていないと起動しません。認証と適合性の展開が完了するまでは、プライベート TLS ゲートウェイの背後に配置してください。
ブラウザーからのリクエストには、カンマ区切りの許可リストを明示的に設定してください。
MCP_ALLOWED_ORIGINS=https://agent.example.com
組み込みの静的ベアラーキーは、範囲を限定したパイロット用の仕組みです。デフォルトでは db:read が許可されます。DB_MCP_API_SCOPES=db:read,db:write は、信頼できる書き込みクライアントに対してのみ設定してください。db:admin は、管理を制御された環境で行う場合に限り使用します。共有デプロイでは、OIDC ディスカバリー、JWKS 署名検証、発行者/オーディエンスの確認、サブジェクト ID を使用するために DB_MCP_OIDC_ISSUER と DB_MCP_OIDC_AUDIENCE を設定してください。データベース固有のスコープは、ポリシーが定義されるまで、意図的に有効化されていません。
Docker 開発用イメージ
公開されているイメージは、開発/デモ用の成果物であり、エンタープライズ向けのセキュリティ強化を推奨するものではありません。現在の Dockerfile は非特権ユーザーで実行され、組み込みの設定を含まず、ローカル Compose との互換性のためにレガシーな -allow-insecure-sse の動作を含んでいます。別個のヘルスポート(9093)を公開しており、一般公開には適していません。
# Build a local image from this source revision
docker build -t db-mcp-server:local .
# Keep it private; the image's default SSE mode is compatibility-only
docker run --rm -p 127.0.0.1:9092:9092 \
-p 127.0.0.1:9093:9093 \
-v "$(pwd)/config.local.json:/app/config.json:ro" \
db-mcp-server:local
チームでデプロイする場合は、認証付き Streamable トランスポートの提供を待ち、プライベートネットワーク、外部シークレットストア、TLS/OIDC ゲートウェイを備えた、非 root かつ読み取り専用ファイルシステムのイメージを使用してください。
ソースコードからのインストール
# Clone the repository
git clone https://github.com/FreePeak/db-mcp-server.git
cd db-mcp-server
# Build the server
make build
# Run the server
./bin/server -t stdio -c config.json
設定
データベース設定ファイル
データベース接続を記述した config.json ファイルを作成してください。schema_version: 1 を指定すると、未定義フィールドの厳密な検証が有効になります。
{
"schema_version": 1,
"connections": [
{
"id": "mysql1",
"type": "mysql",
"host": "mysql1",
"port": 3306,
"name": "db1",
"user": "user1",
"password_env": "DB_MCP_MYSQL_PASSWORD",
"query_timeout": 60,
"max_open_conns": 20,
"max_idle_conns": 5,
"conn_max_lifetime_seconds": 300,
"conn_max_idle_time_seconds": 60,
"read_only": false,
"max_rows": 1000,
"masking_rules": [
{ "pattern": "(?i)email", "strategy": "fixed_string", "value": "***MASKED***" },
{ "pattern": "(?i)(ssn|tax_id)", "strategy": "null" }
]
},
{
"id": "postgres1",
"type": "postgres",
"host": "postgres1",
"port": 5432,
"name": "db1",
"user": "user1",
"password_env": "DB_MCP_POSTGRES_PASSWORD"
},
{
"id": "sqlite_app",
"type": "sqlite",
"database_path": "./data/app.db",
"journal_mode": "WAL",
"cache_size": 2000,
"read_only": false,
"use_modernc_driver": true,
"query_timeout": 30,
"max_open_conns": 1,
"max_idle_conns": 1
},
{
"id": "sqlite_encrypted",
"type": "sqlite",
"database_path": "./data/secure.db",
"encryption_key": "your-secret-key-here",
"journal_mode": "WAL",
"use_modernc_driver": false
},
{
"id": "sqlite_memory",
"type": "sqlite",
"database_path": ":memory:",
"cache_size": 1000,
"use_modernc_driver": true
}
]
}
シークレット参照
本番環境の認証情報を JSON に直接記述しないでください。接続ごとに、環境変数名またはマウントされたシークレットファイルを使用してください。
{
"id": "prod",
"type": "postgres",
"host": "db.internal",
"port": 5432,
"name": "app",
"user": "mcp_reader",
"password_env": "DB_MCP_PROD_PASSWORD"
}
password_file と encryption_key_env/encryption_key_file もサポートされています。相対ファイルパスは設定ファイルのディレクトリを基準に解決されます。インライン値と参照は併用できません。解決された値はプロセスメモリ内に保持され、設定ローダーによって出力されることはありません。
コマンドラインオプション
# Basic syntax
./bin/server -t <transport> -c <config-file>
# HTTP transport options (legacy SSE requires an explicit opt-in)
./bin/server -t sse -h <hostname> -p <port> -allow-insecure-sse -c <config-file>
# Lazy loading mode (recommended for 10+ databases)
./bin/server -t stdio -c <config-file> --lazy-loading
# Customize log directory (useful for multi-project setups)
./bin/server -t stdio -c <config-file> -log-dir /tmp/db-mcp-logs
# Inline database configuration
./bin/server -t stdio -db-config '{"connections":[...]}'
# Environment variable configuration
export DB_CONFIG='{"connections":[...]}'
./bin/server -t stdio
# Print the build version
./bin/server --version
# Upgrade to the latest published release (verifies SHA-256, swaps the binary)
./bin/server update
./bin/server update -check # only report whether a newer release exists
./bin/server update -version 1.13.0 # install a specific release
利用可能なフラグ:
-t, -transport:トランスポートモード(stdio、レガシーのsse、または実験的なstreamable)-c, -config:データベース設定ファイルへのパス-p, -port:HTTP ポート(デフォルト:9092)-h, -host:HTTP バインドホスト(デフォルト:127.0.0.1)--version:ビルドバージョンを表示して終了します-allow-insecure-sse:プライベートな開発用プロキシでレガシー SSE を明示的に許可します-api-key:実験的な Streamable HTTP エントリーポイント用のベアラーキー(またはDB_MCP_API_KEYを使用)-log-level:ログレベル(debug、info、warn、error)-log-dir:ログファイル用ディレクトリ(デフォルト:カレントディレクトリの./logs)-db-config:インライン JSON データベース設定-lazy-loading:初回使用時に接続を確立します-unified-tools:databaseパラメーターを持つ単一のツールセットを登録します
更新: db-mcp-server update は最新の GitHub リリースを取得し、リリースの SHA256SUMS マニフェストとダウンロードファイルを照合してから、実行中のバイナリをその場で置き換えます(検証に失敗した場合、以前のバイナリは変更されません)。お使いの OS とアーキテクチャに一致するアセットがインストールされます。完了後、サーバーを再起動してください。Windows では実行中の実行ファイルを置き換えられないため、npm インストーラーを使って更新してください。-check はダウンロードせずに結果を報告し、-force は現在のバージョンを再インストールします。
環境変数
.env ファイルの値が最初に読み込まれ、実際の環境変数が優先されます。JSON 設定ファイル(CONFIG_PATH/DB_CONFIG_FILE)は、インラインおよび従来のデータベース変数より優先されます。
| 変数 | デフォルト | 用途 |
|---|---|---|
CONFIG_PATH / DB_CONFIG_FILE | config.json | 複数データベース用 JSON 設定ファイルへのパス |
DB_CONFIG | — | インライン JSON データベース設定(ファイルがない場合に使用) |
TRANSPORT_MODE | stdio | -t が指定されていない場合のトランスポートモード |
SERVER_PORT | 9092 | HTTP ポート |
MCP_ALLOWED_ORIGINS | 空 | 実験的な Streamable HTTP が許可する、カンマ区切りのブラウザーオリジン |
DB_MCP_API_KEY | 空 | 実験的な Streamable HTTP 用のベアラーキー。シークレットマネージャーに保管してください |
DB_MCP_API_SCOPES | db:read | 必須/付与するスコープ:db:read、db:write、および/または db:admin |
DB_MCP_OIDC_ISSUER | 空 | OIDC 発行者 URL。設定すると、静的なパイロットキーの代わりに OIDC/JWT 検証が使用されます |
DB_MCP_OIDC_AUDIENCE | 空 | 必須の OIDC オーディエンス/クライアント ID |
LOG_LEVEL | info | ログの詳細度(debug、info、warn、error) |
DISABLE_LOGGING | false | true/1 にすると、ログを完全に無効にします |
DB_TYPE、DB_HOST、DB_PORT、DB_USER、DB_PASSWORD、DB_NAME | エンジンのデフォルト値 | JSON 設定がない場合の単一データベース用フォールバック |
QUERY_TIMEOUT_SECONDS | 未設定 | 独自の query_timeout が設定されていない接続に値を設定します。負の値を指定すると上限が無効になります。JSON 設定が優先されます。 |
DB_MCP_AUDIT_LOG | 未設定 | オプションの追記専用 JSONL 監査ログのパス |
VERBOSE | 未設定 | true/1 にすると、起動時のログレベルが debug に設定されます(デフォルトは error で、LOG_LEVEL が設定されていない限り出力されません) |
MCP_DISABLE_LOGGING | 未設定 | true/1 にすると、MCP プロトコルログを破棄します(LOG_LEVEL/DISABLE_LOGGING とは独立したライターレベルの切り替え) |
SQLite の設定オプション
SQLite データベースを使用する場合は、次の追加設定オプションを利用できます:
SQLite 接続パラメーター
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
database_path | string | 必須 | SQLite データベースファイルへのパス。インメモリの場合は :memory: |
encryption_key | string | - | SQLCipher 暗号化データベース用のキー |
read_only | boolean | false | データベースを読み取り専用モードで開きます |
max_rows | integer | 無制限 | クエリごとに返す最大行数。上限を超える結果は、明示的な通知とともに切り詰められます。すべてのデータベースタイプで機能します |
cache_size | integer | 2000 | SQLite のキャッシュサイズ(ページ数) |
journal_mode | string | "WAL" | ジャーナルモード:DELETE、TRUNCATE、PERSIST、WAL、OFF |
use_modernc_driver | boolean | true | modernc.org/sqlite(CGO 不要)または mattn/go-sqlite3 を使用します |
SQLite の例
基本的なファイルデータベース
{
"id": "my_sqlite_db",
"type": "sqlite",
"database_path": "./data/myapp.db",
"journal_mode": "WAL",
"cache_size": 2000
}
暗号化データベース(SQLCipher)
{
"id": "encrypted_db",
"type": "sqlite",
"database_path": "./data/secure.db",
"encryption_key": "your-secret-encryption-key",
"use_modernc_driver": false
}
インメモリデータベース
{
"id": "memory_db",
"type": "sqlite",
"database_path": ":memory:",
"cache_size": 1000
}
読み取り専用データベース
{
"id": "reference_data",
"type": "sqlite",
"database_path": "./data/reference.db",
"read_only": true,
"journal_mode": "DELETE"
}
Oracle の設定オプション
Oracle データベースを使用する際は、以下の追加設定オプションを活用できます。
Oracle 接続パラメーター
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
host | string | 必須 | Oracle データベースのホスト |
port | integer | 1521 | Oracle リスナーポート |
service_name | string | - | サービス名(RAC では推奨) |
sid | string | - | システム識別子(レガシー。代わりに service_name を使用してください) |
user | string | 必須 | データベースのユーザー名 |
password | string | 必須 | データベースのパスワード |
wallet_location | string | - | Oracle Cloud ウォレットディレクトリへのパス |
tns_admin | string | - | tnsnames.ora を含むディレクトリへのパス |
tns_entry | string | - | tnsnames.ora の名前付きエントリー |
edition | string | - | エディションベースの再定義におけるエディション名 |
pooling | boolean | false | ドライバーレベルの接続プーリングを有効にします |
standby_sessions | boolean | false | スタンバイデータベースでのクエリを許可します |
nls_lang | string | AMERICAN_AMERICA.AL32UTF8 | 文字セットの設定 |
Oracle の例
基本的な Oracle 接続(開発)
{
"id": "oracle_dev",
"type": "oracle",
"host": "localhost",
"port": 1521,
"service_name": "XEPDB1",
"user": "testuser",
"password": "testpass",
"max_open_conns": 50,
"max_idle_conns": 10,
"conn_max_lifetime_seconds": 1800
}
SID を使用した Oracle 接続(レガシー)
{
"id": "oracle_legacy",
"type": "oracle",
"host": "oracledb.company.com",
"port": 1521,
"sid": "ORCL",
"user": "app_user",
"password": "app_password"
}
Oracle Cloud Autonomous Database(ウォレットを使用)
{
"id": "oracle_cloud",
"type": "oracle",
"user": "ADMIN",
"password": "your-cloud-password",
"wallet_location": "/path/to/wallet_DBNAME",
"service_name": "dbname_high"
}
Oracle RAC(Real Application Clusters)
{
"id": "oracle_rac",
"type": "oracle",
"host": "scan.company.com",
"port": 1521,
"service_name": "production",
"user": "app_user",
"password": "app_password",
"max_open_conns": 100,
"max_idle_conns": 20
}
TNS エントリーを使用した Oracle 接続
{
"id": "oracle_tns",
"type": "oracle",
"tns_admin": "/opt/oracle/network/admin",
"tns_entry": "PROD_DB",
"user": "app_user",
"password": "app_password"
}
エディションベースの再定義を使用した Oracle 接続
{
"id": "oracle_ebr",
"type": "oracle",
"host": "oracledb.company.com",
"port": 1521,
"service_name": "production",
"user": "app_user",
"password": "app_password",
"edition": "v2_0"
}
Oracle 接続文字列の優先順位
複数の接続方法が設定されている場合、以下の優先順位が適用されます。
- TNS エントリー(
tns_entryとtns_adminが設定されている場合) - ウォレット(
wallet_locationが設定されている場合)- Oracle Cloud 用 - 標準(host:port/service_name)- デフォルトの方法
利用可能なツール
接続された各データベースに対して、DB MCP Server は以下の専用ツールを自動的に生成します。
クエリツール
| ツール名 | 説明 |
|---|---|
query_<db_id> | SELECT クエリを実行し、結果を表形式のデータセットとして取得します。任意の mask_pii ブール値を指定すると、コンテンツの形式に基づいて PII をマスキングします(ガードレールの表を参照)。この設定は追加で適用されます。つまり、データベースに "mask_pii": true が設定されている場合は、常にマスキングされます。 |
execute_<db_id> | データ操作ステートメント(INSERT、UPDATE、DELETE)を実行します。任意の dry_run ブール値を指定すると、ステートメントの種類、リスクレベル、注意事項をオフラインで分類し、何も実行しません。実行される破壊的なステートメントの結果には ⚠ Risk notice が含まれます。 |
transaction_<db_id> | トランザクションを開始、コミット、ロールバックします。取り消し操作として list_snapshots と rollback_snapshot(snapshot_id を指定)も利用できます。execute_<db_id> を通じて実行されるすべての DELETE/UPDATE では、影響を受ける行の変更前スナップショットが記録されます。これはベストエフォートで行われ、データベースごとに直近 25 件まで保持され、結果にその ID が報告されます。 |
スキーマツール
| ツール名 | 説明 |
|---|---|
schema_<db_id> | テーブル、カラム、インデックス、外部キーに関する情報を取得します |
generate_schema_<db_id> | データベーススキーマから SQL またはコードを生成します |
パフォーマンスツール
| ツール名 | 説明 |
|---|---|
performance_<db_id> | アクションを通じてクエリのパフォーマンスを分析します:stats / slow_queries(プロセス内トラッカー)、engine_slow_queries(pg_stat_statements / MySQL のダイジェストテーブル / Oracle v$sqlarea)、suggest(静的 SQL リント)、suggest_indexes(単一のステートメントに対するヒューリスティックな CREATE INDEX の提案、等価条件優先の複合インデックス。EXPLAIN で検証してください)、validate_suggestions(PostgreSQL:hypopg 拡張機能を使用し、同じ提案をコストのかからない仮想インデックスとしてインストールして、プランナーが実際に各インデックスを選択するか報告します。手動 EXPLAIN ではなく、実際の結果で検証します)、workload_suggestions(実行回数で重み付けし、コストの高い上位 N 件のワークロードステートメントを同様に分析します)、index_health(カタログから重複/冗長/未使用/無効なインデックスとテーブルの肥大化を検出します。エンジン統計がある場合は使用状況の根拠も示します)、db_health(index_health のすべての内容に加え、max_connections に対する接続負荷の使用率を示します)、reset |
explain_<db_id> | SQL ステートメントを実行せずに実行計画を表示します。analyze: true を指定すると、タイミング/バッファー統計を取得するために実行します(PostgreSQL/MySQL)。読み取り専用データベースでは書き込みは引き続きブロックされます |
describe_<db_id> | エンジンのカタログクエリを使って、1 つのテーブルのカラム、インデックス、行数の推定値を調べます |
health_<db_id> | 接続状態、ping のレイテンシー、接続プールの状態、エンジン統計(PostgreSQL のバッファーキャッシュヒット率、MySQL InnoDB のバッファー効率)を報告します |
TimescaleDB ツール
timescaledb 拡張機能がインストールされている PostgreSQL データベースでは、起動時に次の専用ツールも自動登録されます(登録は設定に基づいて行われるため、--lazy-loading でも動作します。各ハンドラーは呼び出し時に拡張機能を確認し、存在しない場合は対処方法を示すエラーを返します)。
| ツール名 | 説明 |
|---|---|
timescaledb_timeseries_query_<db_id> | 時間バケット化(time_bucket)、フィルタリング、ウィンドウ関数を使って最適化された時系列クエリを実行します |
timescaledb_analyze_timeseries_<db_id> | 1 つのテーブル/カラムの時系列パターン(トレンド、季節性の概要)を分析します |
timescaledb_list_hypertables_<db_id> | 時間カラムとディメンション数とともにハイパーテーブルを一覧表示します(読み取り専用) |
timescaledb_compression_settings_<db_id> | ハイパーテーブルの圧縮設定を表示します(読み取り専用) |
timescaledb_retention_policy_<db_id> | 設定済みの保持ポリシーを表示します(読み取り専用) |
timescaledb_list_continuous_aggregates_<db_id> | バケット間隔と更新ポリシーを含め、連続集約を一覧表示します(読み取り専用) |
timescaledb_continuous_aggregate_info_<db_id> | 1 つの連続集約の詳細を調べます(読み取り専用) |
統合モードでは、同じ 7 つのツールが timescaledb_timeseries_query、timescaledb_analyze_timeseries、timescaledb_list_hypertables、timescaledb_compression_settings、timescaledb_retention_policy、timescaledb_list_continuous_aggregates、timescaledb_continuous_aggregate_info としてそれぞれ 1 回ずつ表示され、各ツールで必須の database パラメーターを指定します。
対象範囲に関する注意:上記の読み取り専用の探索はクエリパイプラインを通るため、
read_onlyデータベースでも引き続き利用できます。各ハンドラーは最初にtimescaledb拡張機能を確認します。書き込みポリシーに関する操作(ハイパーテーブルの作成、圧縮の切り替え、保持ポリシーや更新ポリシーの追加/削除)は公開されていません。現時点では、クエリ/実行ツールを使って通常の SQL を実行してください。詳しいドキュメントについては、TIMESCALEDB_TOOLS.md を参照してください。
統合ツールモード
多数のデータベース(5 つ以上)に接続すると、データベースごとにツール名を付けることで、ツール数が大量に増加します(5 × N)。一部の MCP クライアント、特に Claude では、ツールの総数とツールの説明のサイズに厳しい上限が設けられているため、エージェントがサーバーを読み込めない、ツールを無視する、またはツールの呼び出しを拒否するといった問題が発生することがあります。Issue #18 には、まさにこの症状が記録されています。「db-mcp-server は OpenAI では問題なく動作するのに、Claude では正常に動作しない」。
これらのクライアントでは、サーバーを --unified-tools フラグ付きで起動すると、データベースごとのツールの代わりに、統合された 6 つのツール(query、execute、transaction、performance、explain、describe、schema、filter_tables)が登録されます。
./bin/server -t stdio -c config.json --unified-tools
**コンテキストウィンドウのコスト(測定済み、TestToolTokenBenchmark、scripts/token-benchmark.sh により 2026-08 に再検証):**統合モードのコストは、接続するデータベース数にかかわらず約 1.25~1.6k トークンです。一方、データベースごとのモードではデータベース 1 つあたり約 800 トークン(ツール 7 個)となり、データベースを 10 個接続すると約 8k トークンになります。統合モードでは、ワイヤーペイロードを 80%削減できます。データベースが 1 つだけの場合は、データベースごとの命名のほうがわずかに効率的ですが、データベースが 2 つ以上になると統合モードが有利になり、その後も一定のコストで拡張できます。scripts/token-benchmark.sh を使って、実際のワイヤーペイロードを再測定してください。測定方法と結果は docs/benchmark-token-efficiency.md を参照してください。
In unified mode, each tool accepts a required `database` parameter that names
which database the call should target. See the [Configuration](#configuration)
section for the full list of available databases. This dramatically reduces the
tool count and the cumulative description size, which resolves the Claude
compatibility issues.
For very large configurations, also enable `--lazy-loading` so that startup
doesn't open connections to databases that may never be queried during the
session.
## Examples
### Querying Multiple Databases
```sql
-- Query the MySQL database
query_mysql1("SELECT * FROM users LIMIT 10")
-- Query the PostgreSQL database in the same context
query_postgres1("SELECT * FROM products WHERE price > 100")
-- Query the SQLite database
query_sqlite_app("SELECT * FROM local_data WHERE created_at > datetime('now', '-1 day')")
-- Query the Oracle database
query_oracle_dev("SELECT * FROM employees WHERE hire_date > SYSDATE - 30")
トランザクションの管理
transaction_<db_id> ツールは、begin、execute、commit、rollback の各アクションをサポートしています。各 begin は transactionId を返します。これを渡してステートメントを準備し、コミットまたはロールバックします。
// 1. Start a transaction
{ "action": "begin" }
// → { "transactionId": "tx_mysql1_1730000000000000000" }
// 2. Execute statements within the transaction
{
"action": "execute",
"transactionId": "tx_mysql1_1730000000000000000",
"statement": "INSERT INTO orders (customer_id, product_id) VALUES (1, 2)"
}
// 3a. Commit — persists all staged statements
{ "action": "commit", "transactionId": "tx_mysql1_1730000000000000000" }
// 3b. OR rollback — discards all staged statements
{ "action": "rollback", "transactionId": "tx_mysql1_1730000000000000000" }
不明なトランザクション ID や、すでに無効になったトランザクション ID を指定すると、成功したように見える応答ではなく、明確なエラーが返されます。これにより、エージェントは失われたトランザクションを検出し、復旧できます。
データベーススキーマの確認
-- Get all tables in the database
schema_mysql1("tables")
-- Get columns for a specific table
schema_mysql1("columns", "users")
-- Get constraints
schema_mysql1("constraints", "orders")
SQLite 固有の機能の使用
-- Create a table in SQLite
execute_sqlite_app("CREATE TABLE IF NOT EXISTS local_cache (key TEXT PRIMARY KEY, value TEXT, timestamp DATETIME)")
-- Use SQLite-specific date functions
query_sqlite_app("SELECT * FROM events WHERE date(created_at) = date('now')")
-- Query SQLite master table for schema information
query_sqlite_app("SELECT name, sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
-- Performance optimization with WAL mode
execute_sqlite_app("PRAGMA journal_mode = WAL")
execute_sqlite_app("PRAGMA synchronous = NORMAL")
Oracle 固有の機能の使用
-- Query user tables (excludes system schemas)
query_oracle_dev("SELECT table_name FROM user_tables ORDER BY table_name")
-- Use Oracle-specific date functions
query_oracle_dev("SELECT employee_id, hire_date FROM employees WHERE hire_date >= TRUNC(SYSDATE, 'YEAR')")
-- Oracle sequence operations
execute_oracle_dev("CREATE SEQUENCE emp_seq START WITH 1000 INCREMENT BY 1")
query_oracle_dev("SELECT emp_seq.NEXTVAL FROM DUAL")
-- Oracle-specific data types
query_oracle_dev("SELECT order_id, TO_CHAR(order_date, 'YYYY-MM-DD HH24:MI:SS') FROM orders")
-- Get schema metadata from Oracle data dictionary
query_oracle_dev("SELECT column_name, data_type, nullable FROM user_tab_columns WHERE table_name = 'EMPLOYEES'")
-- Use Oracle analytic functions
query_oracle_dev("SELECT employee_id, salary, RANK() OVER (ORDER BY salary DESC) as salary_rank FROM employees")
トラブルシューティング
よくある問題
- 接続の失敗:ネットワーク接続とデータベースの認証情報を確認してください
- 権限エラー:データベースユーザーに適切な権限があることを確認してください
- タイムアウトの問題:設定にある
query_timeoutを確認してください
ログ
トラブルシューティングのために詳細ログを有効にします。
./bin/server -t sse -c config.json -v
テスト
テストの実行
このプロジェクトには、サポート対象のすべてのデータベースについて、包括的な単体テストと統合テストが含まれています。
単体テスト
単体テストを実行します(データベースは不要です)。
make test
# or
go test -short ./...
統合テスト
統合テストを実行するには、データベースインスタンスが稼働している必要があります。簡単にセットアップできるよう、Docker Compose の設定を用意しています。
すべてのデータベースをテスト:
# Start test databases
docker-compose -f docker-compose.test.yml up -d
# Run all integration tests
go test ./... -v
# Stop test databases
docker-compose -f docker-compose.test.yml down -v
Oracle Database をテスト:
# Start Oracle test environment
./oracle-test.sh start
# Run Oracle tests
./oracle-test.sh test
# or manually
ORACLE_TEST_HOST=localhost go test -v ./pkg/db -run TestOracle
ORACLE_TEST_HOST=localhost go test -v ./pkg/dbtools -run TestOracle
# Stop Oracle test environment
./oracle-test.sh stop
# Full cleanup (removes volumes)
./oracle-test.sh cleanup
TimescaleDB をテスト:
# Start TimescaleDB test environment
./timescaledb-test.sh start
# Run TimescaleDB tests
TIMESCALEDB_TEST_HOST=localhost go test -v ./pkg/db/timescale ./internal/delivery/mcp
# Stop TimescaleDB test environment
./timescaledb-test.sh stop
リグレッションテスト
すべてのデータベースタイプを対象に、包括的なリグレッションテストを実行します。
# Ensure all test databases are running
docker-compose -f docker-compose.test.yml up -d
./oracle-test.sh start
# Run regression tests
MYSQL_TEST_HOST=localhost \
POSTGRES_TEST_HOST=localhost \
ORACLE_TEST_HOST=localhost \
go test -v ./pkg/db -run TestRegression
# Run connection pooling tests
go test -v ./pkg/db -run TestConnectionPooling
継続的インテグレーション
すべてのプルリクエストで、GitHub Actions によってテストが自動的に実行されます。CI パイプラインには次の項目が含まれます。
- 単体テスト:データベース接続を必要としない高速なテスト
- 統合テスト:MySQL、PostgreSQL、SQLite、Oracle の各データベースを対象とするテスト
- リグレッションテスト:後方互換性を保証する包括的なテスト
- リンティング:golangci-lint によるコード品質チェック
貢献
DB MCP Server プロジェクトへの貢献を歓迎します。貢献するには、次の手順に従ってください。
- リポジトリをフォークします
- 機能ブランチを作成します(
git checkout -b feature/amazing-feature) - 変更をコミットします(
git commit -m 'feat: add amazing feature') - ブランチにプッシュします(
git push origin feature/amazing-feature) - プルリクエストを作成します
詳しいガイドラインについては、CONTRIBUTING.md ファイルを参照してください。
変更のテスト
プルリクエストを送信する前に、次のことを確認してください。
- すべての単体テストが成功すること:
go test -short ./... - 影響を受けるデータベースの統合テストが成功すること
- プロジェクトのスタイルガイドラインに従っていること:
golangci-lint run ./... - 新機能に適切なテストカバレッジが含まれていること
ライセンス
このプロジェクトは MIT License のもとでライセンスされています。詳細については、LICENSE ファイルをご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。