Skip to main content
Glama

MigrationPilot

npm version npm downloads CI Node VS Code License: MIT

Block unsafe Postgres migrations before merge.

Local, deterministic analysis for PostgreSQL migrations. Uses PostgreSQL's parser, checks 112 rules, and exits non-zero in CI. No account required. MIT.

npx migrationpilot analyze migration.sql

Try it in your browser · GitHub Action · Documentation

Benchmark

Tool

Strict detection

False positives

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 labelled files. Author-built corpus. Tools pinned.

Methodology · Corpus · What MigrationPilot missed · Reproduce: pnpm build && node bench/run.mjs

Related MCP server: pg-dash

A finding

-- 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

Exit code is 2. The Risk column combines what a statement's lock does with what the rules found in it, so a statement carrying a critical violation reads RED whatever its lock costs. The lock half of that is capped without a database connection — table size and query frequency need one. See Production context.

Contents

Install · AI coding agents · CI · What it checks · Beyond one file · Configuration · Output · Production context · Comparison · Pricing · Architecture · API

Install

npx migrationpilot analyze migration.sql   # no install
npm install -g migrationpilot              # global

Node 22 or newer. The PostgreSQL parser ships compiled in, so there is nothing else to set up. Exit codes are the same everywhere: 0 clean, 1 warnings under --fail-on warning, 2 critical.

Packaged builds land with each release, including single-file executables for Linux, macOS and Windows on the release page for machines without Node. The Windows .exe is not code-signed, so SmartScreen and most browsers will warn about it on download — SHA256SUMS on the same release is how you check you got the file we published, not a signature.

brew install mickelsamuel/migrationpilot/migrationpilot
docker run --rm -v "$PWD:/work" ghcr.io/mickelsamuel/migrationpilot:1 analyze migration.sql

On Windows in Git Bash, MSYS rewrites paths inside the mount flag, so use the Windows-form working directory instead:

docker run --rm -v "$(pwd -W):/work" ghcr.io/mickelsamuel/migrationpilot:1 analyze migration.sql

AI coding agents

Agents write migrations now. They are good at SQL and bad at knowing which statement takes an ACCESS EXCLUSIVE lock on a table with 40 million rows, and by then the outage has already happened.

MCP server. Seven tools, the important one being check_before_apply: a pass/fail gate the agent calls before it writes or runs DDL. It resolves your .migrationpilotrc.yml exactly like the CLI does, so its verdict is the verdict CI will give.

{
  "mcpServers": {
    "migrationpilot": { "command": "npx", "args": ["migrationpilot-mcp"] }
  }
}

Tool

Purpose

check_before_apply

{sql, pgVersion?, configPath?} returns {verdict: pass|fail, failOn, violations[], summary}

analyze_migration

Violations, risk score and lock analysis for one migration

analyze_migration_dir

Per-file results plus an aggregate for a whole folder

get_rule

What a rule reports, why it matters, whether it auto-fixes

suggest_fix

Auto-fixed SQL plus the violations that need a human

explain_lock

The lock one DDL statement takes and what it blocks

list_rules

The full catalogue

Claude Code plugin. integrations/claude-code/ pairs a skill that tells Claude to check migrations with a PreToolUse hook that blocks the tool call when it doesn't. It fails open on purpose: a missing install, unparseable SQL, or a timeout lets the call through with a note on stderr, because a guardrail that breaks your workflow when it can't run gets uninstalled.

claude plugin install ./integrations/claude-code

Cursor and Copilot. Copy integrations/cursor/migrationpilot.mdc into .cursor/rules/, or paste integrations/copilot/copilot-instructions-snippet.md into .github/copilot-instructions.md. Both tell the agent when to run MigrationPilot and that suppressing a rule to get past a violation is the user's call, not the agent's.

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

Posts a report as a PR comment, fails the check on critical violations, and writes a SARIF file. To feed it into Code Scanning, add an upload step (needs Advanced Security on private repos):

      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: migrationpilot-results.sarif

Without the permissions block the Action still runs. It warns, analyzes every file matching the glob instead of only the ones the PR changed, and skips the comment. The check verdict, the SARIF file and the inline annotations come from the analysis either way.

Input

Description

Default

migration-path

Glob for SQL files (required)

github-token

Token for PR comments

${{ github.token }}

pg-version

Target PostgreSQL version

17

fail-on

critical, warning, irreversible, never

critical

exclude

Comma-separated rule IDs to skip

config-file

Path to .migrationpilotrc.yml

auto-detected

database-url

Connection for production context

license-key

Org plan license key

Outputs: risk-level, violations, sarif-file.

Pre-commit

migrationpilot hook install writes a plain git hook and is Husky-aware. With the pre-commit framework instead:

repos:
  - repo: https://github.com/mickelsamuel/migrationpilot
    rev: v1.6.0
    hooks:
      - id: migrationpilot
        args: [--fail-on, warning]

Clean files print nothing. Only migrations with violations are reported.

If pre-commit install answers Cowardly refusing to install hooks with 'core.hooksPath' set, something else already owns your hooks directory — Husky sets it. Check with git config core.hooksPath, then either git config --unset-all core.hooksPath and let pre-commit manage the hooks, or keep Husky and run migrationpilot hook install, which appends to .husky/pre-commit instead of fighting it.

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

Runs on merge requests that touch migrations, keeps the JSON report as an artifact, and annotates the MR diff through GitLab Code Quality.

What it checks

112 rules: 34 critical, 78 warning, 20 auto-fixable with --fix. Ten that matter most:

Rule

Fix

What it catches

MP001

Yes

CREATE INDEX without CONCURRENTLY blocks writes for the whole build

MP002

SET NOT NULL scans the full table. Use the validated CHECK pattern

MP003

ADD COLUMN with a volatile DEFAULT rewrites the table and its indexes

MP007

ALTER COLUMN TYPE rewrites the table under ACCESS EXCLUSIVE

MP008

Several DDL statements in one transaction compound the lock duration

MP025

Yes

CONCURRENTLY inside a transaction is a runtime ERROR, not a warning

MP027

UNIQUE constraint without USING INDEX scans the table under an exclusive lock

MP055

Dropping a primary key breaks logical replication

MP070

A failed concurrent build leaves an invalid index the retry silently inherits

MP097

Dropping the index behind a constraint is rejected and aborts the migration

Browse all 112 rules, or run migrationpilot explain MP027 for one. The handbook is 20 chapters on why each hazard bites and what to do instead.

Rules adapt to --pg-version (9 through 18): REINDEX CONCURRENTLY from 12, DETACH PARTITION CONCURRENTLY from 14, the native NOT NULL ... NOT VALID path from 18.

Beyond one file

analyze --fix rewrites the 20 fixable violations in place. The rest of the surface:

Command

What it does

check <dir>

Whole directory, plus cross-file sequence analysis

simulate

Runs the migration against an ephemeral in-process PostgreSQL 18 (PGlite) and reports what actually happened

plan-fix

Step-by-step expand-contract plan for violations with no one-line fix, with deploy boundaries

mutation-test

Mutates passing migrations into dangerous near-neighbours to find holes in your config

predict

Duration estimate for an operation, calibrated by --row-count and --size

template

Generates expand-contract SQL for renames, type changes, NOT NULL, and more

plan

Visual execution timeline: lock, duration, blocking impact, transaction boundaries

rollback

Reverse DDL, graded by how recoverable it is

drift

Diffs two live schemas

precommit

Multi-file entry point the pre-commit framework calls

Twenty-four commands in total. migrationpilot --help lists them.

Sequence analysis is what a per-file linter cannot see. Three migrations that each look fine can still take one table down together:

$ 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.

Tune it with --lock-budget <seconds> and --hot-table-threshold <files>, turn it off with --no-sequence, and make it blocking with --fail-on-sequence.

--fail-on irreversible is stricter than critical: it also blocks migrations that destroy data with no down file.

Configuration

Zero-config is the default. check with no directory detects your framework, finds its migrations, and analyzes them in apply order. Fourteen are supported: Flyway, Liquibase, Alembic, Django, Knex, Prisma, TypeORM, Drizzle, Sequelize, goose, dbmate, Sqitch, Rails, Ecto. Force one with --framework prisma, or pipe any generator through --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"

Five presets: recommended (default), strict, ci, startup, enterprise. Inline, -- migrationpilot-disable MP001 suppresses a rule for the next statement and -- migrationpilot-disable-file MP001 does it for the whole file. Name no rule and it suppresses all of them.

Ed25519 license keys validate client-side. --offline skips update checks and every other network call. There is no telemetry.

Output

--format text (default), json, sarif, or markdown, plus --quiet for one gcc-style line per violation and --verbose for per-statement pass/fail.

{
  "$schema": "https://migrationpilot.dev/schemas/report-v1.json",
  "version": "1.6.0",
  "file": "migrations/001.sql",
  "riskLevel": "RED",
  "riskScore": 80,
  "violations": []
}

SARIF feeds GitHub Code Scanning, VS Code and IntelliJ: migrationpilot analyze migration.sql --format sarif --output results.sarif.

Production context

Pass --database-url and MigrationPilot opens one read-only connection to read pg_class, pg_stat_statements and pg_stat_activity. It reads no user data and runs no DDL.

That turns risk scoring from a guess into a measurement, and gives three rules the numbers they have nothing to say without: MP013 (DDL on a high-traffic table), MP014 (long-held locks on a table with millions of rows), MP019 (ACCESS EXCLUSIVE while connections are piling up).

Factor

Weight

Needs --database-url

Lock severity

0-40

No

Table size

0-30

Yes

Query frequency

0-30

Yes

GREEN is 0-24, YELLOW 25-49, RED 50-100.

Comparison

MigrationPilot

Squawk

Atlas

Rules, all free

112

40

50+ analyzers, lock analyzers Pro-only

Auto-fix

20 rules

0

0

Cross-file sequence analysis

Yes

No

No

Real execution against ephemeral PG

Yes

No

Yes, needs Docker

MCP server for agents

Yes

No

No

Framework detection

14

0

0

Config presets

5

0

0

SARIF for Code Scanning

Yes

No

No

License

MIT

Apache-2.0 / MIT

Apache-2.0 core, no free lint

Squawk: 40 rules as of v2.62.0 (Aug 2026). Atlas gates migrate lint behind a Pro login in the official binary since v0.38 (Oct 2025); the Community build keeps a basic analyzer set, but the PostgreSQL lock analyzers are Pro-only. It could not be benchmarked without a paid account. The methodology records the exact command and its refusal.

Pricing

Everything the linter does is free and unmetered: all 112 rules including the production-context ones, auto-fix, sequence analysis, simulate, every output format, the GitHub Action, the MCP server. No account, no seat count, no telemetry, MIT.

The $499/year Org plan turns the free linter into an enforceable control: one policy across repositories that developers cannot quietly disable, a JSONL audit trail of every check, and direct support from the maintainer.

Org plan · Full pricing

Architecture

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

Programmatic API

import { analyzeSQL, allRules, parseMigration, classifyLock } from 'migrationpilot';

const result = await analyzeSQL(sql, 'migration.sql', 17, allRules);
console.log(result.violations, result.overallRisk);

Sixty-nine value exports plus full TypeScript types. allRules is the same rule set the CLI runs.

Development

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

License

MIT

Available Tools

7 tools
analyze_migrationA

Analyze a PostgreSQL migration SQL for safety issues. Returns violations, risk level, and lock analysis.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesThe SQL migration to analyze
pg_versionNoTarget PostgreSQL version (default: 17)

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden. It discloses that the tool performs analysis and returns violations, risk level, and lock analysis, which is useful. However, it does not explicitly state whether it is read-only, requires a database connection, or executes the SQL, leaving some behavioral ambiguity.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the purpose and mentions key return values. Every word earns its place, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two parameters, full schema coverage, and no output schema, the description adequately covers purpose and high-level outputs. It lacks detailed guidance on the structure of violations or risk level, but this is not critical for selection and invocation given the schema coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and both parameters (sql and pg_version) have meaningful descriptions in the schema. The tool description adds no additional parameter semantics beyond what the schema provides, which aligns with the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool analyzes a PostgreSQL migration SQL for safety issues and specifies its outputs (violations, risk level, lock analysis). It is specific enough to distinguish from siblings like analyze_migration_dir, though it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when you have a single migration SQL to analyze, but provides no explicit guidance on when to use this tool versus sibling tools like check_before_apply or suggest_fix. No when-not or alternative mentions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

analyze_migration_dirA

Analyze every migration file in a directory. Returns per-file results plus an aggregate summary. Use this to audit a whole migrations folder before a release, or to find which existing migration introduced a risky pattern.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesPath to the migrations directory
patternNoGlob pattern for SQL files, relative to path (default: **/*.sql, or the config's migrationPath)
pgVersionNoTarget PostgreSQL version. Defaults to the config's pgVersion, or 17.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of disclosure. It mentions the output structure (per-file results plus aggregate summary) and implies a read-only analysis, but it does not explicitly state that files are not modified, nor does it mention any requirements or side effects. This is useful context but leaves gaps about safety and exact behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core action, and includes return format and usage guidance without any fluff. Every word adds value, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 3 parameters, no output schema, and no annotations, the description covers the main purpose, output shape, and suggested use cases. It stops short of explaining what 'analyze' means in terms of rules or checks, but the sibling tools like 'list_rules' and 'get_rule' imply a rule system. Overall, it is fairly complete for making an informed selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, so the input schema already documents all three parameters (path, pattern, pgVersion) with clear descriptions. The tool description adds no additional parameter-level meaning, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Analyze every migration file in a directory' with a specific verb and resource scope, distinguishing it from the sibling 'analyze_migration' by emphasizing directory-wide analysis. It also notes the return format (per-file results plus aggregate summary), making the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage context: 'Use this to audit a whole migrations folder before a release, or to find which existing migration introduced a risky pattern.' This clearly indicates when to choose this tool over alternatives, though it does not explicitly name the single-file sibling or give exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_before_applyA

Safety gate: call this BEFORE writing or executing any PostgreSQL DDL or migration. Resolves the project's own MigrationPilot config (rule toggles, severity overrides, failOn threshold) exactly like the CLI, then returns a pass/fail verdict. On "fail", do not apply the migration — fix the blocking violations and check again.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesThe exact SQL that is about to be written or executed
pgVersionNoTarget PostgreSQL version. Defaults to the config's pgVersion, or 17.
configPathNoPath to a config file, or a directory to resolve config from. Defaults to searching upward from the working directory, exactly like the CLI.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It discloses that the tool is non-mutating (it is a 'check' that returns a verdict), explains config resolution ('exactly like the CLI'), and instructs the agent on failure behavior. It doesn't explicitly state it makes no writes to the database, but the safety-gate framing and 'returns a verdict' imply it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with 'Safety gate.' Each sentence provides necessary context: when to call, what it does, and how to handle the verdict. No redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 3 params and no output schema, the description covers the critical points: use case, behavior, and outcome ('pass/fail verdict'). It could describe the verdict structure or error cases, but for a safety gate the essential info is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds only minor reinforcement (e.g., 'exactly like the CLI' for configPath, 'exact SQL' for sql) but no substantive meaning beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the tool as a 'Safety gate' with the specific verb 'call this BEFORE writing or executing any PostgreSQL DDL or migration.' It states the function (resolves config, returns verdict) and differentiates from siblings like analyze_migration or suggest_fix because it is explicitly a gate that blocks application.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use ('BEFORE writing or executing any PostgreSQL DDL or migration') and provides the rule for fail ('do not apply the migration'). However, it doesn't explicitly state when NOT to use it (e.g., for read-only queries), leaving the exclusion to interpretation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

explain_lockA

Explain what PostgreSQL lock a DDL statement acquires and its impact.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesA single DDL statement to analyze
pg_versionNoTarget PostgreSQL version (default: 17)

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It only states the tool 'explains' lock acquisition, without disclosing whether the DDL is executed, if a database connection is needed, or if there are any side effects. This is a significant gap for a tool that could potentially run DDL.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence of 13 words, front-loading the action and the resource. It contains no filler or redundant wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema or annotations, the description provides only the core function. It does not explain what the explanation looks like, how pg_version changes behavior, or what 'impact' refers to. Adequate but with clear room for additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides full descriptions for both parameters (sql and pg_version) with 100% coverage. The tool description adds no additional parameter detail beyond its core purpose, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Explain') and a clear resource ('PostgreSQL lock a DDL statement acquires'), distinguishing it from sibling tools that focus on migration analysis or fixes. It unambiguously states the tool's function.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for analyzing lock behavior of DDL statements, but provides no explicit context or alternatives. It does not mention when to use this tool versus sibling tools like analyze_migration or check_before_apply.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ruleA

Get the full documentation for one MigrationPilot rule: what it reports, why it matters, whether it can be auto-fixed, and how to configure it. Call this when a violation ID appears and you need the reasoning behind it before rewriting a migration.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlNoOptional SQL to run this one rule against. When the rule fires, the response carries the exact violation message and the concrete safe alternative for that statement.
ruleIdYesRule ID, e.g. MP001 (case-insensitive)

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It reveals that the tool returns documentation details (what it reports, why it matters, auto-fix capability, configuration) and implies it is a read-only lookup operation. It does not state potential side effects or permissions, but for a documentation retrieval tool, the behavior is clear and appropriately disclosed. The addition of specific return content adds value beyond the name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, each earning its place. The first sentence defines the tool's output comprehensively, and the second sentence gives the exact usage trigger. There is no redundancy or fluff, making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with only two parameters and no output schema, the description is complete. It explains what the tool does, what content it returns, when to use it, and how it relates to the migration workflow. The lack of an output schema is mitigated by the description's clear enumeration of return contents. Sibling tools are implicitly distinguished, and no critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both parameters ('ruleId' and 'sql') well-documented in the schema. The description does not add parameter-specific information, but it also does not need to because the schema already provides clear examples and semantics. The baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get') and resource ('full documentation for one MigrationPilot rule'), and enumerates exactly what the documentation includes. It also distinguishes the tool from siblings by emphasizing 'one rule' and the use case of needing reasoning before rewriting, which is unique among the listed sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use the tool: 'Call this when a violation ID appears and you need the reasoning behind it before rewriting a migration.' This provides a clear trigger, but it does not explicitly name alternative tools or contrast with them. Since it gives a direct use case without exclusions, it earns a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rulesA

List all available MigrationPilot safety rules with descriptions.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. 'List' implies a read-only operation, and the phrase 'with descriptions' indicates return content. However, it does not disclose potential auth requirements, pagination, or ordering behavior. For a simple listing tool this is minimally adequate but lacks richer behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, front-loaded with the action verb 'List', and every word earns its place. It is succinct and clearly structured, with no redundant or vague language.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only listing tool, the description covers the core purpose and return essence. It could optionally mention how the output relates to get_rule or describe the expected response structure, but given the low complexity, it is nearly complete. The absence of an output schema is partially mitigated by the note about descriptions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has zero parameters, so the baseline is 4 per the rubric. The description adds no parameter-specific info, but none is needed since the tool takes no inputs. Schema coverage is effectively 100% with no properties, so there is no gap to compensate for.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'List' with a clear resource: 'all available MigrationPilot safety rules with descriptions.' This distinguishes it from sibling tools like get_rule, which presumably fetches a single rule, and from analysis or fix tools. It unambiguously states the scope and output content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for enumerating all safety rules, but it does not explicitly state when to prefer this over alternatives. The sibling get_rule suggests a complementary use case (retrieving a specific rule), but no explicit when-to-use or alternatives are mentioned, leaving the guidance implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

suggest_fixA

Auto-fix safe violations in a PostgreSQL migration SQL. Returns the fixed SQL and list of changes.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesThe SQL migration to fix
pg_versionNoTarget PostgreSQL version (default: 17)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It does add useful context by stating that it returns fixed SQL and a list of changes, but 'safe violations' is vaguely defined, and there is no disclosure of side effects, permissions, or whether changes are applied directly. This is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that is front-loaded with the action and scope, and it includes the return value. Every word earns its place, with no fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must explain the return value; it does say it returns fixed SQL and a list of changes, but without detailing the structure of the changes list. It also doesn't clarify the definition of 'safe violations' or how this tool relates to check_before_apply, which could be important given the sibling tools. Overall, it is functional but leaves several gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for both parameters (sql and pg_version), so the baseline is 3. The description adds no additional parameter-specific semantics beyond what the schema already provides, and no extra context about how the parameters affect the fix behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Auto-fix' with a clear resource ('PostgreSQL migration SQL') and scope ('safe violations'). It also states what it returns (fixed SQL and list of changes), making it clearly distinguishable from siblings like analyze_migration and check_before_apply.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool (when there are safe violations to fix) but does not explicitly mention alternatives or exclusions. No context about when to choose suggest_fix over check_before_apply or analyze_migration is provided, so the usage guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

TDQS

A4.1/5.0
Disambiguation5/5

Each tool targets a distinct operation: single-file analysis, directory analysis, fix suggestion, lock explanation, rule listing, rule documentation, and pre-apply gate. There is no meaningful overlap between tool purposes.

Naming Consistency5/5

All tool names follow a clear verb_noun snake_case pattern (analyze_migration, suggest_fix, explain_lock, list_rules, check_before_apply, analyze_migration_dir, get_rule). The naming is consistent and predictable.

Tool Count5/5

With 7 tools, the server is well-scoped for its purpose. Each tool earns its place, covering analysis, fixing, explanation, rule management, and pre-apply checks without unnecessary bloat.

Completeness5/5

The tool surface covers the full migration safety workflow: analyzing individual migrations, auditing directories, understanding rules, getting rule details, auto-fixing issues, explaining locks, and gatekeeping before apply. No critical gaps are evident.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    AI-native PostgreSQL health checker with 26 MCP tools for query analysis, bloat detection, migration safety, and CI integration.
    16
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    LLM-assisted, safety-gated Postgres migrations exposed as an MCP server, using a deterministic rule engine over Postgres's own parser AST for safety enforcement, with two-phase approval and append-only audit ledger.
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Governed PostgreSQL DBA operations — slow-query, bloat, and blocking-lock RCA, index management, vacuum/analyze, and replication lag, with unbypassable audit logging (MCP + CLI), budget/runaway guards, dry-run, and undo/rollback.
    35
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mickelsamuel/migrationpilot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server