Skip to main content
Glama
pg-migration-guard

pg-migration-guard

pg-migration-guard

An MCP server and CLI that stops AI coding agents (and humans) from shipping Postgres migrations that lock production tables.

AI coding tools are great at migration syntax. They don't know your table has 40 million rows, that CREATE INDEX blocks every write until it finishes, or that a "harmless" ALTER TABLE waiting on a lock queues every query behind it. The migration finishes in 10 ms on a laptop and takes the checkout API down in production.

pg-migration-guard gives the agent that missing knowledge. Connect it to Claude Code, Claude Desktop, Cursor or any MCP client, and the agent can check a migration before it runs it. Each finding comes with the safer rewrite.

[HIGH] line 6  create-index-not-concurrently
  CREATE INDEX idx_orders_customer ON orders (customer_id)
  Why: CREATE INDEX takes a SHARE lock: reads keep working, but every INSERT, UPDATE and
       DELETE on the table waits until the index is built. On a large table that can be minutes.
  Fix: Use `CREATE INDEX CONCURRENTLY` (outside a transaction).
  • Zero runtime dependencies. The MCP protocol layer (JSON-RPC 2.0 over stdio) is implemented directly. Nothing to audit in your supply chain.

  • Deterministic. Rules, not a model. Same SQL in, same answer out. That makes it safe to use as a gate.

  • Works in CI too. The CLI exits non-zero on high-severity findings.

What it checks

Severity

Rule

Why it hurts

high

create-index-not-concurrently

SHARE lock blocks all writes during the build

high

concurrently-in-transaction

CONCURRENTLY fails inside a transaction (most migration tools use one)

high

reindex-not-concurrently

Blocks writes, and reads that use the index

high

add-column-rewrite

Volatile default, serial, or stored generated column rewrites every row (any default before PG 11)

high

set-not-null

Full scan under ACCESS EXCLUSIVE (recognises the PG 12+ CHECK ... VALIDATE workaround)

high

alter-column-type

Usually a full table and index rewrite

high

add-foreign-key-validated

Scans while holding SHARE ROW EXCLUSIVE on both tables

high

add-unique-or-pk-without-index

Builds a unique index under ACCESS EXCLUSIVE

high

full-table-lock-maintenance

VACUUM FULL / CLUSTER lock the table for the whole run

medium

missing-lock-timeout

A blocked ALTER queues every query behind it

medium

add-check-validated

Full scan under ACCESS EXCLUSIVE

medium

add-column-not-null-no-default

Fails on any non-empty table

medium

drop-index-not-concurrently

ACCESS EXCLUSIVE on the table

medium

rename / drop-column / drop-table

Breaks app instances still running the old code

Tables created earlier in the same migration are exempt, because they are empty.

Related MCP server: MigrationPilot

Use it from an AI agent (MCP)

git clone https://github.com/saimulhasnain-dev/pg-migration-guard && cd pg-migration-guard
npm install && npm run build

Claude Code

claude mcp add pg-migration-guard -- node /absolute/path/to/pg-migration-guard/dist/src/server.js

Claude Desktop / Cursor (claude_desktop_config.json or .cursor/mcp.json)

{
  "mcpServers": {
    "pg-migration-guard": {
      "command": "node",
      "args": ["/absolute/path/to/pg-migration-guard/dist/src/server.js"]
    }
  }
}

Then add one line to your project's CLAUDE.md / agent rules:

Before running or committing any Postgres migration, call analyze_migration and apply its fixes.

Tools

Tool

Input

Returns

analyze_migration

sql (required), postgres_version (default 16), assume_transaction

Readable report + structuredContent with every finding

list_rules

none

All rules and severities

Use it in CI

node dist/src/cli.js migrations/*.sql                 # fail on high
node dist/src/cli.js --fail-on medium --tx --pg 15 db/migrate/*.sql
node dist/src/cli.js --json migrations/2026_add_index.sql

--tx tells it your tool wraps each file in a transaction (Rails, Django, Prisma and Knex do by default), so CONCURRENTLY inside one gets flagged.

Try it

npm run build
node dist/src/cli.js examples/risky.sql   # 5 high, 2 medium
node dist/src/cli.js examples/safe.sql    # the same changes, done safely: clean
npm test                                  # 19 tests, including a real MCP stdio session

Limitations

It's pattern-based, not a full SQL parser. It doesn't look inside DO blocks or function bodies, and it can't know your table sizes. A finding on a 200-row lookup table may be fine to ignore. Treat it as a reviewer that never forgets the lock rules, not as a replacement for knowing your data.

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Blocks unsafe PostgreSQL migrations before an AI agent writes or runs them. check_before_apply returns a pass/fail gate; reads the real Postgres parser, classifies the lock each statement takes, checks 112 safety rules. Runs offline, no database required.
    7
    611 npm
    9
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables checking Postgres migration SQL against a table-size estate snapshot and safety policy before apply, returning approve/block verdicts with lock details and remediation guidance, plus tools to explain locks and list policy rules.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Exposes read-only tools that let AI assistants detect schema drift, analyze lock impact, verify data with checksums, and plan safe PostgreSQL migrations that are validated by deterministic checks and shadow runs.
    58 npm
    Apache 2.0