Pointing an AI agent at a database is easy. Pointing it at production is where people stop.
dbboard is an open-source desktop database client with an MCP server that gives Claude Code read-only access to Postgres, MySQL, Turso / libSQL, Cloudflare D1, MongoDB and Firestore — enforced by the database, not by a keyword filter.
The usual guard is a keyword filter: reject anything that starts with UPDATE or DROP. It holds until the agent writes a CTE that deletes, a SELECT … FOR UPDATE, or two statements in one string. And the agent still needs the password, which now sits in its config and its transcript.
dbboard is built so that this question has a boring answer.
The one idea: the database says no, not only a filter
dbboard ships a separate MCP server, dbboard-mcp, that hands the connections you already have to Claude Code or Claude Desktop. Every read passes two checks.
First, the statement is parsed — a real SQL parser, not string matching — and anything that is not a single read-only statement is refused. Then it runs inside the database's own read-only mode, or through an adapter that cannot write at all:
| Engine | How a read is run |
|---|---|
| Postgres, Neon, Supabase, CockroachDB, Aurora DSQL | BEGIN TRANSACTION READ ONLY |
| MySQL / MariaDB | SET TRANSACTION READ ONLY |
| Turso / libSQL | PRAGMA query_only |
| Cloudflare D1 | no read-only mode exists, so the parser is the enforcement and fails closed |
| Cloud Firestore | the adapter has no write path to reach: it implements the read endpoints and nothing else |
| MongoDB | only six commands (find, aggregate, count, distinct, listCollections, listIndexes) and only their known options; the pipeline is walked for a $out or $merge hidden inside a $facet, $lookup or $unionWith
|
The second check is the one that matters. Here is dbboard-mcp against a local Postgres with fictional data, called exactly as an agent calls it:
run_read_query DELETE FROM orders WHERE quantity = 1
→ query failed: not a single read-only statement: only read-only SELECT / WITH / EXPLAIN statements are allowed
run_read_query WITH gone AS (DELETE FROM orders RETURNING id) SELECT count(*) FROM gone
→ query failed: not a single read-only statement: a data-modifying statement (in a CTE or set expression) is not read-only
run_read_query SELECT nextval('orders_id_seq')
→ query failed: cannot execute nextval() in a read-only transaction
run_read_query SELECT count(*) FROM orders
→ 180
The first two are caught by the parser. The third is a plain SELECT that still writes — it advances a sequence — so no parser flags it. Postgres refuses it, because the transaction itself is read-only. The table still has all 180 rows, and the sequence did not move.
Three more rules sit around that:
-
Passwords never reach the agent. They stay in the OS keychain. The agent sees
{ id, name, kind }for each connection, and no error message embeds a URL. -
Writing is off until a person turns it on, per connection. Even then only an allowlist runs (
INSERT,UPDATE,DELETE,CREATE TABLE, …).DROPof anything,TRUNCATE,GRANT/REVOKEand user or role changes are refused whatever the setting says. - Results are bounded, so one careless query cannot pour a whole table into the agent's context.
How to give Claude Code read-only access to your database
Download dbboard-mcp for your platform from the latest release (one self-contained executable), then:
# macOS
claude mcp add dbboard --scope user -- "$HOME/.local/bin/dbboard-mcp"
# Windows (PowerShell)
claude mcp add dbboard --scope user -- "$env:LOCALAPPDATA/dbboard/dbboard-mcp.exe"
The agent can then list connections and tables, describe a table, search a connection's schema by column name, follow foreign keys, and run read queries. Ask it "which orders in the last week have no shipment row?" and it finds the tables itself.
And for the person: one window
The desktop app is the same connections, for you:
- Every database you look after in one sidebar — Postgres (Neon, Supabase, CockroachDB, Aurora DSQL), MySQL / MariaDB, Turso / libSQL, Cloudflare D1, Firestore and MongoDB. An SSH tunnel reaches the one behind a bastion; a colour and a tag on each connection show which one you are about to run against.
- Leave the database name blank and one login lists every database it can open, with schemas and tables beneath.
-
Fix one value without writing an
UPDATE: double-click the cell, type, save. Edits are keyed on the primary key, so a table without one stays read-only instead of guessing.
What it is not
Not a hosted service: nothing leaves your machine except your own queries to your own databases. Not code-signed either — a certificate is a recurring purchase this project does not make, so every release ships SHA256SUMS.txt to check instead.
Try it
- Download from the download page (Windows x64 / ARM64
.exe, macOS.dmg) - Manage → Add connection, pick the database type, fill in the server
- Add
dbboard-mcpto your agent as above
MIT-licensed. Bug reports and requests: Issues.

Top comments (0)