mcpField
D
dryrun

dryrun

ローカル
boringsql.comデータベース36今日更新

dryrun について

dryrunは、AIエージェント、IDE、CI向けのPostgreSQLスキーマ分析CLI兼MCPサーバーです。コミット済みのオフラインスナップショットからスキーマ情報を提供するため、アシスタントにデータベースの認証情報を渡さずに検証や安全性チェックを行えます。

主な機能

  1. 01PostgreSQLスキーマスナップショットの取得
  2. 02スキーマ規約と構造の検査
  3. 03マイグレーションのロックとテーブル書き換えを分析
  4. 04スキーマに照らしたSQL検証
  5. 05スナップショット比較とドリフト検出
  6. 06MCPツールによる分析機能の提供

活用シーン

  1. 01デプロイ前にマイグレーションのリスクを確認
  2. 02プロジェクトのスキーマに照らして生成SQLを検証
  3. 03認証情報なしでチーム内のスキーマ確認を可能にする
  4. 04リリース間のスキーマスナップショットを比較

MCP 対応

MCPサーバーはプロジェクトのオフラインスナップショットを読み込み、スキーマ探索、クエリ検証、実行計画分析、マイグレーション検査、Lintなどのツールを提供します。stdioまたはSSEに対応し、一部のツールにはライブデータベース接続が必要です。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"boringsql-dryrun": {
"command": "npx",
"args": [
"-y",
"@boringsql/dryrun"
]
}
}
}
起動コマンドnpx -y @boringsql/dryrun

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@boringsql/dryrun0.20.0

ツール

9

掲載時のツール一覧 · 2 日前に更新

パラメーター型必須説明
sqlstringはいSQL クエリ。
plan_jsonobject|array|stringいいえすでに取得済みの EXPLAIN プラン。ユーザーが貼り付けたもの、または CI が取得したもので、EXPLAIN (FORMAT JSON) が返す [{"Plan": ...}] 配列、あるいはラップされていない {"Plan": ...} オブジェクトです。クライアントが構造化引数を再エンコードする場合があるため、どちらの形式の JSON 文字列も受け付けます。渡されたまま読み取り、advise が再実行することはありません。
include_index_suggestionsbooleanいいえインデックスの提案を含めます(既定値は true)。

詳細

DryRun PostgreSQL MCP

本番環境への接続が不要な PostgreSQL MCP サーバーです。

dryrun を使うと、AI エージェント、IDE、CI がスキーマ全体を把握できます。ライブデータベースへの接続ではなく、オフラインのスナップショットを使用します。スキーマのリント、クエリの検証、マイグレーションの安全性の確認、外部キーのグラフの探索ができます。DBA のマシンから認証情報を持ち出すことなく、すべて実行できます。

dryrun は、RegreSQL および Fixturize と並ぶ boringSQL スイートの一部です。

問題

LLM/AI コーディングアシスタントは、コードや SQL クエリを書くのがとても得意です。しかし、盲点があります。スキーマ、インデックス、制約を把握していません。そのため、最も負荷の高いテーブルに ACCESS EXCLUSIVE ロックをかけるマイグレーションを生成し、アプリを停止させる可能性があります。

データベースへの接続を求める PostgreSQL MCP サーバーもあります。管理タスクを実行するには、SUPERUSER 権限が必要になることもあります。しかし、それは問題を招くようなものです。

その結果はすでに目にしています。AI エージェントによる本番データベースの消去や、読み取り専用であるはずの MCP サーバーでの SQL インジェクションが発生しています。

モデルがデータベースに対して クエリを実行 する必要はありません。必要なのは、スキーマの構造、制約、統計情報、バージョン固有の動作を 理解する ことです。こうした情報は構造的なものです。変わるのはマイグレーションをデプロイしたときであり、クエリごとではありません。

DryRun の機能

dryrun は、CLI ツール と MCP サーバー の 2 つの役割を担います。CLI はスキーマを抽出して分析します。MCP サーバーは、その分析結果を AI アシスタントに提供します。意図的に別々にしています。

CLI - 抽出と分析

CLI は PostgreSQL データベースに接続して、完全なカタログ(テーブル、ビュー、インデックス、制約、パーティション、関数、列挙型、RLS ポリシー、トリガー、拡張機能、GUC)をイントロスペクトし、スナップショットを .dryrun/history.db に書き込みます。このスナップショットが、以降のすべての処理の信頼できる情報源になります。

スナップショットを取得すれば、CLI はオフラインで動作します。

  • リント - 20 以上の規約ルール(命名、型、主キー、タイムスタンプ、パーティショニング)と 13 の構造監査ルール(重複インデックス、外部キーのカバレッジ、循環外部キー、VACUUM の調整)
  • マイグレーションの安全性 - ロックタイプの分析、所要時間の推定、テーブルの書き換えの検出、各 DDL 文に対する安全な代替案
  • クエリの検証 - libpg_query による SQL 解析、実際のスキーマに基づくカラム参照のチェック、アンチパターンの検出
  • スナップショットの差分 - スナップショット間でスキーマ、プランナー統計、アクティビティを比較し、ライブデータベースとのドリフトを検出
  • クエリ統計 - ノードごとに pg_stat_statements を取得し、ORM クエリのバリエーションをクエリ形式にまとめ、2 つの取得結果を比較して新規または遅くなったクエリを特定
  • マルチノード統計 - レプリカごとの統計、seq_scan のホットスポット、ルーティングの偏り
MCP サーバー - AI アシスタントにスキーマの知識を提供

MCP サーバーは同じスナップショットを読み込みます。stdio または SSE 経由で、スキーマの探索と検索、クエリの検証、プランの分析、マイグレーションのチェック、リント、VACUUM の健全性確認、取得済みの pg_stat_statements の上位クエリなど、9 つのツールを公開します。ライブデータベースに接続すると、さらに 3 つのツール(explain_query、check_drift、columnar_report)が利用可能になります。AI アシスタントは SQL を書きながら、データベースを理解できます。

データベースへの接続は不要です。アシスタントが認証情報を見ることはありません。

オフラインである理由

スキーマコンテキストはライブ接続ではなく、ファイルに保存するものです。 列の型、行数の推定値、インデックスの定義、FK の関連、PostgreSQL のバージョンはすべて、一度エクスポートしてリポジトリにコミットできます。データベースにアクセスできる人がスキーマをダンプすれば、ほかの全員は、人間も AI エージェントも、認証情報なしでスキーマのインテリジェンスをすべて利用できます。

認証情報を DBA のマシンの外に持ち出すべきではありません。 MCP サーバーが役に立つには DATABASE_URL が必要だとすれば、利用する開発者全員が本番環境の認証情報を必要とします。これは AI とは無関係なセキュリティ上の問題です。

サーバーは単にデータを渡すのではなく、分析するべきです。 生の \d+ の出力を返すのは、自分でチャットに貼り付けるより多少ましという程度です。価値があるのは、そのデータを解釈することです。PostgreSQL のバージョンに対してマイグレーションが安全かを確認し、FK インデックスの不足を指摘し、実際のスキーマに照らして列参照を検証します。

インストール

PostgreSQL 14 以降が必要です。 古いサーバーも拒否されるわけではありません。dryrun は警告を出し、取得できる情報を収集しますが、テストされておらず、一部のストリーム(特にプランナー統計)は利用できません。最低バージョンは、上流でサポートが継続されている最も古いリリースに合わせています。

Homebrew:

Homebrew 6.0 では、フォーミュラを読み込む前にサードパーティのタップを信頼する必要があります。

brew trust --tap boringsql/boringsql
brew install boringsql/boringsql/dryrun

Homebrew 5.x 以前では、brew trust の手順を省略してください。タップ全体を信頼したくない場合は、brew trust --formula boringsql/boringsql/dryrun でフォーミュラだけを信頼できます。

npm / npx:

すでに Node をお使いであれば、何もインストールせずに dryrun を実行できます。

npx @boringsql/dryrun --version

これにより、お使いのプラットフォーム用のビルド済みバイナリ(darwin-arm64、linux-x64、linux-arm64)が取得され、キャッシュされた後、バージョンが表示されます。dryrun を PATH に永続的に追加するには、次のようにします。

npm install -g @boringsql/dryrun
dryrun --version

npm パッケージは同じ Go バイナリをラップしており、すべての CLI コマンドが同じように動作します。lint などのコマンドを使うには、先にスキーマスナップショットが必要です。クイックスタートを参照してください。ビルド済みバイナリは、macOS(Apple Silicon と Intel)、Linux(x64 と arm64)、Windows x64 に対応しています。そのほかのプラットフォーム(Alpine/musl、Windows arm64)では、Homebrew を使うか、ソースからビルドしてください。

ソースからインストール:

Go 1.26 以降が必要です。インストールされていない場合は、go.dev/dl からインストールしてください。

git clone https://github.com/boringsql/dryrun.git
cd dryrun
go build -o bin/dryrun ./cmd/dryrun

バイナリは bin/dryrun にあります。

30 秒デモ

dryrun をインストールしたら、データベースもセットアップも必要なく、このリポジトリをクローンして用意されているスキーマスナップショットを lint できます。

git clone https://github.com/boringsql/dryrun.git
cd dryrun/examples/demo
dryrun lint

(npm または Homebrew でインストールしたものの、リポジトリをクローンしていない場合は、examples/demo がありません。クイックスタートに進み、独自のスキーマを dryrun に指定してください。以下のサンプル出力は lint の実行結果です。)

[ERROR] public.audit_log: table has no primary key
       fix: add a primary key (bigint GENERATED ALWAYS AS IDENTITY recommended)
[WARN ] public.audit_log: gap in range partitions: ends at '2024-07-01' but next starts at '2024-10-01'
       fix: inserts into the gap will fail unless a DEFAULT partition exists
[ERROR] public.task_comments: table has no primary key
       fix: add a primary key (bigint GENERATED ALWAYS AS IDENTITY recommended)
[WARN ] public.projects.created_at: timestamp column uses timestamp without time zone instead of timestamptz
       fix: use timestamptz for timestamp columns
[ERROR] public.tasks.project_id: FK 'tasks_project_id_fkey' on column(s) (project_id) has no covering index
       fix: add an index on FK columns to avoid sequential scans on DELETE/UPDATE
[WARN ] public.users.email: column 'email' uses character varying(255), prefer text
       fix: VARCHAR(n) adds a hidden CHECK constraint with no performance benefit
[WARN ] public.user_notifications: table is missing 'created_at' column
       fix: add: created_at timestamptz NOT NULL DEFAULT now()

26 finding(s): 6 error, 20 warning, 0 info (13 tables checked)

データベースは不要です。完全にオフラインのスナップショットを使って動作します。

同じデモを MCP 経由でも実行できます。examples/demo から、アシスタントにサーバーを登録してください。

claude mcp add dryrun -- npx -y @boringsql/dryrun mcp-serve

次に、そのディレクトリから「どんなテーブルがあり、何が問題ですか?」と尋ねてください。

MCP サーバー

1 つのコマンドで、サーバーを AI エージェントに接続できます。setup は Claude Code、Cursor、Codex、Zed を検出してエージェントの MCP 設定を書き込み、エージェントが SQL を書く前にスキーマを確認するよう、AGENTS.md/CLAUDE.md に指示を追加します。

dryrun setup

エージェントを自分で選ぶ場合や、非対話型シェルから実行する場合は、--agents を渡します。

dryrun setup --agents=claude,cursor   # or: all

サーバーを手動で登録する場合:

# for claude code
claude mcp add dryrun -- dryrun mcp-serve

# for codex
codex mcp add dryrun -- dryrun mcp-serve

ソースからビルドした場合は、バイナリへのフルパスを使います。

claude mcp add dryrun -- /path/to/dryrun mcp-serve

インストールせずに使う場合は、クライアントの接続先に npx を指定します。

claude mcp add dryrun -- npx -y @boringsql/dryrun mcp-serve

この形式のクライアント設定は次のとおりです。

{
  "mcpServers": {
    "dryrun": {
      "command": "npx",
      "args": ["-y", "@boringsql/dryrun", "mcp-serve"]
    }
  }
}

サーバーは、現在のプロジェクトの .dryrun/history.db から最新のスナップショットを読み込みます。データベースの認証情報は不要です。アシスタントはオフラインのスナップショットからスキーマに関するすべての情報を取得します。

スナップショットがなくてもサーバーは起動し、ツールはスキーマが読み込まれていないことを返します。dryrun init --db "$DATABASE_URL" でスナップショットを取得するか、チームメイトがプッシュしたものを取得してください(クイックスタートを参照)。サーバーは再起動しなくても、次のツール呼び出し時にスナップショットを読み込みます。

複数のデータベースがあるプロジェクトでは、データベースごとに dryrun mcp-serve を実行し、クライアント設定にサーバーごとのエントリーを追加してください。1 つの MCP プロセス内で複数のデータベースをネイティブに提供する機能は、#7で追跡しています。

ライブデータベースの設定、SSE トランスポート、Claude Desktop の設定については、チュートリアルを参照してください。

クイックスタート

始める方法は 2 つあります。セットアップに合った方法を選んでください。

オプション A:データベースにアクセスできる場合

PostgreSQL インスタンス(ローカル、開発環境、本番環境)に接続できる場合は、1 つのコマンドですべて完了します。

dryrun init --db "$DATABASE_URL"

これにより、dryrun.toml([project] id とデフォルトプロファイルを含む)、.dryrun/ データディレクトリが作成され、データベースのスナップショットが .dryrun/history.db に取得されます。スナップショットは (project_id, database_id) をキーとして保存されます。プロジェクトに複数のデータベースがある場合は、プロファイルごとに database_id を設定してください(例:auth、billing)。設定の詳細については、docs/dryrun-toml.mdを参照してください。

オプション B:他の人がデータベースにアクセスできる場合

認証情報を持つ人が一度スナップショットを取得して共有ディレクトリにプッシュします。共有ディレクトリはリポジトリ内にあるものでも、双方がアクセスできる場所にあるものでもかまいません。

dryrun init --db "$DATABASE_URL"
dryrun snapshot push --to-path ./snapshots

dryrun.toml と ./snapshots の両方をコミットします。他のメンバーは次のコマンドで取得します。

dryrun snapshot pull --from-path ./snapshots

snapshot pull はスナップショットを .dryrun/history.db に読み込みます。そのマシンにデータベースは必要ありません。

dryrun.toml のコミットは必須です。スナップショットは (project_id, database_id) をキーとして保存され、dryrun init はライブデータベース名から database_id を設定するためです。チームメイトが --db なしで dryrun init を実行すると、異なる database_id が設定されます。その場合、pull はソースに存在しないキーを参照するため、0 copied と報告します。

プッシュされたスナップショットには、スキーマとともにプランナーおよびアクティビティの統計情報も含まれます。そのため、サイズやバキュームのデータが必要なオフラインツールも動作します。通常の JSON エクスポートではこれらの情報を取得できません。ディレクトリではなくレジストリを使う場合は、dryrun remote add と snapshot push --remote を参照してください。人やエージェントに読みやすい JSON を渡すには、引き続き dryrun dump-schema で書き出せます。これはエクスポートであり、入力ではありません。

では、使ってみましょう
dryrun lint

すべてのコマンドは .dryrun/history.db を使ってオフラインで動作します。プロジェクトごとに独自の dryrun.toml と .dryrun/ があり、グローバルな状態はありません。.dryrun/ を .gitignore に追加してください。

スナップショットは .dryrun/history.db に保存され、(project_id, database_id) をキーとして管理されます。これが唯一のスキーマソースです。MCP サーバー、lint、drift はすべてここから読み込みます。以前の dryrun で残された .dryrun/schema.json は無視されます。

データベースは SQLite の WAL モードで動作するため、スケジュールされた snapshot capture と長時間稼働する mcp-serve が同じデータベースを共有できます。サーバーがクエリを実行中でもキャプチャがコミットでき、どちらかがもう一方の終了を待つ必要はありません。WAL モードでは history.db の隣に history.db-wal と history.db-shm というサイドカーファイルが追加されます。これらは最後のプロセスが正常終了すると削除され、クラッシュ時には残ります。そのため、これらも .dryrun/ と同様に無視してください。知っておくべき点が 2 つあります。WAL モードの history.db では、lint のような読み取り専用コマンドでも .dryrun/ への書き込み権限が必要です。また、WAL には共有メモリが必要ですが、ネットワークファイルシステムでは共有メモリが提供されません。NFS または SMB 上の .dryrun/ では、ロールバックジャーナルが自動的に使われます(正しく動作しますが、競合時は遅くなります)。

マルチノード:レプリカからアクティビティをキャプチャする

プライマリで snapshot capture を実行すると、スキーマとプランナー統計が書き込まれます。アクティビティカウンター(idx_scan、n_dead_tup、最終バキューム時刻)は各レプリカ上にあるため、こちらもキャプチャしてください。

dryrun --profile primary snapshot capture --label primary
dryrun snapshot capture --from "$REPLICA1_URL" --label replica1
dryrun snapshot capture --from "$REPLICA2_URL" --label replica2

dryrun.toml に [[node]] ブロックを設定しておくと、dryrun snapshot capture --all で一度にすべて実行できます。

MCP の describe_table(ノード別内訳)と detect kind=anomalies ツールでは、ノードごとの idx_scan が確認できるため、ルーティングの偏りを見つけられます。詳しくは docs/multi-node-stats.md を参照してください。

プロジェクトごとの複数データベース

dryrun snapshot capture は、(project_id, database_id) をキーとしてスナップショットを管理します。デフォルト設定のままで動作します。project_id はフォルダー名、database_id は current_database() が返す実際のデータベース名です。

dryrun init --db "$AUTH_DB"            # captures auth
dryrun snapshot capture --db "$BILLING_DB" --label primary # billing gets its own stream
dryrun snapshot list --db "$AUTH_DB"    # only auth snapshots

安定した参照を使えるようにし(また、list / diff の実行時に URL を再入力しなくて済むようにするため)、dryrun.toml でプロファイルを宣言します。

[project]
id = "myapp"

[profiles.auth]
db_url = "${AUTH_DATABASE_URL}"
database_id = "auth"

[profiles.billing]
db_url = "${BILLING_DATABASE_URL}"
database_id = "billing"

その後、次のように実行します。

dryrun --profile billing snapshot list
dryrun --profile billing snapshot diff --latest

すべてのプロファイルオプションについては、docs/dryrun-toml.md を参照してください。

データベース関連のすべてのコマンド(init、probe、dump-schema、drift、stats apply、すべての snapshot サブコマンド)は --profile を受け付けます。また、--db が指定されていない場合は、解決されたプロファイルの db_url を使用します。lint はオフラインで動作し、.dryrun/history.db を読み込みます。--db を明示的に指定した場合に限り、稼働中のデータベースにアクセスします。

注記: MCP サーバーは現在、単一のデータベースにのみ対応しています。デフォルトのプロファイルを使用してください。または、データベースごとに dryrun mcp-serve プロセスを 1 つずつ実行できます。1 つの MCP プロセス内でのネイティブな複数データベース対応は、#7 で追跡されています。

チームでスナップショットを共有する

チームで利用すると、DryRun の価値が高まります。複数の開発者が、POSIX 準拠の任意のディレクトリからスナップショットを取得できます。

スナップショットを公開するには、次のコマンドを実行します。

cd project_name

# capture from the live DB (use cwd name for project name)
dryrun init --db "$DATABASE_URL"
dryrun snapshot capture --db "$DATABASE_URL" --label primary
dryrun snapshot push --to-path ./snapshots --all

その後、開発者はスナップショットをローカルの履歴にインポートできます。

dryrun snapshot pull --from-path ./shared/snapshots --all

スナップショットはコンテンツアドレス方式({project}/{database}/{ts}-{hash}.json.zst)で保存され、冪等です。同じスナップショットを 2 回プッシュしても、変更は発生しません。

最も簡単なデプロイ方法は、専用の git リポジトリを用意することです。スナップショット用リポジトリを作成し、*.json.zst binary を .gitattributes に追加すると、git がバンドルの差分を取ろうとしなくなります。

オフラインツール(lint、check_migration、drift)は、プル後すぐに使えます。

サーバーも認証情報も必要ありません。これまでと同じ約束です。

OCI レジストリにスナップショットをプッシュする

GitHub Container Registry、Google Artifact Registry、Amazon ECR、Docker Hub、Harbor、またはセルフホストのレジストリなど、どの OCI レジストリでもスナップショットを保存できます。レジストリが認証、保持、アクセス制御を担うため、実行するサーバーは必要ありません。

docker push と同じ方法で認証し、リモートを登録してプッシュします。

docker login ghcr.io
dryrun remote add ghcr --ref ghcr.io/myorg/dryrun --default
dryrun snapshot capture --label primary --push

snapshot capture --push を使うと、スナップショットの取得と公開を一度に行えます。利用する側はプルします。

dryrun snapshot pull --remote ghcr

デフォルトでは、push と pull はどちらも最新のテイクのみを移動するため、コールドプル(新規の CI、空の history.db)でも共有ストアでも、どちら側がどれだけの履歴を保持しているかにかかわらず、コストを低く抑えられます。--full を使うと履歴全体を同期できます。または、--since 7d(2w、24h、2026-01-01 のような UTC 日付も指定可能)を使うと期間を指定できます。どちらの場合も、コピーはコンテンツハッシュに基づいて増分で行われるため、一定間隔でプッシュする所有者は、実行のたびに新しい観測結果だけをアップロードします。

--ref はレジストリのベースです。各データベースはその下に独自のリポジトリを持ちます。<ref>/<project_id>/<database_id> の形式になるため、myapp の auth データベースは ghcr.io/myorg/dryrun/myapp/auth に保存されます。スナップショットはコンテンツハッシュで指定される OCI アーティファクトに対応するため、同じものを 2 回プッシュしても変更はなく、共有 BLOB はレジストリ上で重複排除されます。Google Artifact Registry では、docker login の代わりに gcloud auth configure-docker us-docker.pkg.dev を実行します。それ以外は同じです。

認証。 デフォルトでは、dryrun は Docker の認証情報(~/.docker/config.json と認証情報ヘルパー)を再利用するため、docker login でログインできるレジストリであれば、追加の設定なしで利用できます。remote add で指定できる次の 2 つのオーバーライドで、ほかの場合にも対応できます。

  • --token-env VAR は環境変数から静的なベアラートークンを読み込みます。短期間有効なトークンを発行するレジストリに使います(例:gcloud auth print-access-token で取得した値を渡す --token-env GAR_TOKEN)。
  • --auth gcp は Google Application Default Credentials を直接使用するため、configure-docker を使わずに、gcloud auth login(または GOOGLE_APPLICATION_CREDENTIALS によるサービスアカウントキーの指定)の後で Google Artifact Registry/Container Registry を利用できます。ADC トークンは自動的に更新されます。

プロファイルごとのリモート設定や、複数のプロジェクトで 1 つのストリームを共有する方法については、docs/dryrun-toml.md を参照してください。

詳細

  • チュートリアル では、オフライン、オンライン、マルチノードのワークフローと、ツールの完全なリファレンスを紹介しています
  • マルチノード統計 では、クラスター全体の統計収集、集計ルール、レプリカの不均衡検出について説明しています
  • クエリ統計 では、pg_stat_statements の取得、形状によるグループ化、差分の比較について説明しています
  • 匿名化スナップショット では、他の人に渡せるスナップショットの作成方法として、PII マッピング、マスク処理を行った取得、送信前に確認すべき項目について説明しています
  • 設定リファレンス では、dryrun.toml のプロファイル、規約、リモート、リントルールについて説明しています
  • CLI の安定性 では、安定版と実験的なコマンドを紹介しています
  • セキュリティの概要 では、CLI/MCP の分離とマスキングについて説明しています
  • boringSQL。ブログおよびプロジェクトのホームページ
  • dryrun プロジェクトページ。概要とドキュメント
  • AI に本番データベースを触らせない。多くの Postgres MCP が安全でない理由と、dryrun が異なる点について説明しています
  • RegreSQL。SQL 回帰テスト、および dryrun の関連ツール
  • Fixturize。本番データのサブセット化とマスキングを行い、開発/テストに利用できます

ライセンス

BSD 2-Clause ライセンス

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。