sqlike: MCP server and CLI
[@sqlike/mcp]
[@sqlike/cli]
[license]
Check your SQL before it runs, and check whether a rewrite still returns the same results.
sqlike reads a query and tells you what is wrong with it: validity errors,
anti-patterns, rewrites it can apply for you, and index advice. It also compares two queries and
reports whether the second one still returns the same results. There is no model anywhere in the
analysis, so the same query always gets the same answer.
This repository holds the clients: an MCP server, a CLI, and the
library they share. They tokenize your SQL locally, so identifiers and literals are masked before
anything leaves your machine, and forward only the tokenized query. The analysis engine is not in
this repo. It runs server-side and is closed.
Dialects: Postgres, MySQL, MariaDB, SQLite, SQL Server, and DuckDB. Each rule carries a verdict
measured on that engine, so the severity you get is that database's behaviour and not Postgres by
inheritance. DuckDB is the columnar one: it has no general-purpose secondary index, so the ten index
advisors are replaced there by four columnar ones.
Why
A lot of SQL is written by an AI now, and the SQL it writes reads well more often than it runs
correctly. A LEFT JOIN turns into an INNER and rows quietly disappear. A WHERE goes missing and
the UPDATE hits every row. Two tables get joined on the wrong key. None of it looks wrong on the
page, and none of it shows up until it has already done something.
sqlike is the check in between. It flags unsafe patterns from a catalog of 172 rules, each one
verified against a real database before it ships, and it decides whether a rewrite preserves results.
That second check is sound rather than complete: it certifies the rewrites it can prove, and when it
cannot prove one it answers Undecided instead of guessing. Undecided never means equivalent.
Because nothing is generated, there is no retry loop, no per-token cost, and no variance between two
runs on the same input. The equivalence check normalizes rather than solves, so it answers in about
a millisecond where the state-of-the-art academic prover takes hundreds. That is
measured head to head, including the queries where the prover wins.
Install the MCP server
Add it to any MCP client (Claude Code, Claude Desktop, Cursor, and so on):
Or install it through Smithery. Set SQLIKE_API_KEY
if you have a key and want the higher rate limits. Without one you get the anonymous tier, which
needs no signup.
Tools
analyze
Static analysis of one query: validity, anti-patterns, suggested rewrites, and schema and index
advice. Returns the JSON analysis envelope.
diff
Checks whether two queries are equivalent, which is the judgement an LLM cannot reliably make about
its own rewrite. Returns a verdict (Equivalent, EquivalentWithNotes, Differs, or Undecided),
a confidence level, and a report per property (columns, rows, cardinality, order), so you see what
changed rather than a single yes or no.
CLI
The same checks from a terminal or a CI job. Run it with no install, or put it on the path:
Point it elsewhere with --remote or SQLIKE_URL, and authenticate with --key or
SQLIKE_API_KEY.
If you have the query's EXPLAIN output, pass it with --explain plan.json and the real access
paths will confirm or dismiss the index findings. The plan is tokenized before it leaves the machine,
same as the query and the schema.
Exit codes are a contract, so each one means exactly one thing:
check defaults to --fail-on block, so advisory findings report without failing a build. Ask for
--fail-on warn to be strict, or never to only report. 3 is never a verdict about your SQL —
a pipeline can tell "this query is bad" from "the call did not go through".
In CI, and on commit
Gate SQL where it is written. Both run the same checks as the CLI, and both tokenize locally first.
GitHub Actions. Findings land inline on the pull-request diff. The workflow authenticates as
your repository owner using GitHub's own OIDC token — no signup, no API key to store or leak.
Set mode: diff and it answers a different question on every pull request: did this rewrite
change what the query returns? Only modified files are compared, and a verdict of "cannot prove
either way" never fails a build.
Pull requests from forks run anonymously. GitHub does not issue OIDC tokens to workflows a fork
triggers, so a contributor's pull request cannot authenticate as your repository — it falls back to
an anonymous, per-IP rate limit. Nothing is broken and there is nothing to configure; your own
branches still authenticate normally. The action says so rather than suggesting a permission that
would not help.
Outside a pull request there is no set of changed files, so changed-only cannot apply and every
matching file is checked. The action warns when that happens, because on a large repository it is
enough requests to reach a rate limit.
pre-commit. Same checks before the commit lands:
The hook blocks a commit on a real defect, not on a bad connection: if sqlike cannot be reached it
says so and lets the commit through.
Private by design
Tokenization happens here, on your machine, before any request goes out. sqlike never sees your real
table names, columns, or values, so there is nothing to leak and nothing to train on. An AI
assistant needs the real thing to help you; sqlike does not.
If a query cannot be parsed it cannot be tokenized, and the client refuses to send it rather than
transmit raw SQL. Sending it anyway is an explicit opt-in (allow_raw on the tools, --allow-raw on
the CLI).
See THREAT-MODEL.md for what that does and does not cover.
What is in this repo
crates/mcp: sqlike-mcp, the MCP server. Ships to npm as @sqlike/mcp.
crates/cli: sqlike, the command-line client. Ships to npm as @sqlike/cli.
crates/client: the shared forwarder, with no engine in it: tokenize, call the API, detokenize.
crates/core-parse: the SQL parser, stage model, tokenizer, and result types.
packages/: the npm packaging, with a prebuilt binary per platform.
skills/: the agent skill, so a coding agent knows when to reach for sqlike on its own.
Learn more
Try it at sqlike.com. The equivalence checker is measured in public against
the standard academic benchmark, including a head-to-head with the state-of-the-art prover, at
sqlike.com/benchmark.
Note
This repository is generated from the upstream monorepo, which is the source of truth. Please file
issues here. Code changes are made upstream and mirrored back.
License
Apache-2.0. See LICENSE.
crates/sqlparser is a vendored copy of sqlparser-rs,
also Apache-2.0. Its NOTICE file records the upstream version and lists every file changed since.