Skip to main content
Glama

sql_migration_lint

Read-onlyIdempotent

Static lint of a SQL migration file (Postgres or MySQL) for operations that lock or rewrite live tables or break running application code. Flags CREATE INDEX without CONCURRENTLY and concurrent index builds inside a transaction, foreign key, CHECK and UNIQUE constraints added without NOT VALID or USING INDEX, SET NOT NULL without a validated CHECK, column type changes, NOT NULL columns added without a default, volatile or serial defaults that rewrite the table, dropped or renamed columns and tables, VACUUM FULL and CLUSTER, DELETE or UPDATE without WHERE, TRUNCATE, a missing lock_timeout, MySQL ALTERs without ALGORITHM/LOCK, and type advice (jsonb, text, identity, timestamptz). Tables created earlier in the same file are treated as new and skipped by lock and rewrite rules. The SQL is tokenized, never executed: no database is contacted, so table sizes and existing column types are unknown, and SQL inside strings, comments and function bodies is not linted. Up to 400 KB of SQL and 5,000 statements. Rules adapted from squawk and strong_migrations. Deterministic, no LLM.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "sql": "<sql>"
    },
    "name": "sql_migration_lint"
  }
}

Input Schema

NameRequiredDescriptionDefault
sqlYesThe migration file content. Max 400 KB (UTF-8); 512 KB request body.
dialectNoSQL dialect. "postgresql" and "pg" are also accepted, case-insensitive.postgres
assume_large_tablesNoTreat existing tables as large and busy. false downgrades lock and rewrite errors (index without CONCURRENTLY, foreign key or unique without NOT VALID / USING INDEX, type change, SET NOT NULL, VACUUM FULL / CLUSTER) to warnings; data-loss and compatibility rules are never downgraded.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Added

TDQS

A4.1/5.0
Behavior5/5

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

The annotations only declare read-only/idempotent/non-destructive; the description adds substantively: tokenized and never executed, no database contacted, table sizes and existing column types therefore unknown, deterministic with no LLM, rules adapted from squawk and strong_migrations, and tables created earlier in the file are skipped. It also states hard limits (400 KB, 5,000 statements), which an agent needs to avoid oversized calls.

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

Conciseness3/5

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

Purpose is front-loaded and the closing sentences on scope and limits are tight. However, the middle is a single run-on sentence enumerating a dozen-plus rule names verbatim, which is dense to parse and could be compressed into categories without losing routing value.

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, yet the return shape is never described — only the error/warning distinction is implied via assume_large_tables downgrading and "type advice." For an agent to act on results it would help to know the finding structure and whether the response is a flat list or grouped by severity.

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?

All three parameters are fully described in the schema (100% coverage), including the enum and the assume_large_tables downgrade behavior, so the description properly defers. It adds only marginally, restating the 400 KB cap and mentioning that data-loss and compatibility rules are never downgraded — context rather than new parameter meaning.

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?

Names a specific verb and resource ("Static lint of a SQL migration file") and scopes the dialects supported. The follow-on enumeration of flagged patterns distinguishes it from the many generic *lint siblings (regex_lint, story_lint, mcp_tool_lint) without ambiguity.

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?

Clear context for use: a Postgres or MySQL migration file, static analysis before applying. It also states what it will not catch (SQL in strings, comments, function bodies) and that no DB is contacted, which implicitly frames when its verdicts are trustworthy. It never explicitly names an alternative tool or a when-not-to-use case, so it stops short of a 5.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.