A read-only PostgreSQL query proxy for local AI agents (Claude Code, Cursor, etc.).
pgagent is a tiny CLI that lets an AI agent run SQL against your databases
without ever being able to mutate them. It is meant to be invoked one query at
a time from an agent's shell tool.
- Read-only by construction. Every query runs inside a
READ ONLYtransaction, so the database itself rejects any write — even if the SQL parser misses something. - Static keyword check. Before the query is sent,
pgagentstrips comments and string literals, then rejects anyINSERT,UPDATE,DELETE,DROP,TRUNCATE,ALTER,GRANT,SET, etc. - Single statement only. Multi-statement payloads (
;separated) are rejected. - Automatic
LIMIT. A bareSELECTwithoutLIMIT/FETCHgetsLIMIT 500appended so a curious agent cannot dump a whole table. - Use a read-only DB role. The supplied credentials should belong to a
role with
SELECT-only grants.pgagentis defense in depth, not a substitute for a properly scoped Postgres user.
- Go 1.25 or newer (
go version) make- A PostgreSQL server you can reach from your machine
- A read-only Postgres role for
pgagentto connect as
git clone <this-repo> pg-agent
cd pg-agent
make installmake install will:
- Build the
pgagentbinary into./dist/ - Install it to
~/.local/bin/pgagent - Create
~/.pgagent/and seed~/.pgagent/config.ymlfromconfig.yml.example(only if the file does not already exist — re-runningmake installwill never overwrite your config)
After install:
pgagent -db <name> -sql "SELECT ..."make install PREFIX=$HOME/.local # → ~/.local/bin/pgagent
make install BIN_DIR=/opt/bin # → /opt/bin/pgagent
make install CONFIG_DIR=$HOME/.config/pgagentmake uninstallThe binary is removed; ~/.pgagent/config.yml is left in place so you do
not lose your credentials.
Edit ~/.pgagent/config.yml. Each key under databases: is the name you
will pass to -db.
databases:
lico:
host: 127.0.0.1
port: 5432
user: readonly
password: "your-password"
dbname: lico
sslmode: disable
txn:
host: 127.0.0.1
port: 5432
user: readonly
password: "your-password"
dbname: txn
sslmode: disableThe file is created with mode 0600 (owner read/write only). Keep it that
way — it holds plaintext passwords.
In order of precedence:
-config <path>flag$PGAGENT_CONFIGenvironment variable~/.pgagent/config.yml(the default)
pgagent -db lico -sql "SELECT * FROM users WHERE id = 12231;"
pgagent -db txn -sql "SELECT id, status FROM txn ORDER BY id DESC;"Output is a plain ASCII table on stdout. Notes and errors go to stderr.
pgagent -db lico -sql "UPDATE users SET name='x' WHERE id=1;"
# rejected: write keyword "UPDATE" not allowed
pgagent -db lico -sql "SELECT 1; SELECT 2;"
# rejected: multiple statements not allowedDrop skill.md into your agent's skills/instructions so it knows how to
call pgagent. The skill file documents the flags, the safety model, and
the patterns the agent should and should not use.
make build # binary into ./dist/
make test # go test ./...
make clean # remove ./dist/