Skip to main content
Glama

Locksmith 🔒

An MCP server that catches dangerous SQL migrations before they lock your database.

Most migrations look harmless and then take down production: a plain CREATE INDEX blocks every write for the length of the build; ALTER COLUMN ... TYPE rewrites the whole table under ACCESS EXCLUSIVE; SET NOT NULL scans every row. Which operations are safe — and the rewrite that makes the dangerous ones safe — is knowledge that lives in senior engineers' heads.

Locksmith encodes that knowledge as a tool an LLM agent (or a human) can call. Give it a PostgreSQL migration; it returns a PASS / REVIEW / BLOCK verdict, a finding for each risky statement (which lock it takes, why that's dangerous), and a concrete safe rewrite.

🛑 BLOCK — do not ship as written

## 🛑 CREATE INDEX without CONCURRENTLY  `create-index-non-concurrent` (line 5)
> `CREATE INDEX idx_users_email ON users (email)`
Problem: This index build will block all writes to the table until it completes.
Lock taken: SHARE (blocks writes)
Fix: Build the index with CREATE INDEX CONCURRENTLY, which does not block writes.
Suggested rewrite:
  CREATE INDEX CONCURRENTLY idx_users_email ON users (email)

Why an MCP server?

An agent can often reason about lock semantics — but not reproducibly, and not in a way you can test, audit, or trust to gate a deploy unsupervised. The same prompt may approve a table-rewriting ALTER one run and flag it the next, or miss it entirely in a long migration. Locksmith turns that probabilistic capability into a deterministic, tested tool: the lock semantics were verified once (against the PostgreSQL docs and the parser's real behavior, with a test suite pinning each rule) and now run identically every time, returning the same verdict plus a paste-ready fix — so "review this migration" stops being a guess.

Related MCP server: migratoor

Capabilities

Tools

  • analyze_migration(sql, assumeLargeTables?) → verdict + findings + safe rewrites (both human-readable Markdown and validated structured output).

  • explain_lock(query) → what a given Postgres lock mode blocks and what takes it.

Resources

  • locksmith://lock-matrix — the PostgreSQL table-level lock compatibility matrix.

  • locksmith://rules — the full rule catalog (id, severity, rationale) as JSON.

Prompts

  • review-migration — analyze a migration and summarize the risk as a PR comment.

Rule catalog

Rule

Severity

What it catches

create-index-non-concurrent

critical

CREATE INDEX without CONCURRENTLY (blocks writes)

index-concurrently-in-transaction

critical

CONCURRENTLY inside BEGIN/COMMIT (Postgres rejects it)

add-column-not-null-no-default

critical

ADD COLUMN NOT NULL with no default (fails / rewrites)

alter-column-type

critical

ALTER COLUMN ... TYPE (full table rewrite)

add-column-volatile-default

warning

ADD COLUMN ... DEFAULT now() etc. (rewrites table)

set-not-null

warning

SET NOT NULL (full scan under exclusive lock)

add-foreign-key-validating

warning

ADD FOREIGN KEY without NOT VALID (locks both tables)

add-check-constraint-no-not-valid

warning

ADD CHECK without NOT VALID (full scan)

drop-column-or-table

warning

destructive + breaks deployed code

rename-column-or-table

warning

breaks running app code

Suppressing a rule

Acknowledge a deliberate risk inline, eslint-style:

-- locksmith:disable create-index-non-concurrent
CREATE INDEX idx_users_email ON users (email);

A bare -- locksmith:disable suppresses all rules for the next statement.

Install & run

No clone or build required — run it straight from npm:

npx locksmith-mcp

Use with Claude Code

claude mcp add locksmith -- npx -y locksmith-mcp

Or add to any MCP client config (Claude Desktop, etc.):

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

Run from source instead

git clone https://github.com/cxk280/locksmith.git && cd locksmith
npm install && npm run build
# then point your client at:  node /absolute/path/to/locksmith/dist/index.js

Try it with the MCP Inspector

npx @modelcontextprotocol/inspector npx -y locksmith-mcp

Then call analyze_migration with the contents of examples/dangerous.sql.

Development

npm run dev    # run from source with tsx
npm test       # vitest: per-rule + golden tests on examples/

Design notes

  • Deterministic. No clock, randomness, or network — same SQL in, same verdict out. That's what makes it testable and safe to drop into CI.

  • Hybrid parsing. Statements are parsed to an AST (pgsql-ast-parser) when the parser supports them; rules fall back to normalized text for Postgres clauses the parser doesn't model (NOT VALID, CONCURRENTLY). An unparseable statement degrades to a "review manually" note — the linter never fails closed on input it doesn't understand.

  • Composable rules. Each rule is a pure function with its own metadata in its own file; adding one is a one-file change plus a line in the registry.

  • Advisory, not a prover. Locksmith complements review; assumeLargeTables defaults to true so it errs toward flagging.

Roadmap

  • Remote (Streamable HTTP) transport for hosted deployments.

  • Additional dialects (MySQL, SQLite).

  • Optional live DB introspection to suppress findings on known-small tables.

  • A GitHub Action wrapping the same engine to gate PRs.

License

MIT

Available Tools

2 tools
analyze_migrationAnalyze a SQL migration for locking hazardsA

Lint a PostgreSQL migration for operations that take dangerous locks (table rewrites, blocking index builds, validating constraints, destructive/breaking changes) and return a PASS/REVIEW/BLOCK verdict with per-statement findings and safe rewrites. Call this before applying or approving any migration.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesThe full SQL migration script to analyze.
assumeLargeTablesNoAssume target tables are large/hot, so scans and rewrites are flagged. Default true (fail safe).

Output Schema

ParametersJSON Schema
NameRequiredDescription
statsYes
summaryYes
verdictYes
findingsYes

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 provides substantial behavioral detail: it lists specific hazard types (table rewrites, blocking index builds, validating constraints, destructive changes) and the return format (verdict with findings and safe rewrites). It does not explicitly state whether it performs static analysis or side effects, but the linting framing implies a read-only operation.

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 long, with the first sentence packed with specific technical detail and the second giving direct usage guidance. 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?

Given the description, input schema with parameter semantics, and the presence of an output schema, the tool is well specified for an agent to select and invoke it. The only gap is not explicitly stating whether it performs static analysis or requires a database connection, but the linting context and output schema make this adequate.

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 assumeLargeTables) with 100% coverage. The tool description adds no additional parameter semantics beyond what the schema offers, so the 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 the tool's function: 'Lint a PostgreSQL migration for operations that take dangerous locks' and the output verdict (PASS/REVIEW/BLOCK). It distinguishes from the sibling tool 'explain_lock' by focusing on migration linting and returning safe rewrites, not just explaining locks.

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 'Call this before applying or approving any migration,' which gives clear usage context. It does not mention when not to use it or name alternative tools, but the timing guidance is direct and actionable.

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

explain_lockExplain a PostgreSQL lock modeA

Given a lock mode name (e.g. 'ACCESS EXCLUSIVE') or a fragment of an operation, explain what it blocks and which operations acquire it.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesA lock mode name or operation fragment, e.g. 'ACCESS EXCLUSIVE' or 'create index'.

TDQS

A3.8/5.0
Behavior3/5

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

There are no annotations, so the description carries the full burden. It discloses the core behavior (accepts fragments, explains blocking and acquisitions) but does not detail edge cases such as how ambiguous inputs are handled, whether multiple results are returned, or error behavior. This is adequate for a simple read-only tool but lacks explicit safety or limitation notes.

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, well-structured sentence that front-loads the input condition and clearly states the output. Every word contributes to understanding the tool's purpose and behavior, with no redundancy or fluff.

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's simplicity (one parameter, no output schema), the description sufficiently conveys what the tool does, what input to provide, and what the explanation covers. It lacks details about response format or error handling, but these are not critical for a straightforward explanation tool, making it complete enough for correct invocation.

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 provides full coverage of the single parameter 'query' with a clear description and examples. The tool description repeats the same examples without adding new meaning beyond the schema, so it contributes no additional value, meeting the baseline for high schema coverage.

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 states a specific action ('explain') and resource ('PostgreSQL lock mode'), and clearly defines the input type (lock mode name or operation fragment) and the output (what it blocks and which operations acquire it). This clearly differentiates from the sibling tool 'analyze_migration', which presumably focuses on migration analysis.

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 one needs to know about lock modes, but it does not explicitly state when to use this tool versus alternatives, nor does it mention any exclusions or preconditions. There is no contrast with the sibling tool, so guidance is only implicit.

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

TDQS

A4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: analyze_migration scans migrations for risky lock operations, while explain_lock describes lock modes and blocking behavior. There is no overlap or ambiguity between them.

Naming Consistency5/5

Both tool names follow a consistent verb_noun pattern: analyze_migration and explain_lock. The naming is predictable and clearly reflects each tool's action and target.

Tool Count3/5

With only two tools, the server feels minimal but still coherent for its narrow domain of PostgreSQL lock safety. It is borderline thin, but the two tools cover the primary use case of analyzing migrations and understanding locks, so the count is acceptable.

Completeness4/5

The tool surface covers the full workflow of checking a migration for dangerous locks and providing educational support on lock modes. Minor gaps exist, such as no tool for inspecting live database locks or comparing lock compatibility, but the core purpose is well-served.

Maintenance

ActivityStale
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • 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
    B
    quality
    C
    maintenance
    An open-source MCP server for PostgreSQL that provides database health analysis, index tuning, query plan optimization, and safe SQL execution, suitable for both development and production environments.
    9
    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/cxk280/locksmith'

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