How to give Claude safe read-only access to a production Postgres
When to use: You want Claude to answer questions over a real database without a generic execute_sql tool that can DROP TABLE.
Prerequisites
- Postgres reachable via libpq URL — Use a read-only role; never the app's writable user
- Docker or Go installed — Toolbox ships as a single binary; Docker image is easiest
Flow
-
Run Toolbox with the prebuilt postgres profileStart mcp-toolbox in stdio mode using
--prebuilt postgresand POSTGRES_URL pointing at the read replica.✓ Copied→ Toolbox logstools registered: list_tables, describe_table, execute_sql_readonly -
Wire it into Claude DesktopAdd the toolbox docker config to claude_desktop_config.json under mcpServers, then restart Claude.✓ Copied→
/mcplists toolbox tools — no failures -
Ask a real questionToolbox: list tables. Then for
orders, what's the median order value in the last 7 days? Show me the exact SQL you ran.✓ Copied→ Claude calls list_tables → describe_table → execute_sql_readonly with a SELECT (never UPDATE/DELETE)
Outcome: Read-only analytics over real data with zero risk of mutation, audit log of every query.
Pitfalls
- Pointed at the writable user — Claude eventually calls a mutating tool — Always use a role with
GRANT SELECTonly; verify with\duin psql - Connection pool exhausted under parallel agent calls — Set
pool.max_open_connsin tools.yaml; default is conservative