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

01

Eight drivers, one interface — PostgreSQL, CockroachDB, MySQL, MariaDB, SQLite, DuckDB, Snowflake and MSSQL

02

Two gates before any write — the credential must carry writePermission and the query must pass --write, so allowed credentials still cannot write by accident

03

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

04

Fails closed on syntax it cannot parse — the CockroachDB guard refuses CRDB-specific syntax rather than waving it through

05

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

06

Config files never hold secrets — connection add rejects URLs with embedded credentials and demands a keychain-backed --credential instead

07

Schema exploration — tables, describe, indexes, constraints, pattern search and a whole-schema dump

08

Query surface — run, sample, count with --where, and explain with optional --analyze

09

Parquet through DuckDB — query files directly with duckdb:// and a glob, no import step

10

Result caps and timeouts by default — 10,000 rows and 30s, both configurable and overridable per command

11

Token-aware output — --compact emits typed NDJSON with column names once and rows as arrays; long strings truncate with @truncated metadata recording original lengths

12

Honest pagination — a trailing @pagination line says whether more rows exist rather than silently cutting off

13

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

14

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

>_ List tables
$ agent-sql schema tables
>_ Describe a table in full
$ agent-sql schema describe users --detailed
>_ Find every column matching a pattern
$ agent-sql schema search email
>_ Sample rows without writing SQL
$ agent-sql query sample users --limit 5
>_ Count with a predicate
$ agent-sql query count users --where "age >= 21"
>_ Explain a join, with real timings
$ agent-sql query explain "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --analyze
>_ Query parquet directly through DuckDB
$ agent-sql run -c duckdb:// "SELECT * FROM 'data/*.parquet'"
>_ Fewer tokens per row
$ agent-sql run 'SELECT * FROM users' --compact