Safety-railed database access for agents: Postgres, MySQL, Redis. Read-only by default.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
The database workbench built for the AI era β one kernel, many faces (CLI / GUI / MCP / agent skill).
δΈζζζ‘£ β Β· Website β
Every database tool you know β DBeaver, TablePlus, pgAdmin β assumes a human at the keyboard. But increasingly, the entity running your queries is an AI agent, and agents need different guarantees:
Quarry inverts the traditional design: it is a query kernel with an agent-safe contract first, and the human faces (CLI, GUI) are thin shells grown from the same kernel. Whether a query comes from a person in the browser, a script in CI, or Claude running a skill, it passes through the exact same safety rails and returns the exact same structured result.
One core, many faces. Connection management, query execution, schema introspection, and safety rails live in an importable kernel (quarry.core). The CLI (qy), the GUI, the MCP server, and agent skills are thin shells. Fix a bug once, every face gets it.
Read-only by default; escalation is explicit and graduated. Writes and DDL are blocked (exit code 8) unless you pass --write. Production connections require an additional confirmation on top of --write. Every query gets an automatic LIMIT 500 unless you opt out. Because the rails are in the kernel, an agent cannot bypass them by picking a different entry point.
A contract machines can trust. Every query returns {columns, rows, rowCount, truncated, elapsedMs, engine, sql}. Exit codes are stable API: 0 ok, 2 connection error, 3 SQL error, 8 safety block. An agent can branch on outcomes without parsing prose.
Workspace as code. A workspace is just a directory: connections.toml + queries/**/*.sql (named queries with -- @meta headers). It lives in your repo, versioned by git, shared between teammates and agents alike. The kernel itself carries zero business logic and zero secrets.
Nearly zero dependencies. Pure stdlib. PostgreSQL goes through your system psql, Redis through redis-cli, SSH tunnels through system ssh. MySQL is one optional pymysql. No Electron, no daemon, no cloud.
PostgreSQL uses the system psql binary; MySQL needs pip install "quarry-db[mysql]".
A workspace directory is the source of connections + queries:
Resolution order: --workspace PATH β ~/.config/quarry/config.toml β current directory.
| Command | Purpose |
|---|---|
qy connections [list|add|set|remove|test] | Manage connections |
qy ping <db>|--all [--timeout N] [--format text|json] | Reachability probe (ok/fail + latency; exit 1 if any fail) |
qy exec <db> --sql "..." [--format json|ndjson|csv|table] [--timeout N] | Run ad-hoc SQL |
qy speedtest <db> [--env dev] [--bytes N] [--runs N] | Benchmark the current PostgreSQL/MySQL tunnel path |
qy schema <db> <table> | Live table structure |
qy run <name> [k=v ...] | Run a saved named query |
qy save <name> --db X --sql "..." | Save a named query |
qy list / describe / validate / fingerprint / audit | Manage named queries |
qy workspace list/add/remove | Manage aggregated workspaces |
qy up/down/status [--format text|json] | Workspace tunnel keep-alive keeper |
qy local up/down/status/sync [--engine postgres|redis|all] | Local dev containers (see below) |
qy gui | Launch the local GUI |
qy mcp [--write] | Serve the MCP face over stdio (for AI agents) |
qy mcp speaks the Model Context Protocol over stdio β pure stdlib, no SDK dependency. Agents get six tools (list_connections, list_tables, describe_table, exec_sql, list_saved_queries, run_saved_query) with the exact same kernel rails: read-only unless the server was started with --write and the call passes write: true; a prod env additionally requires confirm_prod: true.
Published in the MCP Registry as mcp-name: io.github.Wangggym/quarry.
8; --write to allowrun_query() injects LIMIT 500; raise with --max-rows N--write β prod needs --write plus an interactive confirmation (--yes for automation)0 ok / 2 connection / 3 SQL / 8 safety blockQuery execution and connection establishment (including SSH tunnel setup) are capped independently, so an unreachable host fails fast instead of eating the whole query budget:
The effective execute timeout is resolved in priority order:
--timeout N (CLI, on qy exec/qy run)QUARRY_TIMEOUT env vartimeout field in connections.toml (set via qy connections add/set --timeout N)On PostgreSQL, qy also sets a server-side statement_timeout (~90% of the execute timeout) before running the query; on MySQL/MariaDB it sets the equivalent session variable (MAX_EXECUTION_TIME / max_statement_time, whichever the server supports) best-effort. Either way, the database itself cancels a runaway query and reports the real reason β instead of the client giving up and leaving the query running server-side. A timeout error always tells you how to raise it (--timeout, QUARRY_TIMEOUT, or the connection's timeout setting). --timeout and the timeout field must be a positive number of seconds.
For databases only reachable via a bastion, add ssh_* fields and qy opens the tunnel automatically (system ssh, zero dependencies):
Neptune participates in the same tunnel path now: if a Neptune connection has
ssh_host (plus optional ssh_user/ssh_key/ssh_port), it joins tunnel
pooling/keep-alive the same way as Postgres/MySQL/Redis.
qy up/down/status)If you query the same SSH-backed connections repeatedly (CLI + GUI + MCP), run the workspace keeper once and reuse warm forwards across processes:
keep_alive=true + reconnect=true are persisted per workspace in
~/.config/quarry/config.toml. When reconnect is enabled, dropped tunnels are
re-opened with exponential backoff and reported as reconnecting in both qy status and the GUI header badge. If keep-alive is enabled but the keeper is
down, cold qy exec/qy run still work (legacy behavior) and print a one-line
hint to stderr suggesting qy up.
If an SSH tunnel's throughput is throttled (a cross-border bastion, for example β the handshake connects fine but data crawls), route it through your machine's HTTP(S) proxy instead:
The proxy is auto-discovered β macOS system proxy settings first (scutil --proxy), falling back to ALL_PROXY/HTTPS_PROXY β and the toggle is persisted per workspace in config.toml (never connections.toml). It only affects connections with ssh_host (tunneled via ProxyCommand) and Neptune's direct HTTPS requests; a direct (non-tunneled) DB connection is unaffected, and qy connections add/set warns if you enable the proxy for a connection with no ssh_host. If the proxy is enabled but nothing is listening on its port, qy falls back to a direct connection instead of erroring; targets covered by the system proxy's exceptions list (loopback, private CIDR ranges) are never proxied.
Because the fallback-to-direct behavior above is silent by design (a query still has to run), it's worth knowing how to check whether a given call actually went through the proxy:
qy output: if a workspace has the proxy enabled but a call still ran direct, qy exec/qy run print a one-line reason to stderr β no proxy discovered, discovered but nothing listening on its port, or the target is covered by the proxy's exceptions list. --no-proxy suppresses this (you asked for direct, so there's nothing to report).qy proxy: besides the discovered proxy and each workspace's toggle, it lists every pooled SSH tunnel β ssh target, local port, whether it's actually routed through the proxy (and which address), and whether the underlying ssh process is still alive. Add --format json for a tunnels array with the same fields, handy for scripting.qy uses, not guessed in the browser.engine = "redis" (uses system redis-cli). Queries are redis commands:
Read-only rail applies here too: GET/SCAN/TYPE/TTL/HGETALL pass; SET/DEL/FLUSHALL are blocked without --write. In the GUI, redis keys are clickable with TYPE-aware value display.
Connections can be organized into project folders (group) and env-sets (same db, different env, shared schema):
db fold into one env-set β one saved query runs against any environment: qy exec shop --env proddev (the safest)qy aggregates all workspaces listed in ~/.config/quarry/config.toml β one GUI/CLI over all your projects:
--workspace a:b (os.pathsep-separated) works as a temporary override; the first directory is primary for writes.
When a locally-running service shares a remote (dev) database, every read/write
crosses the public network β and a test/e2e run that hammers the DB gets flaky
on the round trips. qy local runs Postgres/Redis in a docker container so the
service talks only to localhost:
One shared Postgres container hosts a logical database per connection key (fixed
port 5433; redis 6380), and data lives on a named docker volume. Requires a
docker daemon; the image tag is overridable with --image.

qy gui β a local, zero-build web GUI (Slate & Copper theme, light/dark):
quarry-db is out. Editable/dev installs are skipped automatically; set
QUARRY_UPDATE_CHECK=0 to disable it entirely.723 tests in four layers, each auto-classified so you can run any slice:
| Layer | Count | Covers | Needs |
|---|---|---|---|
unit | 568 | pure logic + mocked engines (safety rails, SQL skeleton, params, formatters, cache) | nothing |
integration | 110 | in-process against a real DB, incl. the GUI HTTP API and CLI/MCP dispatch | Postgres |
e2e | 45 | the real qy CLI and qy mcp stdio server as subprocesses | Postgres |
browser | 20 | the real GUI frontend driven in headless Chromium (Playwright) | Postgres + Playwright |
DB/engine-backed tests skip automatically when the engine is unreachable, so the suite stays green on a bare machine; CI provides the engines and runs everything.
Coverage is gated at β₯95% (unit + integration) and currently sits at 99.6%.
make test prints a colored per-layer summary; run one
layer with make test-unit / test-integration / test-e2e / test-browser.make cov enforces the gate and writes an HTML report β
open htmlcov/index.html for a line-by-line view of exactly what's covered.See TESTING.md for the full architecture, fixtures, and CI layout, and CONTRIBUTING.md for contribution guidelines.
Quarry is developed and tested on macOS and Linux. Windows is currently untested (the psql/ssh integration and port takeover are Unix-flavored) β PRs welcome.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/quarry)<a href="https://allmcps.com/mcp/quarry"><img src="https://allmcps.com/api/badge/quarry?style=directory" alt="Quarry on AllMCPs" /></a>