migrationpilot について
MigrationPilotは、マージ前に危険なDDLを検出するローカル実行型のPostgreSQLマイグレーション解析ツールです。112のルールを適用し、CIチェックに加えてエージェント向けのMCP合否ゲートも提供します。
主な機能
- 01PostgreSQLマイグレーション用112ルール
- 02ロックとリスクの分析
- 03複数ファイルの順序チェック
- 04一部ルールの自動修正
- 05CIレポートと判定ゲート
活用シーン
- 01マージ前のマイグレーションSQL確認
- 02エージェントのワークフローで危険なDDLを阻止
- 03マイグレーション群の累積ロックリスク分析
- 04CIチェック用レポートの生成
MCP 対応
MCPサーバーは7つのツールを公開し、`check_before_apply`による合否ゲートのほか、マイグレーション分析、ルール検索、修正案、ロック説明を提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
7掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| sql | string | はい | 分析する SQL マイグレーション |
| pg_version | number | いいえ | 対象の PostgreSQL バージョン(デフォルト:17) |
詳細
MigrationPilot
マージ前に危険な Postgres マイグレーションを検出します。
PostgreSQL マイグレーションをローカルで決定論的に解析します。PostgreSQL のパーサーを使用し、112 個のルールをチェックして、CI ではゼロ以外の終了コードを返します。アカウントは不要です。MIT。
npx migrationpilot analyze migration.sql
ブラウザーで試す · GitHub Action · ドキュメント
ベンチマーク
| ツール | 厳格な検出率 | 誤検出率 |
|---|---|---|
| MigrationPilot | 31/33 (93.9%) | 1/17 (5.9%) |
| Squawk | 20/33 (60.6%) | 1/17 (5.9%) |
| pgfence | 25/33 (75.8%) | 3/17 (17.6%) |
ラベル付きファイル 56 件。作者が作成したコーパス。ツールのバージョンは固定。
方法 · コーパス · MigrationPilot が見逃したもの · 再現方法:pnpm build && node bench/run.mjs
検出例
-- migration.sql
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE (email);
$ migrationpilot analyze migration.sql
✗ MigrationPilot — RED Score: 80/100
migration.sql
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
1 statement · 2 critical · rollback GREEN
┌─────┬─────────────────────────────────────────────┬─────────────────────────┬────────┬────────────┐
│ # │ Statement │ Lock Type │ Risk │ Long lock? │
├─────┼─────────────────────────────────────────────┼─────────────────────────┼────────┼────────────┤
│ 1 │ ALTER TABLE users ADD CONSTRAINT users_e... │ ACCESS EXCLUSIVE │ RED │ YES │
└─────┴─────────────────────────────────────────────┴─────────────────────────┴────────┴────────────┘
Violations:
✗ [MP004] CRITICAL (line 1)
DDL statement acquires ACCESS EXCLUSIVE lock without a preceding SET lock_timeout. Without a timeout, this statement could block the lock queue indefinitely if it can't acquire the lock, causing cascading query failures.
Safe alternative:
-- Set a timeout so DDL fails fast instead of blocking the queue
SET lock_timeout = '5s';
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE (email)
RESET lock_timeout;
Why: Without lock_timeout, if the table is locked by another query, your DDL waits indefinitely. All subsequent queries pile up behind it in the lock queue, causing cascading timeouts across your application. GoCardless enforces a 750ms lock_timeout for this reason.
Docs: https://migrationpilot.dev/rules/mp004
✗ [MP027] CRITICAL (line 1)
Adding UNIQUE constraint "users_email_unique" on "users" scans the entire table under ACCESS EXCLUSIVE lock. Create the index concurrently first, then use USING INDEX.
Safe alternative:
-- Step 1: Create the unique index concurrently (non-blocking)
CREATE UNIQUE INDEX CONCURRENTLY users_email_unique_idx ON users (...);
-- Step 2: Add the constraint using the pre-built index (instant)
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE USING INDEX users_email_unique_idx;
Why: ALTER TABLE ADD CONSTRAINT UNIQUE builds a unique index while holding ACCESS EXCLUSIVE lock, blocking all reads and writes for the entire scan. Instead, create the unique index concurrently (non-blocking), then attach it as a constraint with USING INDEX.
Docs: https://migrationpilot.dev/rules/mp027
Risk Factors:
Lock Severity ██████████ 40/40 — ACCESS EXCLUSIVE (long-held)
Rule Violations ████████░░ 80/100 — 2 critical
112 rules checked in 11ms
終了コードは 2 です。Risk 列は、ステートメントのロックによる影響と、ルールで検出された問題を組み合わせているため、重大な違反を含むステートメントは、ロックのコストにかかわらず RED と表示されます。データベース接続がない場合、ロックに関する評価には上限があります。テーブルサイズとクエリ頻度を調べるには、データベース接続が必要です。本番環境でのコンテキストを参照してください。
目次
インストール · AI コーディングエージェント · CI · チェック項目 · 単一ファイルを超えて · 設定 · 出力 · 本番環境でのコンテキスト · 比較 · 料金 · アーキテクチャ · API
インストール
npx migrationpilot analyze migration.sql # no install
npm install -g migrationpilot # global
Node 22 以降が必要です。PostgreSQL パーサーはコンパイル済みの状態で同梱されているため、ほかに設定するものはありません。終了コードはどの環境でも共通です。問題なしは 0、--fail-on warning で警告がある場合は 1、重大な問題がある場合は 2 です。
Node がないマシン向けに、各リリースではパッケージ済みビルドも公開しています。リリースページには、Linux、macOS、Windows 用の単一ファイル実行形式もあります。Windows の .exe はコード署名されていないため、ダウンロード時に SmartScreen やほとんどのブラウザーから警告が表示されます。同じリリースにある SHA256SUMS を使えば、署名の確認ではなく、公開されたファイルを取得したことを確認できます。
brew install mickelsamuel/migrationpilot/migrationpilot
docker run --rm -v "$PWD:/work" ghcr.io/mickelsamuel/migrationpilot:1 analyze migration.sql
Windows の Git Bash では、MSYS がマウントフラグ内のパスを書き換えるため、代わりに Windows 形式の作業ディレクトリを使用してください。
docker run --rm -v "$(pwd -W):/work" ghcr.io/mickelsamuel/migrationpilot:1 analyze migration.sql
AI コーディングエージェント
エージェントは今やマイグレーションを作成します。SQL は得意ですが、4,000 万行のテーブルでどのステートメントが ACCESS EXCLUSIVE ロックを取得するかを把握するのは苦手です。そしてその頃には、すでに障害が発生しています。
MCP サーバー。 7 つのツールがあり、最も重要なのは check_before_apply です。これは、エージェントが DDL を記述または実行する前に呼び出す合否ゲートです。CLI とまったく同じように .migrationpilotrc.yml を解決するため、その判定は CI が下す判定と一致します。
{
"mcpServers": {
"migrationpilot": { "command": "npx", "args": ["migrationpilot-mcp"] }
}
}
| ツール | 目的 |
|---|---|
check_before_apply | {sql, pgVersion?, configPath?} を受け取り、{verdict: pass|fail, failOn, violations[], summary} を返します |
analyze_migration | 1 つのマイグレーションに対する違反、リスクスコア、ロック分析 |
analyze_migration_dir | フォルダー全体のファイルごとの結果と集計 |
get_rule | ルールが報告する内容、その重要性、自動修正の可否 |
suggest_fix | 自動修正した SQL と、人による対応が必要な違反 |
explain_lock | 1 つの DDL ステートメントが取得するロックと、そのロックによってブロックされる処理 |
list_rules | ルールの全一覧 |
Claude Code プラグイン。 integrations/claude-code/ は、Claude にマイグレーションの確認を指示するスキルと、確認しない場合にツール呼び出しをブロックする PreToolUse フックを組み合わせています。意図的にフェイルオープンにしています。インストールされていない場合、SQL を解析できない場合、またはタイムアウトした場合は、stderr にメモを出して呼び出しを続行します。実行できないときにワークフローを壊すガードレールはアンインストールされてしまうためです。
claude plugin install ./integrations/claude-code
Cursor と Copilot。 integrations/cursor/migrationpilot.mdc を .cursor/rules/ にコピーするか、integrations/copilot/copilot-instructions-snippet.md を .github/copilot-instructions.md に貼り付けてください。どちらも、MigrationPilot を実行するタイミングと、違反を回避するためにルールを抑制するかどうかはエージェントではなくユーザーが決めることを、エージェントに伝えます。
CI
GitHub Action
# .github/workflows/migration-check.yml
name: Migration Safety Check
on: [pull_request]
# New repositories default the workflow token to read-only; the report comment
# needs pull-request write.
permissions:
contents: read
pull-requests: write
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mickelsamuel/migrationpilot@v1
with:
migration-path: "migrations/*.sql"
fail-on: critical
レポートを PR コメントとして投稿し、重大な違反がある場合はチェックを失敗させ、SARIF ファイルを書き出します。Code Scanning に取り込むには、アップロードのステップを追加してください(プライベートリポジトリでは Advanced Security が必要です)。
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: migrationpilot-results.sarif
permissions ブロックがなくても Action は実行されます。警告を出し、PR で変更されたファイルだけでなく、グロブに一致するすべてのファイルを分析し、コメントの投稿を省略します。チェックの判定、SARIF ファイル、インライン注釈は、いずれの場合も分析結果に基づいて作成されます。
Action が読み込めない、または解析できないマイグレーションがあると、そのファイルは分析されていないため、チェックは失敗します。失敗メッセージにはファイル名とパーサーのエラーが含まれます。psql のメタコマンドやテンプレートのプレースホルダーを含むファイルなど、プレーンな SQL ではないファイルは、設定の ignore に指定してください。fail-on: never の場合は報告されますが、チェックは成功します。
Action は CLI と同じ設定ファイルを読み取るため、ignore、rules、failOn、pgVersion、extends がすべて適用されます。ワークフローで設定した入力値は設定ファイルより優先されます。Org ライセンスキーがある場合は、設定ファイルの policy ブロックと監査ログも有効になり、ポリシーは入力値より優先されます。つまり、exclude で必須ルールを除外することはできず、fail-on: never の場合でも、ブロック対象のステートメントがあればチェックは失敗します。
| 入力 | 説明 | デフォルト |
|---|---|---|
migration-path | SQL ファイルのグロブ、または配下のすべての .sql ファイルを対象とするディレクトリ(必須) | |
github-token | PR コメント用のトークン | ${{ github.token }} |
pg-version | 対象の PostgreSQL バージョン | 設定の pgVersion、なければ 17 |
fail-on | critical、warning、irreversible、never | 設定の failOn、なければ critical |
exclude | スキップするルール ID(カンマ区切り) | |
config-file | 設定ファイルのパス | 最も近い .migrationpilotrc.yml |
database-url | 本番環境のコンテキスト用の接続情報 | |
license-key | シークレットに設定する Org プランキー。設定の policy ブロックと監査ログを有効にします。指定しない場合も、すべてのルールが実行されます | MIGRATIONPILOT_LICENSE_KEY 環境変数 |
出力:risk-level、violations、sarif-file。
Pre-commit
migrationpilot hook install はプレーンな git フックを書き込み、Husky にも対応しています。代わりに pre-commit フレームワークを使う場合は、次のようにします。
repos:
- repo: https://github.com/mickelsamuel/migrationpilot
rev: v1.6.0
hooks:
- id: migrationpilot
args: [--fail-on, warning]
問題のないファイルは何も出力されません。違反のあるマイグレーションのみが報告されます。
pre-commit install を実行したときに Cowardly refusing to install hooks with 'core.hooksPath' set と表示された場合、フックディレクトリはすでに別のツール(Husky など)が管理しています。git config core.hooksPath で確認し、git config --unset-all core.hooksPath を実行して pre-commit にフックの管理を任せるか、Husky を使い続けて migrationpilot hook install を実行してください。こちらは競合するのではなく、.husky/pre-commit に追記します。
GitLab CI
include:
- remote: 'https://raw.githubusercontent.com/mickelsamuel/migrationpilot/v1.6.0/integrations/gitlab/.gitlab-ci-migrationpilot.yml'
migrationpilot:
variables:
MIGRATIONPILOT_PATH: db/migrate
マイグレーションに変更があるマージリクエストで実行され、JSON レポートをアーティファクトとして保持し、GitLab Code Quality を通じて MR の差分に注釈を付けます。
チェック内容
112 個のルールがあります。内訳は、重大なものが 34 個、警告が 78 個で、--fix で自動修正できるものが 20 個です。特に重要な 10 個を紹介します。
| ルール | 修正 | 検出内容 |
|---|---|---|
| MP001 | はい | CONCURRENTLY を付けない CREATE INDEX は、ビルド全体にわたって書き込みをブロックします |
| MP002 | SET NOT NULL はテーブル全体をスキャンします。検証済みの CHECK パターンを使ってください | |
| MP003 | 揮発性の DEFAULT を指定した ADD COLUMN は、テーブルとそのインデックスを書き換えます | |
| MP007 | ALTER COLUMN TYPE は ACCESS EXCLUSIVE ロックのもとでテーブルを書き換えます | |
| MP008 | 1 つのトランザクション内で複数の DDL 文を実行すると、ロック時間が累積します | |
| MP025 | はい | トランザクション内の CONCURRENTLY は警告ではなく、実行時の ERROR を引き起こします |
| MP027 | USING INDEX を指定しない UNIQUE 制約は、排他ロックのもとでテーブルをスキャンします | |
| MP055 | 主キーを削除すると、論理レプリケーションが機能しなくなります | |
| MP070 | 並行ビルドに失敗すると無効なインデックスが残り、再試行時に気付かないまま引き継がれます | |
| MP097 | 制約の背後にあるインデックスの削除は拒否され、マイグレーションが中断します |
112 個すべてのルールを見るか、migrationpilot explain MP027 を実行して個別のルールを確認してください。ハンドブックでは、各リスクが発生する理由と代わりに取るべき方法を 20 章にわたって解説しています。
ルールは --pg-version(9 から 18)に応じて調整されます。REINDEX CONCURRENTLY は 12 から、DETACH PARTITION CONCURRENTLY は 14 から、ネイティブの NOT NULL ... NOT VALID パスは 18 から利用できます。
1 つのファイルを超えて
analyze --fix は、修正可能な 20 個の違反をその場で書き換えます。その他の機能は次のとおりです。
| コマンド | 機能 |
|---|---|
check <dir> | ディレクトリ全体をチェックし、ファイル間のシーケンス分析も実行します |
simulate | 一時的なプロセス内 PostgreSQL 18(PGlite)に対してマイグレーションを実行し、実際に起きたことを報告します |
plan-fix | 1 行では修正できない違反に対し、デプロイ境界を含む、ステップごとの拡張・縮小計画を提示します |
mutation-test | 問題のないマイグレーションを、危険な類似パターンに変異させて、設定の抜け穴を見つけます |
predict | --row-count と --size に基づいて調整された、操作の所要時間を推定します |
template | 名前変更、型変更、NOT NULL などの拡張・縮小 SQL を生成します |
plan | ロック、所要時間、ブロックの影響、トランザクション境界を示す、視覚的な実行タイムラインを表示します |
rollback | 復旧可能性の評価付きで、DDL を元に戻します |
drift | 2 つの稼働中スキーマの差分を表示します |
precommit | pre-commit フレームワークが呼び出す、複数ファイル対応のエントリーポイントです |
コマンドは全部で 24 個あります。migrationpilot --help で一覧を確認できます。
シーケンス分析は、ファイル単位のリンターでは検出できない問題を見つけます。それぞれは問題なく見える 3 つのマイグレーションでも、同時に適用すると 1 つのテーブルを停止させることがあります。
$ migrationpilot check migrations/
⚠ [SQ001] WARNING cumulative-lock-budget
"orders" is locked for an estimated 2m across 2 statements in 2 files — over the 1m budget for one deploy.
⚠ [SQ002] WARNING hot-table-multi-touch
"orders" is locked by 3 files in this sequence. Each one queues behind live traffic on its own — fold them into one migration so the table takes the hit once.
--lock-budget <seconds> と --hot-table-threshold <files> で調整し、--no-sequence で無効にできます。また、--fail-on-sequence でブロッキング対象にできます。
--fail-on irreversible は critical より厳格です。ロールバック用ファイルがなく、データを破壊するマイグレーションもブロックします。
設定
デフォルトでは設定不要です。ディレクトリを指定せずに check を実行すると、フレームワークを検出し、マイグレーションを見つけて、適用順に分析します。対応しているのは14種類です:Flyway、Liquibase、Alembic、Django、Knex、Prisma、TypeORM、Drizzle、Sequelize、goose、dbmate、Sqitch、Rails、Ecto。--framework prisma で指定するか、任意のジェネレーターの出力を --from-command に渡せます:
migrationpilot check --from-command "python manage.py sqlmigrate myapp 0042"
# .migrationpilotrc.yml
extends: "migrationpilot:strict"
pgVersion: 16
failOn: warning
rules:
MP037: false # off
MP004: { severity: warning } # downgrade
MP013: { threshold: 5000 } # retune
ignore:
- "migrations/seed_*.sql"
5つのプリセット:recommended(デフォルト)、strict、ci、startup、enterprise。インラインで -- migrationpilot-disable MP001 と記述すると次の文に対するルールを無効にし、-- migrationpilot-disable-file MP001 と記述するとファイル全体に対して無効にします。ルールを指定しない場合は、すべてのルールが無効になります。
組織ポリシー
MIGRATIONPILOT_LICENSE_KEY に組織プランのキーを設定すると(または --license-key、あるいは Action の license-key 入力を使うと)、analyze、check、precommit、および Action によって、設定の policy ブロックが適用されます。watch、plan、simulate、mutation-test では必須ルールが有効のまま維持され、最低基準も適用されますが、ブロックされたパターンで失敗するのはゲートだけです。
policy:
requiredRules: [MP001, MP004] # run whatever rules:, a preset, --exclude or a disable comment says
severityFloor: critical # a critical rule can't be set below critical
blockedPatterns: ["DROP TABLE", "TRUNCATE"] # fail the run whatever --fail-on says
requireReviewPatterns: ["ALTER TYPE"] # reported for team review
auditLog:
enabled: true # one JSONL line per check
各上書きでは、どの設定が有効のまま維持されたかを示すメッセージが表示されます。警告として提供されるルールは、critical の最低基準を設定しても警告のままです。パターンは、大文字と小文字、空白、コメントを無視して、単語全体に一致します。有効なキーがない場合、実行時にポリシーが適用されていないことが通知され、何も告げずに成功することはありません。--no-config は設定ファイルと、それに含まれるポリシーをスキップします。そのため、コードと同様に設定がレビューされる CI で強制してください。MCP サーバーは設定を読み込みません。
Ed25519 ライセンスキーは、ネットワーク通信なしでクライアント側で検証されます。--offline は更新チェックと、その他すべてのネットワーク通信をスキップします。テレメトリーはありません。
出力
--format text(デフォルト)、json、sarif、または markdown を指定できます。また、違反ごとに gcc スタイルの1行だけを出力する --quiet と、文ごとの合格/不合格を表示する --verbose も利用できます。
{
"$schema": "https://migrationpilot.dev/schemas/report-v1.json",
"version": "1.6.0",
"file": "migrations/001.sql",
"riskLevel": "RED",
"riskScore": 80,
"violations": []
}
SARIF は GitHub Code Scanning、VS Code、IntelliJ に渡せます:migrationpilot analyze migration.sql --format sarif --output results.sarif。
本番環境のコンテキスト
--database-url を渡すと、MigrationPilot は読み取り専用の接続を1つ開き、pg_class、pg_stat_statements、pg_stat_activity を読み取ります。ユーザーデータは読み取らず、DDL も実行しません。
これにより、リスクスコアリングは推測ではなく測定に基づくものになります。また、数値がなければ判断できない3つのルールに値を提供します:MP013(高トラフィックのテーブルに対する DDL)、MP014(数百万行のテーブルで長時間保持されるロック)、MP019(接続が急増している間の ACCESS EXCLUSIVE)。
| 要因 | 重み | --database-url が必要 |
|---|---|---|
| ロックの重大度 | 0-40 | いいえ |
| テーブルサイズ | 0-30 | はい |
| クエリ頻度 | 0-30 | はい |
GREEN は 0-24、YELLOW は 25-49、RED は 50-100 です。
比較
| MigrationPilot | Squawk | Atlas | |
|---|---|---|---|
| ルール(すべて無料) | 112 | 40 | 50以上のアナライザー、ロックアナライザーは Pro 限定 |
| 自動修正 | 20ルール | 0 | 0 |
| ファイル横断のシーケンス分析 | はい | いいえ | いいえ |
| 一時的な PG に対する実際の実行 | はい | いいえ | はい、Docker が必要 |
| エージェント向け MCP サーバー | はい | いいえ | いいえ |
| フレームワーク検出 | 14 | 0 | 0 |
| 設定プリセット | 5 | 0 | 0 |
| Code Scanning 向け SARIF | はい | いいえ | いいえ |
| ライセンス | MIT | Apache-2.0 / MIT | Apache-2.0 コア、無料の lint なし |
Squawk:v2.62.0 時点で40ルール(2026年8月)。Atlas は v0.38 以降(2025年10月)、公式バイナリで migrate lint を Pro ログイン必須にしています。Community ビルドでは基本的なアナライザーセットを利用できますが、PostgreSQL のロックアナライザーは Pro 限定です。有料アカウントがなければベンチマークできませんでした。方法には、正確なコマンドと拒否された内容が記録されています。
料金
リンターのすべての機能は無料で、使用量に制限はありません。本番コンテキスト向けのルールを含む全112個のルール、自動修正、シーケンス分析、シミュレーション、すべての出力形式、GitHub Action、MCP サーバーを利用できます。アカウントもシート数の制限もなく、テレメトリーもありません。MIT ライセンスです。
年額499ドルのOrgプランでは、無料のリンターを強制力のある制御機能として利用できます。開発者がひそかに無効化できない、リポジトリ横断で統一されたポリシー、すべてのチェックを記録するJSONL監査証跡、メンテナーによる直接サポートが含まれます。
アーキテクチャ
src/
├── parser/ locks/ # libpg-query WASM, lock classification
├── rules/ fixer/ # 112 rules and the 20-rule auto-fixer
├── analysis/ scoring/ # shared pipeline, transaction boundaries, risk 0-100
├── sequence/ lockqueue/ # cross-file SQ rules, lock queue modelling
├── simulate/ mutate/ # PGlite execution, mutation-testing operators
├── cascade/ graph/ schema/ prediction/ templates/
├── production/ frameworks/ plugins/ output/ generator/
├── mcp/ action/ config/ hooks/ watch/ drift/ history/
├── policy/ auth/ license/ team/ audit/ billing/ usage/ doctor/
├── index.ts # programmatic API, 69 value exports plus types
└── cli.ts # 24 commands
プログラムによるAPI利用
import { analyzeSQL, allRules, parseMigration, classifyLock } from 'migrationpilot';
const result = await analyzeSQL(sql, 'migration.sql', 17, allRules);
console.log(result.violations, result.overallRisk);
69個の値エクスポートと、完全なTypeScript型を提供します。allRulesは、CLIが実行するものと同じルールセットです。
開発
pnpm install
pnpm test # 1945 tests across 72 files
pnpm build # CLI 1.4MB, Action 1.7MB, API 639KB, MCP 1.7MB
pnpm lint && pnpm typecheck
pnpm dev analyze path/to/migration.sql
CONTRIBUTING.md · SECURITY.md · CHANGELOG.md
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。