Static SQL safety analysis for AI agents. Catch the dangerous queries before they reach your database.
What it does
Your AI agent generates a SQL query. Before you run it, @vibeguard-dev/local
checks the query's structure for known footguns: missing WHERE clauses,
cartesian explosions, type-coercion bugs, recursive CTEs that don't
terminate. 12 senior-DBA-level checks, all static, sub-millisecond,
zero network calls.
Quickstart
npm install @vibeguard-dev/local libpg-query
libpg-query is a peer dependency — install it alongside the SDK.
Server-side Node only for the initial release; browser support is
out of scope for now.
ESM
import { analyze, init } from "@vibeguard-dev/local"; await init(); // one-time WASM-parser bootstrap const result = analyze(`UPDATE users SET email = 'x@y.com'`); if (result.catches.length > 0) { console.error(result.catches[0]); // { // code: 'SQL-003', // title: 'Unbounded UPDATE statement', // severity: 'block', // confidence: 99, // detail: 'UPDATE on `users` has no WHERE clause. Every row in the table will be modified...', // fix: 'Add a WHERE clause that scopes the update to specific rows...', // threatCategories: ['destruction'], // } }
CommonJS
const { analyze, init } = require("@vibeguard-dev/local"); (async () => { await init(); const result = analyze("DELETE FROM users"); console.log(result.catches[0]?.code); // 'SQL-003' })();
That's the whole API. After init(), every analyze() call is
synchronous and sub-millisecond on typical queries.
What we deliberately do NOT do
This SDK does static analysis only. It checks the shape of your SQL. It does not:
- Compare your agent's stated intent against what the SQL would actually do
- Estimate real blast radius from the upstream Postgres planner
- Provide tamper-evident audit logging
- Offer human-in-the-loop escalation for grey-zone queries
- Track per-agent behavioral baselines over time
For those, you want VibeGuard Cloud — the wire-protocol proxy and MCP server this SDK is the static-analysis layer of. Use the SDK locally; use the cloud in production. The two are designed to work together.
The 12 catches
Each catch has a stable code (e.g. SQL-001), a severity, a confidence
range, and links to a docs page with examples and references. Catch IDs
are forever-stable — once published, an ID always means the same thing
(see STABILITY.md).
| Code | Title | Severity | Confidence | Status |
|---|---|---|---|---|
SQL-001 |
Cartesian explosion | block | 90–95 | ✅ shipped |
SQL-002 |
Self-join footgun | warn | 70–85 | ✅ shipped |
SQL-003 |
Unbounded UPDATE / DELETE | block | 95–99 | ✅ shipped |
SQL-004 |
Implicit type coercion in WHERE | warn | 75–85 | ✅ shipped |
SQL-005 |
NULL comparison footgun | warn | 90–95 | ✅ shipped |
SQL-006 |
OFFSET without ORDER BY | warn | 85–95 | ✅ shipped |
SQL-007 |
NOT IN with nullable subquery | warn | 75–85 | ✅ shipped |
SQL-008 |
String-concat injection patterns | block | 80–95 | ✅ shipped |
SQL-009 |
DISTINCT without obvious reduction | info | 60–75 | ✅ shipped |
SQL-010 |
Correlated subquery in SELECT | warn | 70–85 | ✅ shipped |
SQL-011 |
Aggregate without GROUP BY | warn | 85–95 | ✅ shipped |
SQL-012 |
Recursive CTE without termination | block | 80–95 | ✅ shipped |
See ROADMAP.md for what's in / out of scope.
Use with...
Each example is a short, runnable integration showing how to wire the SDK into a common AI tool's pre-execution flow:
- Claude Code — see
examples/claude-code/ - Cursor — see
examples/cursor/ - Replit Agent — see
examples/replit-agent/
Architecture, in one paragraph
The SDK parses your SQL with libpg-query, walks the resulting AST with
a small, pure-function traversal helper, and runs each query through a
registry of catch-functions. Each catch returns either null (didn't
fire) or a structured Catch with code, severity, confidence, detail,
and fix. No network calls. No state between calls. Sub-millisecond on
typical queries. See ARCHITECTURE.md for the full
design rationale.
Contributing
We welcome new catches that meet the SDK's scope: static-AST-detectable SQL anti-patterns with documented real-world incidents. The proposal process starts with an issue (template here); PRs come after maintainer feedback on whether the pattern fits.
See CONTRIBUTING.md for the full process, CODE_OF_CONDUCT.md for community expectations, and ARCHITECTURE.md for how the codebase is laid out.
Security
This SDK does static analysis. It does not execute SQL. It does not open network connections. It does not log to disk.
If you find a vulnerability — a false-negative that lets a real-world dangerous pattern through, a panic / crash on adversarial input, or a supply-chain concern — see SECURITY.md for the disclosure process. Do not file security issues as public GitHub issues.
License
Apache License 2.0 — see also NOTICE for
attribution requirements that travel with derivative works.
About
VibeGuard is a wire-protocol security layer for AI agents that write SQL. This SDK is the open-source static-analysis component of the broader product.




























