SQL Safety & Cost Oracle

The verdict before the query.

A deterministic safety & cost gate that vets every SQL statement your AI agent writes — before it runs.

deterministic no LLM in the loop never connects to your DB
analyze_sql
# your agent wrote:
DELETE FROM users;
● block
{
  "verdict": "block",
  "findings": [{
    "id": "destructive.delete_without_where",
    "severity": "block",
    "recommendation": "Add a WHERE clause, or confirm
                       a full-table delete is intended."
  }]
}
In the loop with Claude Code Cursor Postgres MCP GitHub CI

How it works

A gate between the agent and the database.

  1. 01

    Agent writes SQL

    Your agent calls analyze_sql over /mcp before executing anything.

  2. 02

    Veto vets it

    Deterministic rules + a cost estimate on a throwaway scratch Postgres; your production DB is never touched.

  3. 03

    Verdict returns

    A structured ok / warn / block verdict with finding ids, before the query runs.

Verdicts

One contract. Three states.

● ok
SELECT … LIMIT 100

Safe to run. Ships without friction.

● warn
ALTER TABLE orders ALTER COLUMN id TYPE bigint

Heavy-lock risk or a large sequential scan. You decide.

● block
DELETE FROM users

Destructive without a guard. Stopped before it runs.

Demo

It blocked the migration. You never wrote the postmortem.

Same input, same verdict — every time. Deterministic findings with stable ids you can gate CI on.

Connect via MCP
analyze_sql · response
# DROP TABLE invoices;
● block
{
  "verdict": "block",
  "findings": [{
    "id": "destructive.drop",
    "severity": "block",
    "recommendation": "Confirm the object is unused;
                       consider renaming first as a
                       safer rollback path."
  }]
}

Why Veto

The boring, reliable layer you bet on.

  • Deterministic

    Same statement, same verdict — every time. No model drift, fully reproducible.

  • No LLM in the loop

    Rules + query planning, not a prompt. No tokens, no latency, no hallucinated approvals.

  • Never touches your DB

    Cost estimates run on a scratch Postgres via BEGIN … ROLLBACK. Production is never connected.

  • Gated on golden evals

    Stable finding ids and golden cases in CI — a contract you can trust over time.

FAQ

Questions, answered.

Does Veto connect to my database? +

No. Veto never connects to your production database. Cost and plan estimates run on a throwaway scratch Postgres inside a transaction that's always rolled back.

Is there an LLM making the decision? +

No. The verdict is produced by deterministic rules and query-plan analysis — not a model. Same input always yields the same verdict.

How does my agent call it? +

Connect via MCP at /mcp and expose the analyze_sql tool. Your agent asks for a verdict before it runs any statement.

What does it cover? +

Destructive statements (unscoped DELETE/UPDATE, DDL drops), correctness traps (NULL comparisons like = NULL, NOT IN with a subquery, LEFT JOINs that silently become inner joins), and cost risks (large sequential scans, missing indexes). Scope is intentionally narrow and reliable rather than broad and fuzzy.

Will it false-block my routine migrations? +

No. The rules are plain Postgres — any database (Supabase, Neon, RDS, self-hosted) and any migration tool. Tuned on real-world migrations: routine DROP POLICY / DROP INDEX / DROP FUNCTION and lock-light ALTERs (enable RLS, add a nullable column) come back ok or warn — only genuine data loss (DROP TABLE, TRUNCATE, unguarded DELETE/UPDATE) blocks. A guardrail you'll actually keep switched on.

What are custom org policies? +

A Pro feature that takes Veto from a linter to a governance layer. The built-in rules are the same for everyone — they don't know that payments is sacred in your database. Custom policies let your team add its own rules ("never DELETE from payments", "no TRUNCATE on audit_*"), and Veto enforces them on top of the built-ins. Policies are declarative data — validated, never executed — so the safety tool can't itself become an injection hole.

How do I set custom policies? +

Tell your agent in plain language ("don't let anything delete from payments"); it generates the declarative JSON and calls the set_policies tool with your Pro key. Policies are stored on the key, so every later analyze_sql call made with it enforces them automatically — no web login, no per-call config, nothing extra for your other agents to do.

Pricing

Free today. More when you need it.

Free €0
  • Full deterministic verdict — every rule
  • Destructive, locking, correctness & cost analysis (CTE-aware)
  • Never connects to your database
  • MCP endpoint with stable finding ids
  • 60 requests / min
Pro €9.90/mo
  • Custom org policies — your rules on your tables, enforced on top of the built-ins. e.g. no DELETE on payments.
  • 1200 requests / min — 20× the free cap
  • Direct support from the maintainer
  • Early access & a say in what ships next

On the roadmap, funded by Pro: an audit & usage dashboard, an embed SDK / self-host.

Subscribe to Pro

Your agent won't drop prod.

Point your MCP client at the endpoint — free in seconds. Add your Pro key for 1200 req/min and custom org policies.

.mcp.json
{
  "mcpServers": {
    "veto": { "url": "https://vetosql.com/mcp" }
  }
}

Any MCP client — Claude Code, Cursor, … Free tier, no key, 60 req/min.

Your key stays in your browser — nothing is sent or stored. Keep the word Bearer and the space.

Claude Code · .mcp.json
{
  "mcpServers": {
    "veto": {
      "type": "http",
      "url": "https://vetosql.com/mcp",
      "headers": { "Authorization": "Bearer VETO-…" }
    }
  }
}
Cursor · ~/.cursor/mcp.json
{
  "mcpServers": {
    "veto": {
      "url": "https://vetosql.com/mcp",
      "headers": { "Authorization": "Bearer VETO-…" }
    }
  }
}
  1. Connected — have your agent analyze_sql a DROP TABLE test; → a block means Veto is wired in. (works on free too)
  2. Pro is live — have it set_policies (block delete on payments), then analyze_sql a DELETE FROM payments → a policy.violation block proves your key unlocked Pro. (free keys can't set policies)
set_policies · Pro
# tell your agent, in plain language:
"never let anything DELETE from payments"
# it calls set_policies with your Pro key →
{
  "policies": [
    { "table": "payments", "operations": ["delete"],
      "action": "block" }
  ]
}

Stored on your key — every later analyze_sql enforces it. No web login.

shipped with a seatbelt