
QueryPilot
io.github.nickklos10Published by GitHub account nickklos10v0.1.1Updated Oct 24, 2026
Safe SQL gateway for AI agents: SELECT-only validation, access policies, masking, audit trail, evals
The publisher's own server: QuickBooks Connector by Meridian
Overview
QueryPilot gives an AI assistant a read-only SQL gateway: it searches schemas, validates SELECT-only SQL, and executes queries against a configured database.
- What you can do
- QueryPilot exposes four MCP tools: ask_database, search_schema, validate_sql, and execute_sql. Before execution it parses SQL, enforces a single-statement SELECT-only policy, checks tables and columns, inserts or caps LIMIT, and assigns a risk level. It also supports column and row access policies, result masking, and structured audit records, plus an eval harness that scores generated SQL against fixture databases.
- When to use it
- Use it when an assistant needs to query a SQL database without write access, and you want validation, access policies, and an audit trail between the model and the data. It also suits teams that want to regression-test generated SQL against fixtures or replay audit logs as a benchmark suite.
- Requirements
- Runs locally over stdio (or Streamable HTTP) via the PyPI package querypilot, typically launched with uvx and the [mcp] extra. Requires a SQLAlchemy-style connection URL in QUERYPILOT_DATABASE_URL, plus optional settings such as QUERYPILOT_DIALECT, QUERYPILOT_MAX_ROWS, QUERYPILOT_TIMEOUT_SECONDS, and QUERYPILOT_ACCESS_POLICY_JSON. Optional LLM generators need provider API keys; local OpenAI-compatible endpoints can be used instead.
Installation
In SourceWeft
- Open QueryPilot in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
QueryPilot
[PyPI] [Python] [License: MIT] [CI]
Safe, measurable SQL for AI agents.
QueryPilot sits between an LLM agent and your database. It gives the agent read-only, policy-checked SQL tools for any SQLAlchemy database. It grounds the model in your real schema, feeds errors back so the model can fix its SQL, and ships an eval harness that proves the SQL is correct and stays correct.
[querypilot eval run terminal report]
Quickstart
querypilot demo writes a small SaaS database (querypilot-demo.db), runs a validated query against it and shows a blocked DELETE. Then try:
ask uses OpenAI or Anthropic when OPENAI_API_KEY or ANTHROPIC_API_KEY is set (--generator openai-compatible covers Ollama, vLLM and LM Studio). Without a key it falls back to an offline demo generator.
For your own database, querypilot init --db postgresql://[email protected]/prod writes a querypilot.yaml that holds the connection, business hints, column descriptions and access policy. Every command, the MCP server and QueryPilot.from_config() read it, so you can drop --db from then on.
In Python:
Connect any database
QueryPilot.connect(url) infers the SQL dialect from the URL and introspects tables, views, primary and foreign keys, and comments. It also accepts a SQLAlchemy Engine.
Every query is validated with sqlglot for the target dialect. Validation means one statement, SELECT only, and known tables and columns. It also blocks dangerous functions for each engine, such as pg_read_file, DuckDB's read_csv, MySQL's LOAD_FILE and SQL Server's xp_cmdshell. Execution then adds the engine's own guard: a read-only transaction on Postgres, MySQL and Oracle, a read-only connection on DuckDB, and a statement timeout where the engine supports one. Every query runs in a transaction that is always rolled back. For warehouses that have no read-only session mode, connect with a read-only role.
Give your agent the tools
Every integration exposes the same small toolset. Results are compact JSON, and errors come back as {"ok": false, "error": ..., "hints": [...]} rather than as exceptions, so the agent can correct itself.
MCP (Claude Code, Claude Desktop, Cursor, VS Code, Windsurf):
The generated config uses the absolute path to uvx, which avoids the common spawn uvx ENOENT failure. Pass --runner python to launch the current environment instead. Every tool carries the MCP readOnlyHint annotation. querypilot mcp --transport streamable-http --port 8000 serves the same tools over HTTP.
OpenAI / Anthropic tool calling:
Agent frameworks:
naming="langchain" reuses the tool names from the community SQLDatabaseToolkit (no longer maintained), so existing prompts keep working. Install the matching extra: querypilot[langchain], [llamaindex], [openai-agents], [claude-agent] or [mcp]. See examples/07_frameworks.py.
Protect any Postgres client: querypilot proxy (prototype)
The proxy needs no SDK. It is a Postgres wire-protocol server that applies the same validator and access policy to every statement, whatever the client. That covers psql, psycopg, SQLAlchemy and LangChain, an existing MCP database server, Cursor or Claude Code, and BI tools. Point the client's connection string at the proxy instead of the database:
Every statement then gets the following:
- Read-only enforcement. Writes, DDL, COPY and
SETof anything outside a small allowlist are rejected. Allowed statements run in aREAD ONLYtransaction on a session that defaults to read-only, soCOMMIT; DROP TABLE …is rejected. - Row filters and the row cap. The rewritten SQL is what reaches the database, so the policy's
row_filtershold under joins, subqueries and CTEs, andLIMITis capped atmax_rows. - Masking.
masking_rulesapply by output position, soupper(email) AS contactis masked too. - Errors an agent can repair. A rejection is a normal Postgres error with a SQLSTATE, the validator's message, and a
HINT, for exampleColumn 'nope' does not exist. Columns of orders: id, customer_id, …. - Audit. One JSONL record per statement goes to
--audit-log, with the client's SQL, the SQL that ran, the row count, and the client user and application.
Driver handshakes, SET/SHOW of formatting settings, and catalog queries for psql \d and ORM reflection pass through an allowlist. Catalog queries that could read data, such as pg_stats or query_to_xml(...), are rejected. The policy file is a normal querypilot.yaml, and its database_url is used when you omit --upstream. Off loopback, set QUERYPILOT_PROXY_PASSWORD. Protocol coverage, known gaps (no TLS termination yet, no server-side cursors), and the reasons it fails closed are in docs/proxy.md.
Watch the SQL your agent already runs: querypilot trace and hooks
Some query tools can't sit behind QueryPilot, for example Palantir Foundry's MCP SQL tool. For those, QueryPilot reads what the agent did instead. trace import pairs every query tool call in Claude Code transcripts with its result. hooks install logs new calls live. trace doctor reports the failure rate by class, retry chains, latency and stalls, and says for each problem whether it is best fixed in the tool, the prompt, or the data:
With --guard, a PreToolUse hook validates each query against schemas cached from the agent's own schema calls. It denies unknown columns with a "did you mean" reply before the query reaches the warehouse, blocks date arithmetic on DATE columns stored as epoch milliseconds, and enforces a row cap. Foundry's tool is mapped by default; map any other with --tool NAME=SQL_FIELD[:DIALECT]. Recovered retry chains export to eval replay as a regression suite. See docs/trace.md and the first Foundry report.
Better SQL from the model
When QueryPilot writes the SQL itself (ask, ask_database, evals), it uses the techniques with the largest measured gains in the text-to-SQL literature. The sources and numbers are in docs/research/developer-needs.md.
- Grounded schema. The prompt shows each table as compact DDL with primary keys, foreign-key join paths, comments and real values for category-like text columns: every value when there are 10 or fewer, otherwise the 3 most common. Sample values are never drawn from blocked, masked or row-filtered columns.
- Your business rules. Pass
hints=anddescriptions=toconnect(), or set them inquerypilot.yaml, for definitions such as "revenue means paid invoices only". - Pruning only when needed. Below
schema_token_budget(default 6000 tokens) the full schema is sent. Above it, QueryPilot sends the relevant tables plus the foreign-key bridge tables that join them. - A repair loop that converges. Validation errors get "did you mean" hints. Database errors are cleaned before they go back to the model. An empty result triggers one gentle review. Up to 3 attempts by default.
Why QueryPilot exists
Read-only SQL access for agents is becoming a commodity. The hard part is making that access measurably reliable: proving the SQL the agent writes is correct, safe and fast, and that it doesn't regress.
QueryPilot can measure every change to your prompts, model or configuration against an execution-truth eval suite. You can write suites by hand, or generate them by replaying your audit log as a regression set. The queries that worked in production yesterday then have to keep working tomorrow.
Eval quickstart
From a clone of this repository (the bundled suites run against tests/fixtures/demo.db):
Sample output (abridged — see the full report at the top of this README):
The bundled suites/smoke.yaml runs against a tiny SQLite fixture (tests/fixtures/demo.db) so the harness works end-to-end without an LLM key. In your own project, querypilot eval init scaffolds suites/ and .eval/. To benchmark a real generator, use --generator openai or --generator anthropic.
Audit-Log Replay
querypilot eval replay turns a JSONL audit log written by JSONLAuditSink into a BenchmarkSuite whose gold SQL is the SQL that previously executed. Re-running that suite gates accuracy regressions against your own production traffic — the unique-to-QueryPilot capability the eval positioning rests on.
Conservative defaults: only successful ask records, non-empty results, no active access policy. --include-failures, --include-masked, --include-empty relax each filter.
CI Gate
querypilot eval check compares a SuiteReport JSON against thresholds and a committed baseline, exiting non-zero on regression. A sample GitHub Actions workflow ships at .github/workflows/eval.yml:
When a regression is detected the output explains which cases regressed and how:
Refresh the baseline on main after a deliberate change:
Authoring a Suite
Suites are YAML or JSON. Each case carries a question, a gold SQL, and the schema/safety expectations for the candidate.
Result-set correctness is scored by executing both the gold and candidate SQL against the same fixture database and comparing rows. Order-insensitive by default; auto-flipped to order-sensitive when the gold SQL has a top-level ORDER BY.
Examples
Runnable, self-contained examples live in examples/. They all use
the bundled demo SQLite fixture, so most need no API key:
See examples/README.md for setup and the full index.
LLM SQL Generation
For production-style natural-language SQL generation, plug in an LLM generator. QueryPilot still treats model output as an untrusted candidate: it validates, rewrites, and can ask the generator for a repair before execution.
Install optional provider dependencies:
OpenAI:
Anthropic:
Local / open models
Any OpenAI-compatible endpoint — Ollama, vLLM, LM Studio,
or llama.cpp's server — works through OpenAICompatibleSQLGenerator. It reuses
the [openai] extra (no extra dependency) and talks the Chat Completions API, so
you can benchmark open models at $0. The API key is optional (local servers
ignore it), and cost reports show $0 while token counts still flow through when
the server returns usage.
From the eval harness, add open models to the benchmark matrix with
--generator openai-compatible:
--base-url also reads $QUERYPILOT_BASE_URL, and defaults to Ollama's
http://localhost:11434/v1 when unset.
The safety loop is always:
Eval Harness (Library)
The CLI is a thin wrapper around run_suite, which is also usable directly:
The returned SuiteReport is a Pydantic model with pass_rate, safety_pass_rate, correctness_rate, repair_rate, p50_latency_ms, p95_latency_ms, total_prompt_tokens, estimated_cost_usd, tag_rollups, failure_breakdown, threshold_violations, and the full per-case case_results list.
Safety Engine
QueryPilot validates SQL before execution with:
sqlglotparsing- single-statement enforcement
- SELECT-only read-only policy
- blocked keyword detection
- known table checks
- column checks where feasible
- allowed/blocked table policy
- automatic
LIMITinsertion and max-row capping SELECT *warnings or rejection- Cartesian join detection
- structured policy checks
- query fingerprints
- risk levels:
low,medium,high,critical
For PostgreSQL production use, connect QueryPilot with a dedicated
least-privilege role that has only the required schema USAGE and table
SELECT grants. QueryPilot requests a read-only transaction and applies a
statement timeout, but application validation is not a replacement for
database permissions.
Example:
For stricter deployments:
FastAPI Server
Run QueryPilot as a local safe SQL gateway:
Or use environment variables:
Endpoints:
GET /healthGET /schemaPOST /search-schemaPOST /askPOST /generate-sqlPOST /validate-sqlPOST /execute-sqlPOST /evals/runGET /audit/recent
Example:
Audit Trail
QueryPilot records structured audit events for schema search, SQL generation, validation, execution, and full ask() flows.
Each audit record can include:
audit_id- timestamp
- operation
- question
- original SQL
- rewritten SQL
- validation metadata
- execution status
- row count
- execution time
- error
- actor/session/application/trace metadata
Use the default in-memory sink:
Or persist JSONL audit events:
Access Control
Read-only SQL is necessary but not enough. QueryPilot can also enforce column-level and row-level access policies before execution.
What this does:
- rejects SQL that selects blocked columns
- rejects SQL outside an allowlist when
allowed_columnsis configured - injects required row filters such as
tenant_id = 42 - masks configured result columns after execution
- records the applied access policy in validation, result, answer, and audit metadata
The server and MCP runtimes can also receive access policy JSON:
Current Scope
Shipped:
pip install querypilot,querypilot demo/schema/sql/ask/init/mcp-config, and aquerypilot.yamlproject config- connectors for SQLite and PostgreSQL built in, plus DuckDB, MySQL/MariaDB, SQL Server, Snowflake, BigQuery, Redshift, Trino, Oracle and Databricks through SQLAlchemy extras
- dialect-aware SQL validation and rewriting (sqlglot), per-engine dangerous-function blocklists, and layered read-only execution
- one agent toolkit exposed for MCP, OpenAI, Anthropic, LangChain, LlamaIndex, OpenAI Agents SDK, Claude Agent SDK and plain functions
- grounded generation: keys, foreign keys, comments, policy-safe sample values, business hints, and threshold-gated schema pruning
- OpenAI, Anthropic and OpenAI-compatible (Ollama, vLLM, LM Studio) generators with a repair loop for validation errors, database errors and empty results
- column policies, row filters and result masking
- in-memory and JSONL audit logging
- FastAPI server and MCP server runtimes
- eval-driven harness: YAML/JSON suites, execution-truth correctness scoring, safety/repair/latency/cost metrics, per-tag rollups, failure-category breakdown, threshold violations, JSON and terminal reports
- audit-log → regression suite (
querypilot eval replay), CI regression gate (querypilot eval check), andquerypilot eval init - the SaaSPulse contamination-proof benchmark (
benchmarks/)
Roadmap
The ranked roadmap and the evidence behind it are in docs/roadmap.md and docs/research/developer-needs.md. Next up: multi-candidate generation with result voting, few-shot retrieval from verified queries, warehouse cost guards (dry runs, bytes-billed caps), and multi-database MCP servers.
Source: README.md at commit 975bc74
Tools
0Version history
1- v0.1.1LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Other Pilot integrations
QuickBooks Connector by Meridian
com.pilot.meridianOfficial publisher
Lets an assistant read from and write to QuickBooks Online company data through a hosted remote connector.
AI Agent Connector by Meridian
com.pilot.meridianOfficial publisher
Lets an AI assistant connect to Xero with authorised read or write access across multiple organisations.

XuLan ScreenPilot
Published by GitHub account dahuam
Turn the real Windows screen into a numbered element table your AI agent can operate.

Covenant AAP - hosted developer pilot
Published by GitHub account covenant-common
Hosted marketplace and contract-drafting server: search public listings, prepare trade records, draft and compare clauses, and review agreement evidence.
Tag Pilot Search Console
Published by GitHub account tagpilot
Read-only Google Search Console MCP server that lets an assistant query clicks, impressions, CTR, positions, sitemaps and index status for your properties.