
Queryshield
- 1 repo stars
- Updated July 27, 2026
- bch1212/queryshield
QueryShield is a MCP server that proxies agent SQL with NL→SQL, AST safety, per-agent RLS, and audit logging.
About
QueryShield MCP is a stdio Model Context Protocol server that fronts your database with a secure SQL proxy built for AI agents: natural language to SQL, AST validation, per-agent row-level security, and an audit trail. developers who let Claude Code or Cursor run analytics or support queries know the risk of over-broad SELECTs or destructive statements; this server centralizes guardrails so the agent never holds raw DB credentials. Install from PyPI as queryshield-mcp, obtain an agent API key from QueryShield, and optionally set QUERYSHIELD_BASE_URL. Skillselion places it under Operate → Infra because it is infrastructure you add once agents are allowed near real data, though security-minded teams may also touch it during Ship planning. Complexity is advanced due to RLS policy design and SQL safety semantics. It is a governed data access layer, not a schema design or migration tool.
- Natural language to SQL with AST-based safety checks before execution
- Per-agent row-level security (RLS) so each agent sees only allowed rows
- Audit log of agent queries for production accountability
- PyPI stdio package queryshield-mcp with QUERYSHIELD_API_KEY
- Optional QUERYSHIELD_BASE_URL override for non-default deployments
Queryshield by the numbers
- Data as of Jul 28, 2026 (Skillselion catalog sync)
claude mcp add --env QUERYSHIELD_API_KEY=YOUR_QUERYSHIELD_API_KEY --env QUERYSHIELD_BASE_URL=YOUR_QUERYSHIELD_BASE_URL queryshield-mcp -- uvx queryshield-mcpAdd your badge
Show developers this MCP server is listed on Skillselion. Paste this into your README.
| repo stars | ★ 1 |
|---|---|
| Package | queryshield-mcp |
| Transport | STDIO |
| Auth | Required |
| Last updated | July 27, 2026 |
| Repository | bch1212/queryshield ↗ |
What it does
Route agent-generated natural language into audited, row-level-scoped SQL instead of handing your database credentials to the model.
Who is it for?
Best when you're running agent-assisted internal tools or support bots and need NL queries with RLS and auditability on a real database.
Skip if: Greenfield projects with no database yet, or teams fine with read-only static exports instead of live governed SQL.
What you get
After you issue agent keys and connect the MCP, queries flow through QueryShield with safety checks, scoped rows, and logs you can review.
- Agent-executed SQL passing AST safety and RLS boundaries
- Audit log entries for accountability on agent-driven queries
By the numbers
- Server version 1.0.1 via PyPI package queryshield-mcp
- Capabilities: NL→SQL, AST safety, per-agent RLS, audit log
- Optional QUERYSHIELD_BASE_URL endpoint override
README.md
QueryShield
Secure SQL proxy between AI agents and enterprise databases.
Agents call a single endpoint in plain English (or structured SQL). QueryShield:
- Translates natural language → SQL via Claude with prompt caching.
- Validates every query at the AST level — only
SELECTis allowed, no stacked statements, no forbidden functions, LIMIT required. - Applies per-agent row-level security: schema/table whitelists and
WHEREclause injection. - Executes against the customer DB and returns rows.
- Logs every attempt to an append-only audit table — metadata only, never row contents.
Agents never see connection strings.
Quickstart
pip install -r requirements.txt
cp .env.example .env
# Set ANTHROPIC_API_KEY, DATABASE_URL, VAULT_KEY (see below)
python -m queryshield.start
Generate a Fernet key for VAULT_KEY once and never lose it:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
End-to-end flow (curl)
# 1) Boot a tenant. Returns the admin API key — copy it.
curl -X POST localhost:8000/v1/tenants?name=Acme
# 2) Register the customer DB. Connection string is encrypted at rest.
curl -X POST localhost:8000/v1/databases \
-H 'X-Admin-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{
"alias": "prod",
"db_type": "postgresql",
"connection_string": "postgresql://reader:secret@db.acme.internal:5432/app",
"allowed_tables": ["users", "orders"]
}'
# 3) Provision a scoped agent (different from admin) for your AI app.
curl -X POST localhost:8000/v1/agents \
-H 'X-Admin-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{ "name": "reporting", "tenant_id": "<tenant>" }'
# 4) Set the agent's RLS policy.
curl -X POST localhost:8000/v1/policies \
-H 'X-Admin-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{
"agent_id": "<agent>",
"database_alias": "prod",
"allowed_tables": ["users", "orders"],
"row_filters": { "users": "tenant_id = 42" }
}'
# 5) The agent queries.
curl -X POST localhost:8000/v1/query \
-H 'X-API-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{
"database_alias": "prod",
"query": "how many active users do we have?",
"mode": "nl",
"max_rows": 10
}'
MCP integration
Listed in the official MCP Registry as io.github.bch1212/queryshield.
Install the client:
pip install queryshield-mcp
Then drop this into your Claude Desktop / Cursor / agent config:
{
"queryshield": {
"command": "queryshield-mcp",
"env": { "QUERYSHIELD_API_KEY": "qs_..." }
}
}
Source for the standalone PyPI package lives in packages/queryshield-mcp/.
MCP integration (legacy)
Drop this into any MCP-aware client (Claude Desktop, Cursor, custom agents):
{
"queryshield": {
"command": "python",
"args": ["-m", "queryshield.mcp_server"],
"env": {
"QUERYSHIELD_API_KEY": "qs_...",
"QUERYSHIELD_BASE_URL": "https://api.queryshield.io"
}
}
}
Tools exposed:
query_database(database_alias, question, max_rows)— natural-languagequery_database_sql(database_alias, sql, max_rows)— pre-built SELECTget_audit_log(limit)— recent attempts for the calling agent
Security model
| Threat | Defense |
|---|---|
Agent crafts a DROP TABLE |
sqlglot AST refuses non-SELECT |
Agent sneaks ; and a second statement |
parser rejects len(statements) > 1 |
Agent uses pg_sleep, xp_cmdshell, ... |
function deny-list at the AST node level |
| Agent reads tables outside its scope | RLS schema + table whitelist |
| Agent reads other tenants' rows | row_filters injected via AST .where() |
| Connection string leaks via stack traces | Fernet-encrypted, never returned in any API |
| Audit log becomes the data exfil vector | only metadata is stored — never rows |
VAULT_KEY rotation |
re-encrypt rows under new key (script-driven) |
safety.py is the single most important module. Every additional check
that lands there should ship with a test in tests/test_safety.py.
Pricing
| Tier | Monthly | Databases | Queries / month | Notes |
|---|---|---|---|---|
| Starter | $500 | 3 | 1,000,000 | |
| Pro | $1,500 | 10 | 10,000,000 | audit export |
| Enterprise | $3,500 | unlimited | unlimited | SSO, SIEM webhook |
Targets $32.5K MRR @ 15 customers (10 Pro + 5 Enterprise).
Deploy
The repo is Railway-ready. python -m queryshield.start is the entrypoint
(reads PORT via os.getenv, since Railway exec's the start command without
a shell). Provision Postgres + (optionally) Redis from Railway's marketplace
and the rest is env vars.
railway up
/health is the liveness check. /ready returns 503 if the control-plane
DB is unreachable.
Tests
pip install pytest
python -m pytest tests/
42 tests cover:
- AST safety (24 cases — direct DDL, comments, encoded keywords, multiple statements, forbidden functions, missing LIMIT)
- RLS engine (6 cases — whitelist enforcement, WHERE injection, conjunction with existing predicates)
- Proxy end-to-end against a SQLite "customer DB" (5 cases — happy path, blocked DML, RLS row filtering, table whitelist, cache hit)
- HTTP integration via FastAPI TestClient (7 cases — full provisioning → query flow, scoped agent with RLS, auth failures)
Recommended MCP Servers
How it compares
Secure database proxy MCP—not a generic ORM code-generation skill.
FAQ
Who is QueryShield for?
Developers who already expose databases to AI agents and need AST-checked SQL, per-agent RLS, and audit logs instead of sharing connection strings.
When should I use QueryShield?
Use it in Operate when agents run recurring analytics or ops queries against staging or production and you must enforce scope and traceability.
How do I add QueryShield to my agent?
Install queryshield-mcp from PyPI, set QUERYSHIELD_API_KEY (and QUERYSHIELD_BASE_URL if needed), register the stdio server in your MCP client, and restart.