sql-agent-cli gives people and coding agents a safe, predictable way to inspect MySQL, MariaDB, PostgreSQL, and SQLite databases. It runs one read-only SQL statement at a time, rejects writes before connecting, and returns deterministic output that agents can parse reliably.
You need an existing database and access to it from the machine where your agent runs. For a network database, obtain its hostname, database name, and a login with read access. A password-free connection URL can supply those details. SQLite needs only an existing database file.
Install uv, then run setup in your terminal. uvx obtains the CLI and its Python dependencies. No database client installation is required.
# Install uv if it is not already available.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Open a new PowerShell terminal after installation.
uvx sql-agent-cli setup# Install uv if it is not already available.
curl -LsSf https://astral.sh/uv/install.sh | sh
# Open a new terminal after installation.
uvx sql-agent-cli setupSetup asks only for missing connection details. It masks password input with asterisks, verifies the database, saves the target and any entered password separately, and installs the managed skill in ~/.agents/skills/sql-agent-cli/SKILL.md. Environment variables are optional. No separate test or skill installation command is needed.
To skip connection questions, supply a password-free URL. These commands work in both shells. Replace the example connection details with yours:
uvx sql-agent-cli setup "postgres://reader@db.example.com/app"
uvx sql-agent-cli setup "mysql://reader@db.example.com/app"
uvx sql-agent-cli setup "mariadb://reader@db.example.com/app"
For SQLite, use an existing file:
uvx sql-agent-cli setup 'C:\data\app.db'uvx sql-agent-cli setup "$HOME/data/app.db"Start a new agent session that discovers ~/.agents/skills, then ask:
Use the sql-agent-cli skill to list the tables in my default database and explain their columns. Do not read application rows yet.
Use your agent's skill picker if needed. This project supports the agent-agnostic location only. It does not install an agent-specific copy. A remote agent or container needs its own reachable database, configuration, credentials, and skill files.
See Setup and authentication for required permissions, native authentication, private CAs, password renewal, multiple targets, and troubleshooting.
Inspect, update, or remove the managed skill:
uvx sql-agent-cli skill status
uvx sql-agent-cli skill install
uvx sql-agent-cli skill removeNormal runs of an installed CLI keep an existing, unmodified managed skill synchronized with the running CLI version. Missing skills and unmanaged files are left alone. Use skill install --force to restore modified managed content.
See Managed agent skill for integrity metadata, automatic synchronization, custom locations, compatibility aliases, and removal behavior.
JSON is the default output because it is reliable for agents and automation:
{
"target": {
"name": "reporting",
"engine": "postgres",
"database": "app",
"user": "reader",
"host": "db.example.com",
"port": 5432,
"ssl_mode": "required"
},
"query": {
"input": "SELECT COUNT(*) AS total FROM users",
"normalized": "SELECT COUNT(*) AS total FROM users",
"statement_type": "select"
},
"result": {
"columns": ["total"],
"rows": [[842]],
"returned_row_count": 1,
"truncated": false
}
}Target metadata never includes passwords. The result reports its columns, rows, returned row count, and whether the configured row limit truncated the output.
See Output and compatibility contract for value serialization, diagnostic output, stable fields, and compatibility guarantees.
Run a query against the configured default target:
uvx sql-agent-cli "SELECT id, name FROM users ORDER BY id LIMIT 10"Select a named target when needed:
uvx sql-agent-cli --target reporting "SELECT COUNT(*) AS total FROM users"Query an existing SQLite database without saving a target:
uvx sql-agent-cli --engine sqlite --path C:\data\app.db "SELECT * FROM customers LIMIT 5"To install the command as a persistent tool instead:
uv tool install sql-agent-cliThe examples below continue to use uvx sql-agent-cli so they work without a global installation.
Every invocation follows the same five steps:
- Accept exactly one query from an argument, a file, or stdin.
- Resolve a configured or one-off database target.
- Parse the SQL and reject unsafe or unsupported statements before connecting.
- Execute the query in a read-only database session with time and row limits.
- Write the result in deterministic JSON, Markdown, table, or CSV form.
The default-target happy path is intentionally short:
uvx sql-agent-cli "SELECT ..."The CLI resolves the target in this order:
- A target selected with
--target NAME - A one-off target created with
--engineand connection options - The target named by
SQL_AGENT_CLI_TARGET - The target named by
[defaults].targetin~/.sql-agent-cli/config.toml
The first successful setup creates a default target. Repeat setup to verify and reuse it. Add a named target without changing the existing default:
uvx sql-agent-cli setup
uvx sql-agent-cli setup "postgres://reader@db.example.com/analytics" --target reporting
uvx sql-agent-cli config set-default-target reporting
Inspect configuration without exposing passwords or changing files:
uvx sql-agent-cli targets
uvx sql-agent-cli config show
uvx sql-agent-cli config check --offline
uvx sql-agent-cli config check --all
Ordinary settings live in ~/.sql-agent-cli/config.toml. Entered passwords live in a separate credentials.toml beside it. Files use normal inherited permissions. The setup guide explains overrides and agent access.
Existing config add-target, config set-default-target, config init-native-auth, --password-stdin, and --prompt-password commands remain available.
Setup reuses saved credentials or native authentication when available. Otherwise it offers a masked password prompt. SQL_AGENT_CLI_PASSWORD overrides saved or native credentials for the current execution environment. PostgreSQL also accepts PGPASSWORD. Neither is saved by setup.
New network targets created by setup default to verify-full, which verifies the server certificate and hostname. Supply --ssl-ca PATH for a private CA. Existing targets keep their TLS setting.
| Option | Behavior |
|---|---|
--ssl-mode verify-full |
Require TLS and verify the certificate and hostname |
--ssl-mode required |
Require encryption without guaranteeing server identity |
--ssl-mode preferred |
Attempt TLS but allow plaintext fallback |
--ssl-mode disabled |
Disable TLS |
--insecure |
Query shorthand for --ssl-mode preferred |
Legacy direct connections still default to required. The tool never weakens TLS automatically.
Positional SQL is the normal input form. The explicit alternatives are useful for scripts and longer queries:
uvx sql-agent-cli --target reporting --query "SELECT NOW()"
uvx sql-agent-cli --target reporting --sql-file query.sql
Get-Content query.sql | uvx sql-agent-cli --target reportingProvide exactly one query source per invocation.
| Format | Best for |
|---|---|
json |
Agents, scripts, and automation |
markdown |
Reports and chat responses |
table |
Terminal inspection |
csv |
Import into other tools |
Select a format with --format:
uvx sql-agent-cli --format table "SELECT id, name FROM users LIMIT 10"
uvx sql-agent-cli --format markdown "SELECT id, name FROM users LIMIT 10"
uvx sql-agent-cli --format csv "SELECT id, name FROM users LIMIT 10"Stdout is reserved for payload output. Diagnostics and errors go to stderr.
Supported statement classes include:
SELECTWITH ... SELECTSHOWDESCRIBEandDESCEXPLAIN
The CLI rejects mutating and administrative statements before connecting. It executes exactly one statement per invocation. SQLite PRAGMA queries are limited to an explicit read-only allowlist.
The safety model has several layers:
- Parser-backed validation rejects writes, stacked statements, locking reads, unsafe functions, and mutating SQLite pragmas
- PostgreSQL and MySQL or MariaDB sessions are configured read-only
- SQLite files are opened in read-only mode
- Query timeouts and row limits bound execution and output
These controls are defense in depth. They are not a substitute for database authorization. Configure targets with dedicated roles that have only the read and metadata privileges they need.
After a connection failure, check the default target with a constant query and a bounded catalog query:
uvx sql-agent-cli config check
uvx sql-agent-cli config check --format jsonUse --target NAME to check one named target or --all to check every configured target. The result includes non-secret target settings, credential-source availability, and connection status.
If target selection is unclear, list the configured targets:
uvx sql-agent-cli targets --format jsonNormal queries should start with the default-target happy path. Setup already verifies the target. A check is useful when troubleshooting a later failure.
| Command | Purpose |
|---|---|
uvx sql-agent-cli "SELECT ..." |
Query the default target |
uvx sql-agent-cli --target NAME "SELECT ..." |
Query a named target |
uvx sql-agent-cli targets |
List targets and identify the default |
uvx sql-agent-cli config show |
Show effective non-secret configuration |
uvx sql-agent-cli setup |
Verify and save a database, then install its skill |
uvx sql-agent-cli config check |
Check connectivity, read-only session, and catalog access |
uvx sql-agent-cli config --help |
Show target-management commands |
uvx sql-agent-cli skill --help |
Show skill-management commands |
uvx sql-agent-cli --about |
Show version, project, and license metadata |
uvx sql-agent-cli --help |
Show all query and connection options |
Exit codes:
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime, connection, driver, timeout, or query-execution failure |
2 |
Command usage or SQL validation failure |
Normal query failures emit no stdout payload. setup --format json and config check --format json emit structured diagnostic reports even on failure. They return 1 for runtime failures and 2 for missing or invalid input.
See the output contract for stable JSON fields, value serialization, stdout and stderr behavior, and the compatibility policy.
List visible tables on a PostgreSQL or MySQL target through the information schema:
uvx sql-agent-cli --target reporting "SELECT table_schema, table_name FROM information_schema.tables ORDER BY table_schema, table_name LIMIT 100"Summarize records without retrieving unnecessary detail:
uvx sql-agent-cli --target reporting "SELECT status, COUNT(*) AS total FROM orders GROUP BY status ORDER BY status"Inspect a query plan without running a write:
uvx sql-agent-cli "EXPLAIN SELECT id, name FROM users WHERE email = 'user@example.com'"Version 0.14.0 is a pre-1.0 release. Its command, config, JSON, and exit-code contracts are being stabilized for 1.0. Incompatible changes found during testing will be documented.
The current behavior target is defined in spec.md. See CHANGELOG.md for release history and SECURITY.md for the security model and vulnerability-reporting guidance.
Run the CLI from a source checkout:
uv run ./sql_agent_cli.py --help
uv run ./sql_agent_cli.py "SELECT 1"Run the no-network test suite and lint checks:
uv run --locked python -m unittest discover -v
uvx ruff==0.16.1 check .
uvx ruff==0.16.1 format --check .Build and smoke-test an installed wheel in an isolated environment:
uv build --no-sources
uv run --no-project --with ./dist/sql_agent_cli-0.14.0-py3-none-any.whl python tests/wheel_smoke.pyCI runs the no-network suite on Python 3.11, 3.12, and 3.13 on Linux, plus Python 3.13 on Windows. It also runs opt-in integration tests against PostgreSQL and MySQL service containers.
To run those integration tests locally, set SQL_AGENT_CLI_INTEGRATION=1 and provide the documented SQL_AGENT_CLI_POSTGRES_* and SQL_AGENT_CLI_MYSQL_* environment variables:
uv run --locked python -m unittest tests.test_network_integration tests.test_read_only_integration -vMIT