agent-sql
Read-only-by-default SQL CLI for AI agents
- Language
- Go
- Version
- 1.19.2
- License
- PolyForm Perimeter 1.0.0
- Category
- CLI Tool
A SQL CLI designed for AI agents that need safe database exploration across eight engines. Schema inspection, flexible querying, explain plans and configurable output — behind a two-gate safety model where a write needs both a credential granted write permission and --write on the query itself, backed by per-driver enforcement at the parser, protocol or OS level.
Features
Eight drivers, one interface — PostgreSQL, CockroachDB, MySQL, MariaDB, SQLite, DuckDB, Snowflake and MSSQL
Two gates before any write — the credential must carry writePermission and the query must pass --write, so allowed credentials still cannot write by accident
Enforcement per engine, not per convention — libpg-query validates PostgreSQL statements, MySQL runs each query in START TRANSACTION READ ONLY, SQLite opens SQLITE_OPEN_READONLY, DuckDB runs -readonly
Fails closed on syntax it cannot parse — the CockroachDB guard refuses CRDB-specific syntax rather than waving it through
LLM-safe credential entry — credential add --form opens a native OS dialog (osascript, zenity/kdialog, Win32) so the secret never touches argv or the model's context; the agent sees a redacted receipt
Config files never hold secrets — connection add rejects URLs with embedded credentials and demands a keychain-backed --credential instead
Schema exploration — tables, describe, indexes, constraints, pattern search and a whole-schema dump
Query surface — run, sample, count with --where, and explain with optional --analyze
Parquet through DuckDB — query files directly with duckdb:// and a glob, no import step
Result caps and timeouts by default — 10,000 rows and 30s, both configurable and overridable per command
Token-aware output — --compact emits typed NDJSON with column names once and rows as arrays; long strings truncate with @truncated metadata recording original lengths
Honest pagination — a trailing @pagination line says whether more rows exist rather than silently cutting off
Structured errors and advisories — errors as JSON on stderr with fixable_by and hint; non-error notices as their own structured lines, so stdout stays clean NDJSON
Single compiled Go binary — no runtime dependencies, except the duckdb CLI for DuckDB connections
Install
Homebrew
$ brew install shhac/tap/agent-sql AI Agent Skill
$ npx skills add shhac/agent-skills --skill agent-sql --global GitHub Release (macOS)
$ curl -L https://github.com/shhac/agent-sql/releases/latest/download/agent-sql-darwin-arm64.tar.gz | tar xz Go Install
$ go install github.com/shhac/agent-sql/cmd/agent-sql@latest Build from Source
$ git clone https://github.com/shhac/agent-sql.git && cd agent-sql && make build Getting Started
The -c flag accepts a file path, a connection URL or a saved alias. For a database you use repeatedly, store the secret in the OS keychain as a credential and reference it from a named connection — the config file is plaintext on disk, so agent-sql refuses to put a password in it.
01 · Quick ad-hoc query
$ agent-sql run -c ./data.db 'SELECT * FROM users' SQLite and DuckDB files work straight from a path. PostgreSQL, CockroachDB, MySQL, MariaDB, Snowflake and MSSQL take connection URLs, with driver options as query-string params.
02 · Store the secret without it passing through chat
$ agent-sql credential add pg-cred --username app --form --form opens a native OS dialog so the user types the secret directly into the OS; the agent only sees a redacted receipt. Use --password for headless setups, where --form fails with a hint rather than hanging.
03 · Add a named connection that references it
$ agent-sql connection add mydb postgres://localhost:5432/myapp --credential pg-cred Driver, host, port and database are auto-detected from the string. A URL with credentials embedded is rejected — they belong in the keychain.
04 · Test it, then explore
$ agent-sql connection test Then agent-sql schema tables. Every command group has its own usage subcommand, and agent-sql usage gives the overview.
Usage
$ agent-sql schema tables $ agent-sql schema describe users --detailed $ agent-sql schema search email $ agent-sql query sample users --limit 5 $ agent-sql query count users --where "age >= 21" $ agent-sql query explain "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --analyze $ agent-sql run -c duckdb:// "SELECT * FROM 'data/*.parquet'" $ agent-sql run 'SELECT * FROM users' --compact