PreSQL
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@PreSQLCheck if DELETE FROM orders; is safe to run"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
PreSQL — a seatbelt for AI-generated SQL
An MCP server that validates SQL before it runs. Give it your schema; it gives your agents three tools:
Tool | What it does |
| Validates a statement against your schema → |
| Explains what a statement does in plain English (no verdict — for understanding before deciding) |
| Pre-execution go/no-go hook → |
Database MCP servers give agents access. PreSQL checks the SQL before it goes in. It composes with any of them — point your agent at both.
Zero network at runtime. Zero config to try. MIT licensed.
Quickstart
npx -y @k1sh0r3/presqlThat runs with a built-in demo e-commerce schema. To use your own:
npx -y @k1sh0r3/presql --schema ./schema.sql
# or
SQL_GUARD_SCHEMA=./schema.sql npx -y @k1sh0r3/presql
# or inline DDL:
SQL_GUARD_DDL="CREATE TABLE users (id INT, email VARCHAR(255));" npx -y @k1sh0r3/presqlSchema resolution order: --schema flag → SQL_GUARD_SCHEMA env → SQL_GUARD_DDL env → demo/schema.sql → built-in demo schema.
Related MCP server: SQL Server MCP Server
Connect your agent
Claude Desktop (claude_desktop_config.json) or Cursor:
{
"mcpServers": {
"presql": {
"command": "npx",
"args": ["-y", "@k1sh0r3/presql", "--schema", "/path/to/schema.sql"]
}
}
}Then: "Before running any SQL against the database, check it with presql's guard_query."
What it catches
Schema-aware validation powered by the SQL Sentinel engine (13 check codes):
DESTRUCTIVE_NO_WHERE—DELETE/UPDATEwithoutWHERE→ blockedDESTRUCTIVE_UNBOUNDED—DROP,TRUNCATE→ blockedUNKNOWN_TABLE/UNKNOWN_COLUMN— with Levenshtein did-you-mean suggestionsTYPE_MISMATCH,AMBIGUOUS_COLUMN,IMPLICIT_CROSS_JOIN,CROSS_JOINPII_ACCESS— flags selects over PII-ish columns (name-heuristic)SELECT_STAR,MISSING_LIMIT— hygiene nudgesPARSE_ERROR,SCHEMA_MISSING,MULTI_STATEMENT— honest meta-checks
Example:
> validate_sql("DELETE FROM orders;")
{
"verdict": "blocked",
"issues": [{
"code": "DESTRUCTIVE_NO_WHERE",
"severity": "error",
"message": "DELETE without WHERE affects every row in the table.",
"suggestion": "Add a WHERE clause — or run a SELECT with the same filter first to preview the blast radius."
}],
"explanation": "Deletes EVERY row from orders."
}Honest limits
Static analysis only. It can't know row counts or see your data.
CTE/subquery output columns are skipped, not faked — where certainty is impossible, it says so.
PII detection is name-heuristic only (column named
email≈ PII). Not a compliance tool on its own.One statement per call. Multi-statement input validates the first statement and warns (
MULTI_STATEMENT).AST-evasion hardening (quoted/unicode-escaped identifier tricks, cf. AWS's pglast guard) is a v1.1 target — not claimed as solved.
English error messages;
postgres/mysql/sqliteparse dialects.
Development
npm install
npm run build # tsc → dist/
npm test # build + node --test (41 tests: 30 engine + 11 MCP protocol)
npm start # run the server over stdioThe validator (src/vendor/validator.js) and SQL parser (src/vendor/node-sql-parser.umd.js) are copied verbatim from SQL Sentinel — the engine is shared, not forked.
License
MIT — see LICENSE.
Available Tools
3 toolsexplain_sqlA
Explain a SQL statement in plain English. No verdict, no judgment — for understanding what a query does before deciding whether to run it.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | The SQL statement to check. | |
| dialect | No | SQL dialect used to parse the statement. | postgres |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully implies the tool is non-evaluative and (via 'before deciding whether to run it') likely does not execute the statement, which is real added value. But it says nothing about permissions, cost/rate limits, or what the returned explanation looks like.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the core action and followed by the one scoping caveat that matters. Nothing is wasted and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no output schema, the description should ideally sketch the shape of the explanation returned or note dialect-fallback behavior. It covers intent and the no-judgment scope but stops short of that, leaving a modest gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both 'sql' and 'dialect' are already documented in the schema, including the enum values and default. The description adds no dialect guidance or format hints beyond that, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource: explains a SQL statement into plain English. The clause 'No verdict, no judgment' implicitly distinguishes it from validate_sql/guard_query, but those siblings are never named, so an agent must infer the boundary rather than being told.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'For understanding what a query does before deciding whether to run it' gives a clear use context and implies ordering relative to execution. However, it never names validate_sql or guard_query, nor states when to pick this over validation or guarding — the distinction is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
guard_queryA
Pre-execution safety hook for AI-generated SQL. Returns a go/no-go decision (allow/review/block) with a human-readable reason and the underlying verdict. Designed to be called before handing SQL to a database MCP server or executing it.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | The SQL statement to check. | |
| dialect | No | SQL dialect used to parse the statement. | postgres |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose meaningful behavior: the three-way decision model, that a human-readable reason and the underlying verdict are returned, and implicitly that it does not execute the SQL. It omits operational traits such as side effects, auth needs, or error behavior, but the return semantics are unusually well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, both load-bearing: the first defines the tool and its return shape, the second states when to call it. The most important information is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with no output schema, the description adequately explains what comes back and when to call it. Its one real gap is the unresolved overlap with validate_sql, which the description should have disambiguated given the sibling set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the sql and dialect parameters are already documented in the schema, including the enum and default. The description adds no syntax, format, or dialect-specific guidance beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific function: a pre-execution safety check on AI-generated SQL that returns an allow/review/block verdict. It is clear what the tool does, but it never distinguishes itself from the sibling validate_sql, which an agent could easily confuse it with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit timing guidance ('Designed to be called before handing SQL to a database MCP server or executing it'), which tells the agent exactly where this fits in a workflow. It stops short of naming alternatives or stating when not to use it, especially versus validate_sql.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_sqlA
Validate a SQL statement against the configured schema. Returns a verdict (safe/review/blocked), a list of issues with codes, severities, messages and fix suggestions, plus a plain-English explanation. Call this before executing AI-generated SQL.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | The SQL statement to check. | |
| dialect | No | SQL dialect used to parse the statement. | postgres |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and largely meets it: it discloses the output taxonomy (safe/review/blocked verdicts, issue codes, severities, messages, fix suggestions, plus a plain-English explanation). It does not state whether validation is purely static or requires a live connection, and it never confirms that the SQL is not executed — a meaningful omission for a guardrail tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with purpose, then return shape, then the call condition. Nothing is redundant and every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema and no annotations, so the description must explain both purpose and returns — and it describes the verdict and issue structure well. The remaining gap is behavioral rather than structural: no statement about side effects, permissions, or whether a schema must be pre-configured for the call to succeed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (sql, dialect) are already documented in the schema with an enum and default. The description adds no syntax, format, or dialect-specific guidance beyond that, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ("Validate a SQL statement against the configured schema") and immediately names the artifact produced (a verdict). It does not differentiate itself from the sibling guard_query, which plausibly also performs SQL safety checking, leaving the agent to infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit trigger — "Call this before executing AI-generated SQL" — which tells the agent when this tool belongs in a workflow. It offers no when-not condition and never names explain_sql or guard_query as alternatives, so the routing guidance is incomplete but the positive case is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
explain_sql - First observed
guard_query - First observed
validate_sql
TDQS
Scored across 3 tools
validate_sql and guard_query overlap heavily: both return a safety verdict (safe/review/blocked vs allow/review/block) with reasons, differing mainly in framing. explain_sql is clearly distinct (no judgment), but an agent could easily struggle to choose between validate and guard.
All three tools follow a clean verb_noun snake_case pattern (validate_sql, explain_sql, guard_query) with no mixing of conventions.
Three tools is well-scoped for a focused SQL safety server, though the overlap between validate_sql and guard_query makes one of them feel somewhat redundant rather than each earning a distinct place.
The domain (pre-execution SQL validation and understanding) is largely covered: validate, explain, and guard. Coverage is adequate, though the surface is thin and could benefit from e.g. schema-aware fix application or batch validation.
Maintenance
Related MCP Connectors
Deterministic safety, correctness & cost gate that vets Postgres SQL before your AI agent runs it.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Deterministic validation for AI-generated artifacts: JSON Schema, OpenAPI response, SQL syntax.
Pre-execution governance for AI agents. Deterministic PASS/FAIL/REVIEW verdicts, replayable proof.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceValidates SQL queries via AST parsing, ensuring they are single read-only SELECTs on allowed tables with enforced LIMITs, and masks PII columns based on user roles. Provides a tamper-evident audit log and runs fully offline.1MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to inspect schemas, analyze performance, check security, and troubleshoot SQL Server 2019+ databases through a safe, controlled interface.-
- AlicenseNot gradedqualityCmaintenanceEnforces safety and governance for SQL queries executed by AI agents, providing read-only enforcement, cost estimation, and audit trails.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables analytics agents to run validated read-only SQL against a warehouse API with enforced row limits, required JSON responses, and secret-safe audit metadata.MIT