dbcli β€” Database CLI for AI Agents

Languages: English | 繁體中文

A unified database CLI tool that enables AI agents (Claude Code, Gemini, Copilot, Cursor) to safely query, discover, and operate on databases.

Core Value: AI agents can safely and intelligently access project databases through a single, permission-controlled CLI tool with sensitive data protection.

Security update: dbcli init now writes only a small project binding stub into ./.dbcli/config.json. The full connection configuration is stored under ~/.config/dbcli/projects/<project-id>/config.json, so sensitive settings do not live inside the project workspace by default.

Internationalization (i18n)

dbcli supports multiple languages via the DBCLI_LANG environment variable:

# English (default)
dbcli init

# Traditional Chinese
DBCLI_LANG=zh-TW dbcli init

# Or set in .env
export DBCLI_LANG=zh-TW
dbcli init

Supported languages:

  • en β€” English (default)
  • zh-TW β€” Traditional Chinese (Taiwan)

All messages, help text, error messages, and command output respond to the language setting automatically.

Quick Start

Installation

Global Installation (Recommended)

bun install -g @carllee1983/dbcli
# or: npm install -g @carllee1983/dbcli

dbcli runs on Bun. npm and npx are supported as distribution channels, but the installed dbcli executable requires Bun 1.3.3+ on your PATH β€” install it first with curl -fsSL https://bun.sh/install | bash. Only the ./agent-core subpath export is importable from a plain Node process.

Zero-Install (No Installation Needed)

bunx @carllee1983/dbcli init
bunx @carllee1983/dbcli query "SELECT * FROM users"
# or with npm: npx @carllee1983/dbcli init

Update

# Self-update (recommended)
dbcli upgrade

# Or via npm
npm update -g @carllee1983/dbcli

Development Installation

git clone https://github.com/CarlLee1983/dbcli.git
cd dbcli
bun install
bun run src/cli.ts -- --help
# or: bun run dev -- --help

When dbcli is not on your PATH, use bun run src/cli.ts <subcommand> ... (same as bun run dev -- <subcommand> ...).

First Steps

# Initialize project with database connection
dbcli init

# Interactive shell (SQL + dbcli commands, tab completion)
dbcli shell

# List available tables
dbcli list

# View table structure
dbcli schema users

# Query data
dbcli query "SELECT * FROM users"

# Preview schema DDL (dry-run by default; add --execute to apply)
dbcli migrate create posts --column "id:serial:pk" --column "title:varchar(200):not-null"

# Generate AI agent skill
dbcli skill --install claude

Agent first-look

dbcli inspect --for-agent

A single read-only command that returns a bounded JSON snapshot of the current connection, permission level, blacklist size, schema cache freshness, available saved-query intents, and the safest next commands to run. No host, no port, no credentials β€” safe to log or pipe to an LLM.

Diagnostic report

dbcli report --format json

Builds on inspect to also run curated read-only built-in @diag/* snippets grouped into health / capacity / perf sections. Bounded by per-snippet timeout and per-evidence row cap. Use --format markdown for human reading, --section health,capacity to scope, or --for-agent for compact JSON.

Guide

dbcli guide slow-query --format json

Deterministic next-command planner. Pick a goal (slow-query, capacity, health, index-usage, permissions, schema-overview) and dbcli guide emits an ordered plan that combines dbcli inspect, engine-appropriate @diag/* snippets, and dbcli queries suggest / dbcli doctor follow-ups. The planner is cache-first (no network); add --probe to refresh the underlying inspect context. Use --list to see all goals, --format markdown for human reading, or --for-agent for compact JSON.

Interactive HTML Dashboards

# Open results in browser
dbcli query "SELECT * FROM orders" --ui

# Run a saved snippet with visualization metadata
dbcli q @analytics/revenue --ui

# Export query results as a standalone HTML file
dbcli export "SELECT * FROM users" --format html --output report.html

dbcli can render query results as fully interactive, standalone HTML dashboards. These reports are powered by React + Recharts and are zero-dependency β€” the entire application and data are inlined into a single HTML file.

  • --ui flag: Automatically generates a temporary report and opens it in your default browser.
  • visual: block: Snippet frontmatter can define KPIs and charts (Line, Bar, Area, Pie) to drive the dashboard.
  • Security: Result sets are redacted by the blacklist before injection, and data is safely escaped for HTML.
  • Completeness warnings: Truncation and security metadata are shown before KPIs, charts, and the raw table so incomplete or masked data is never presented as a complete result.

Recovery & Guided Remediation

# Lookup recovery commands for a code
dbcli recovery --code CONN_REFUSED --format json

# Execute a failing command with recovery opt-in
dbcli query "SELECT 1" --recovery

# (v1.17.0+) Inspect or apply the last saved recovery plan
dbcli recover                       # View last plan (Markdown)
dbcli recover --apply               # Execute safe steps (readonly/dry-run)
dbcli recover --apply --allow-write=readonly-cmd  # Allow local writes
dbcli recover --apply --allow-write=write-cmd     # Allow database writes

# (v1.17.0+) Multi-turn recovery (for AI agents)
dbcli recover --next --after-step 1 --result '{"status":"ok"}'

Machine-readable error envelope with guided remediation. As of v1.16.0 every first-party command accepts the --recovery flag. In v1.17.0, the recover command was added to automate the execution of these plans.

  • Risk Gating: --apply is safe-by-default, running only readonly and dry-run steps. Elevated tiers require --allow-write.
  • Verification: After a successful --apply, dbcli automatically runs a verification step to confirm the fix actually worked.
  • Multi-turn Protocol: The --next flag allows agents to advance recovery one step at a time, providing the result of the previous step to enable deterministic branching.

dbcli inspect --require-schema-cache throws SCHEMA_CACHE_MISSING when the active SQL connection has no usable schema cache; combine with --recovery to receive the structured envelope.

For write commands (insert / update / delete), BLACKLIST_COLUMN_WRITE and PERMISSION_DENIED envelopes lead with a risk: 'dry-run' step that suggests previewing the SQL with --dry-run before re-attempting.

MongoDB Atlas / SRV Connections

MongoDB connections are supported via both standard mongodb:// URIs and Atlas-style mongodb+srv:// URIs.

# Atlas / SRV connection
dbcli init --system mongodb --conn-name atlas --uri "mongodb+srv://user:[email protected]/mydb"

# List collections in the configured MongoDB database
dbcli list --use atlas

# Query a collection with JSON filter or pipeline
dbcli query '{"status":"active"}' --collection users --use atlas

For MongoDB, list and query operate on the database configured for the connection, and query requires --collection <name>.

For a command-by-command support matrix across PostgreSQL, MySQL, MariaDB, MongoDB, Redis, and Elasticsearch, see docs/feature-matrix.md.

Redis & Elasticsearch Support

dbcli extends its unified interface to Redis and Elasticsearch, providing consistent discovery and querying.

Redis

# Connect to Redis
dbcli init --system redis --host localhost --port 6379

# List keys (uses SCAN)
dbcli list

# Inspect a key (type, TTL, size, sample)
dbcli schema my-key

# Run Redis commands (whitelisted)
dbcli query "GET my-key"
dbcli query "HGETALL user:1"

Elasticsearch

# Connect to Elasticsearch
dbcli init --system elasticsearch --host localhost --port 9200

# List indices and document counts
dbcli list

# Show mapping/structure of an index
dbcli schema my-index

# Query using Lucene or DSL JSON
dbcli query "status:active" --index my-index
dbcli query '{"query": {"match_all": {}}}' --index my-index

Multi-connection Support (v2)

dbcli supports multiple named database connections within a single project. This is useful for managing different environments (development, staging, production) or multiple databases.

The project .dbcli directory now acts as a binding + cache layer. The actual connection config is stored in ~/.config/dbcli/projects/<project-id>/, which keeps sensitive settings out of the workspace by default.

Initializing Named Connections

To create a named connection, use the --conn-name option during init. You can also specify a custom .env file for that connection.

# Add a staging connection using .env.staging
dbcli init --conn-name staging --env-file .env.staging

# Add a production connection with environment variable references
dbcli init --conn-name prod --env-file .env.production --use-env-refs

For connections shared across projects, use the user-global scope. It stores a v2 registry at ~/.config/dbcli/config.json and leaves the current project's .dbcli binding untouched:

dbcli --global init --conn-name shared --system postgresql --host db.example.com \
  --port 5432 --user app --password '<secret>' --name appdb \
  --skip-test --no-interactive --force
dbcli --global use --list --format json
dbcli --global query "SELECT 1"

Root-level --global must precede the command. Without it, commands continue to use the project configuration.

Managing Connections

Use the dbcli use command to switch between connections or list them.

# List all connections (* marks the current default)
dbcli use --list

# Switch the default connection to 'staging'
dbcli use staging

# Show the current default connection
dbcli use

# Remove a connection
dbcli init --remove staging

# Rename a connection
dbcli init --rename staging:production

Using a Specific Connection Temporarily

You can use the --use <name> global flag, the supported command-level form, or DBCLI_CONNECTION to execute against a specific connection without changing the default. Selection precedence is explicit --use, then DBCLI_CONNECTION, then the configured default. A selector is rejected for legacy v1 single-connection configuration instead of being silently ignored.

# Query the production database once
dbcli query "SELECT count(*) FROM users" --use prod

# Check staging table health
dbcli check users --use staging

# Select one connection for this process
DBCLI_CONNECTION=prod dbcli query "SELECT count(*) FROM users"

query, schema, list, export, and check accept the command-level --use form shown above. Other commands use the global form before the subcommand.

For read-only comparisons, an explicit comma-separated --use fans one query out to multiple named connections:

dbcli query --use primary,staging "SELECT count(*) FROM users" --format json

SQL fan-out permits SELECT, SHOW, DESCRIBE, and EXPLAIN; MongoDB permits filters and read-only pipelines; Elasticsearch permits search. Redis, writes, --recovery, --ui, CSV, and HTML are rejected. Connections run independently: JSON returns an ordered results array, table output labels each section, and one failure does not cancel the others. Exit codes are 0 for all success, 2 for mixed outcomes, and 1 for all failures or a preflight rejection. DBCLI_CONNECTION always names one literal connection and never enables fan-out.


dbcli init

Initialize a new dbcli project with database connection configuration.

Usage:

dbcli init [OPTIONS]

Options (Basic):

  • --system <type> β€” Database system: postgresql, mysql, mariadb, mongodb
  • --host <host> β€” Database host
  • --port <port> β€” Database port
  • --user <user> β€” Database user
  • --password <pass> β€” Database password
  • --name <db> β€” Database name
  • --permission <level> β€” Permission level: query-only, read-write, data-admin, admin
  • MongoDB only: --uri <uri> β€” full connection URI (mongodb://… or mongodb+srv://…); --auth-source <db> β€” auth database (default admin when using user/password)
  • --use-env-refs β€” Store environment variable references instead of actual values in config
  • --skip-test β€” Skip connection test
  • --no-interactive β€” Non-interactive mode (requires all options)
  • --force β€” Overwrite existing config without confirmation

Options (Multi-connection v2):

  • --conn-name <name> β€” Create a named connection (e.g., staging, prod)
  • --env-file <path> β€” Load credentials from a specific .env file for this connection
  • --remove <name> β€” Remove a named connection from the config
  • --rename <old:new> β€” Rename an existing connection (format: old:new)

Behavior:

  • Reads .env file if present (auto-fills DATABASE_URL, DB_* variables)
  • Prompts for missing values (host, port, user, password, database name, permission level)
  • Creates a project binding stub in .dbcli/config.json and stores the full config under ~/.config/dbcli/projects/<project-id>/
  • Tests database connection before saving

Examples:

# Interactive initialization
dbcli init

# Multi-connection setup
dbcli init --conn-name staging --env-file .env.staging
dbcli init --conn-name prod --env-file .env.production --use-env-refs

# Store env var references (non-interactive)
dbcli init --use-env-refs --system mysql \
  --env-host DB_HOST --env-port DB_PORT \
  --env-user DB_USER --env-password DB_PASSWORD \
  --env-database DB_DATABASE \
  --no-interactive

dbcli use (Requires v2 config)

Manage or switch the default database connection in multi-connection projects.

Usage:

dbcli use [connection-name] [OPTIONS]

Options:

  • --list β€” List all connections and show the current default

Examples:

# Show current default connection
dbcli use

# Switch default connection to 'prod'
dbcli use prod

# List all connections
dbcli use --list

--use-env-refs: When enabled, the config stores environment variable names (e.g., {"$env": "DB_HOST"}) instead of actual values. This avoids writing sensitive credentials into the config file, making it suitable for multi-environment deployments and CI/CD pipelines. At connection time, dbcli automatically reads the actual values from the referenced environment variables.

Storage model: The project .dbcli directory is now a binding + cache layer, not the canonical home for secrets. If you inspect ./.dbcli/config.json, you should only see the binding metadata; the full config lives in the home storage path shown above.


dbcli list

List all tables in the connected database.

Usage:

dbcli list [OPTIONS]

Options:

  • --format json β€” Output as JSON instead of ASCII table

Examples:

# Table format (human-readable)
dbcli list

# JSON format (for AI parsing)
dbcli list --format json

# Pipe to tools
dbcli list --format json | jq '.data[].name'

dbcli schema [table]

Show table structure (columns, types, constraints, foreign keys).

Usage:

dbcli schema [table]
dbcli schema                 # Scan entire database and update .dbcli
dbcli schema users           # Show structure of 'users' table

Options:

  • --format json β€” Output as JSON
  • --refresh β€” Detect and update schema changes incrementally (requires --force for approval)
  • --reset β€” Clear all existing schema data and re-fetch from database (useful after switching DB connections)
  • --force β€” Skip confirmation for schema refresh/overwrite/reset

Examples:

# Show users table structure
dbcli schema users

# JSON output with full metadata
dbcli schema users --format json

# Update schema with new tables (incremental)
dbcli schema --refresh --force

# Clear and re-fetch all schema (after switching DB)
dbcli schema --reset --force

# Scan entire database
dbcli schema

dbcli query [query]

Execute a SQL statement, MongoDB filter/pipeline, allow-listed Redis command, or Elasticsearch DSL/Lucene query and return results.

Usage:

dbcli query "SELECT * FROM users"
dbcli query --query-file ./queries/active-users.sql

Options:

  • --format json|table|csv|html β€” Output format (default: table)
  • --ui β€” Render HTML to a temporary file and open it in the system browser
  • --limit <number> β€” Cap rows (overrides the automatic limit in query-only mode)
  • --no-limit β€” Disable the automatic 1000-row cap in query-only mode
  • -f, --query-file <path> β€” Read a UTF-8 query from a file; use - for piped stdin
  • --fields <list> β€” Include a,b or exclude -a,-b fields from SQL/MongoDB results
  • --truncate <number> β€” Set the table cell limit in Unicode code points (default: 120)
  • --no-truncate β€” Show complete table cells

Behavior:

  • Enforces permission-based restrictions (Query-only mode blocks INSERT/UPDATE/DELETE)
  • Requires exactly one query source: positional text, --query-file <path>, or piped stdin through --query-file -
  • Auto-limits results to 1000 rows in Query-only mode, unless --no-limit or --limit applies
  • Uses a one-row lookahead for dbcli-owned limits. Truncated tables say so in the footer, JSON returns metadata.truncated and metadata.limit_applied, and CSV appends a truncation comment
  • Applies --fields after SQL execution and pushes it into MongoDB find/pipeline operations. Blacklist masking remains authoritative
  • Truncates table cells only; JSON and CSV rows remain lossless. Explicit truncation flags with JSON, CSV, HTML, or --ui are rejected
  • To write CSV/JSON to a file, use shell redirection or the export command

Examples:

# Table output (human-readable)
dbcli query "SELECT * FROM users"

# JSON (for AI/programmatic parsing)
dbcli query "SELECT * FROM users" --format json

# CSV to stdout (redirect to a file)
dbcli query "SELECT * FROM users" --format csv > users.csv

# Pipe to other tools
dbcli query "SELECT * FROM products" --format json | jq '.data[] | .name'

# Large result sets (paginate with LIMIT/OFFSET)
dbcli query "SELECT * FROM users LIMIT 100 OFFSET 0"

# Multiline SQL from stdin
dbcli query --query-file - <<'SQL'
SELECT id, email
FROM users
WHERE status = 'active';
SQL

# Include or exclude fields (use = when the value starts with a hyphen)
dbcli query "SELECT * FROM users" --fields id,email,status
dbcli query "SELECT * FROM users" --fields=-password_hash,-raw_payload

dbcli insert [table] (Requires Read-Write or Admin permission)

Insert data into table.

Usage:

dbcli insert users --data '{"name": "Alice", "email": "[email protected]"}'

Options:

  • --data JSON β€” Row data as JSON object (REQUIRED)
  • --dry-run β€” Show SQL without executing
  • --force β€” Skip confirmation

Behavior:

  • Validates JSON format
  • Generates parameterized SQL (prevents SQL injection)
  • Shows confirmation prompt before inserting (unless --force used)

Examples:

# Insert single row
dbcli insert users --data '{"name": "Bob", "email": "[email protected]"}'

# Preview SQL without executing
dbcli insert users --data '{"name": "Charlie"}' --dry-run

# Skip confirmation
dbcli insert users --data '{"name": "Diana"}' --force

dbcli update [table] (Requires Read-Write or Admin permission)

Update existing rows.

Usage:

dbcli update users --where "id=1" --set '{"name": "Alice Updated"}'

Options:

  • --where condition β€” WHERE clause (REQUIRED, e.g., "id=1 AND status='active'")
  • --set JSON β€” Updated columns as JSON object (REQUIRED)
  • --dry-run β€” Show SQL without executing
  • --force β€” Skip confirmation

Examples:

# Update single row
dbcli update users --where "id=1" --set '{"name": "Alice"}'

# Update multiple rows
dbcli update users --where "status='inactive'" --set '{"status":"active"}'

# Preview SQL
dbcli update users --where "id=1" --set '{"name": "Bob"}' --dry-run

# Skip confirmation
dbcli update users --where "id=2" --set '{"email": "[email protected]"}' --force

dbcli delete [table] (Requires Data-Admin or Admin permission)

Delete rows (blocked for query-only and read-write; requires elevated DML permission).

Usage:

dbcli delete users --where "id=1" --force

Options:

  • --where condition β€” WHERE clause (REQUIRED)
  • --dry-run β€” Show SQL without executing
  • --force β€” Required to actually delete (safety guard)

Examples:

# Delete single row (requires --force)
dbcli delete users --where "id=1" --force

# Preview deletion
dbcli delete products --where "status='deprecated'" --dry-run

# Delete multiple rows
dbcli delete orders --where "created_at < '2020-01-01'" --force

dbcli export "SQL"

Export query results to file.

Usage:

dbcli export "SELECT * FROM users" --format json --output users.json

Options:

  • --format json|csv β€” Output format
  • --output file β€” Write to file (default: stdout for piping)
  • --limit <number> β€” Deliberately accept a bounded export
  • --no-limit β€” Export the complete result

Behavior:

  • Query-only mode still applies its automatic 1000-row limit, but reaching it fails closed with exit code 1 and writes no partial file
  • Re-run with --no-limit for the complete export or --limit N to accept a cap explicitly
  • Generates RFC 4180 compliant CSV
  • Creates well-formed JSON arrays

Examples:

# Export to JSON
dbcli export "SELECT * FROM users" --format json --output users.json

# Export to CSV
dbcli export "SELECT * FROM orders" --format csv --output orders.csv

# Pipe compressed export
dbcli export "SELECT * FROM products" --format csv | gzip > products.csv.gz

# Combine with query tools
dbcli export "SELECT * FROM users WHERE active=true" --format json | jq '.data | length'

dbcli skill

Generate or install AI agent skill documentation.

Usage:

dbcli skill                           # Output skill to stdout
dbcli skill --output SKILL.md         # Write to file
dbcli skill --install claude          # Install to Claude Code config
dbcli skill --install gemini          # Install to Gemini CLI (being phased out)
dbcli skill --install antigravity     # Install to Antigravity CLI (Gemini CLI's successor)
dbcli skill --install copilot         # Install to GitHub Copilot
dbcli skill --install cursor          # Install to Cursor IDE
dbcli skill --install codex           # Install to Codex skills
dbcli skill --install windsurf        # Install to Windsurf (.windsurfrules)

Behavior:

  • Ships canonical assets/SKILL.md + assets/reference.md (single source of truth: concise skill + long command reference)
  • Prints the skill to stdout, writes it with --output, or copies it to a platform-specific path with --install
  • Actual database access is still enforced by your .dbcli permission level and blacklist β€” the skill text describes the full CLI surface

Examples:

# Generate skill for Claude Code
dbcli skill --install claude

# Generate skill manually for documentation
dbcli skill > ./docs/SKILL.md

# View generated skill (stdout)
dbcli skill

# Install for all platforms
dbcli skill --install claude && \
dbcli skill --install gemini && \
dbcli skill --install antigravity && \
dbcli skill --install copilot && \
dbcli skill --install cursor && \
dbcli skill --install codex

dbcli blacklist

Manage the data access blacklist to block AI agents from accessing sensitive tables or columns.

Usage:

dbcli blacklist list
dbcli blacklist table add <table>
dbcli blacklist table remove <table>
dbcli blacklist column add <table>.<column>
dbcli blacklist column remove <table>.<column>

Subcommands:

Subcommand Description
dbcli blacklist list Show current blacklist (tables and columns)
dbcli blacklist table add <table> Add table to blacklist (blocks all operations)
dbcli blacklist table remove <table> Remove table from blacklist
dbcli blacklist column add <table>.<column> Add column to blacklist (omitted from SELECT results)
dbcli blacklist column remove <table>.<column> Remove column from blacklist

Behavior:

  • Table blacklist blocks all operations on that table (query, insert, update, delete)
  • Column blacklist silently omits columns from SELECT results and shows a security notification
  • Blacklist rules are stored in .dbcli and apply to all permission levels
  • Override for admin use via DBCLI_OVERRIDE_BLACKLIST=true environment variable

Examples:

# View current blacklist
dbcli blacklist list

# Block all access to sensitive tables
dbcli blacklist table add audit_logs
dbcli blacklist table add secrets_vault

# Hide sensitive columns from query results
dbcli blacklist column add users.password_hash
dbcli blacklist column add users.ssn

# Remove a table from blacklist
dbcli blacklist table remove audit_logs

# Remove a column from blacklist
dbcli blacklist column remove users.ssn

# Override blacklist (admin use only)
DBCLI_OVERRIDE_BLACKLIST=true dbcli query "SELECT * FROM secrets_vault"

dbcli check

Run data-quality and health checks on tables.

Usage:

dbcli check [table] [OPTIONS]

Options:

  • --all β€” Check every table (skips huge tables unless --include-large)
  • --include-large β€” Include huge tables in --all scan
  • --checks <types> β€” Comma-separated checks: nulls, duplicates, orphans, emptyStrings, rowCount, size
  • --sample <number> β€” Sample size for large tables (default: 10000)
  • --format json|table β€” Output format (default: json)

Examples:

# Check users table
dbcli check users

# Run specific checks only
dbcli check orders --checks nulls,orphans --format table
# Scan all tables
dbcli check --all

# Table view + all-tables with selected checks
dbcli check orders --format table
dbcli check --all --checks nulls,duplicates --format json

dbcli diff

Save a schema snapshot, compare the live database to a previous snapshot, or compare an ORM definition with the local SQL schema cache. ORM drift is cache-only: it does not connect, refresh the cache, or execute proposals.

Usage:

dbcli diff --snapshot ./schema-before.json
dbcli diff --against ./schema-before.json
dbcli diff --against ./schema-before.json --format table
dbcli diff --against-orm prisma/schema.prisma --format json
dbcli diff --against-orm drizzle/meta/0001_snapshot.json --orm-format drizzle --format table
dbcli diff --against-orm schema.sql --orm-format typeorm --format table

Options:

  • --snapshot <path> β€” Write the current schema to a JSON file
  • --against <path> β€” Diff live schema vs. the saved snapshot
  • --against-orm <path> β€” Compare Prisma, Drizzle snapshot, TypeORM/Sequelize DDL, raw DDL, or normalized JSON with the cached SQL schema
  • --orm-format prisma|drizzle|typeorm|sequelize|ddl|json β€” Override ORM input detection
  • --format json|table|markdown β€” Output format (default: json)
  • --config <path> β€” Config path (default: .dbcli)

dbcli snapshot

Capture a result fingerprint of a query (distinct from diff, which snapshots schema): row count plus per-column aggregates (null/distinct counts, min/max/sum) and an order-independent checksum. Blacklisted columns are masked at the source, so the snapshot is safe to store. Use it as a baseline for dbcli assert --against. SQL engines only.

Usage:

dbcli snapshot "SELECT * FROM orders WHERE created_at >= '2026-05-01'"   # β†’ .dbcli/snapshots/snap-<timestamp>.json
dbcli snapshot @analytics/daily-revenue --out base.json
dbcli snapshot "SELECT status, count(*) FROM orders GROUP BY status" --stdout

Options:

  • --out <path> β€” Output path (default: .dbcli/snapshots/snap-<timestamp>.json)
  • --rows β€” Also store the full (blacklist-masked) rows
  • --stdout β€” Print snapshot JSON to stdout instead of writing a file
  • --format json|table β€” Output format for --stdout (default: json)
  • --no-limit β€” Disable the automatic query-only LIMIT

dbcli assert

Assert an invariant on a query result. Exits 1 on failure (composes in scripts/CI) unless --no-fail. SQL engines only.

Usage:

dbcli assert "SELECT count(*) FROM orders" --expect "value > 0"
dbcli assert "SELECT * FROM orders WHERE total < 0" --expect "rows == 0"
dbcli assert "SELECT email FROM users" --expect "col:email not null"
dbcli assert "SELECT sum(amount) FROM ledger_a" --vs "SELECT sum(amount) FROM ledger_b" --compare value
dbcli assert "SELECT * FROM orders" --against base.json --tolerance 0.01

Options:

  • --expect <condition> β€” rows > 0, value == 5000, col:email not null, col:id unique, col:amount between 0 and 100, col:age >= 18
  • --vs <query> β€” Reconcile against a second query
  • --compare rows|value β€” Comparison mode for --vs (default: value)
  • --against <path> β€” Compare the current result fingerprint to a saved snapshot
  • --tolerance <pct> β€” Allowed relative drift for --against (e.g. 0.01; default: 0 = exact checksum match)
  • --no-fail β€” Always exit 0; report pass/fail in output only
  • --format json|table β€” Output format (default: json)

dbcli proxy (v1.26)

Local-development observability proxy for MySQL, MariaDB, and PostgreSQL. Point an existing app at the proxy port; dbcli relays all TCP frames to the real database and appends one JSONL event per query to .dbcli/proxy/events.jsonl. Observe-only β€” no rewrite or blocking. Not a production gateway.

Subcommands: mysql Β· mariadb Β· postgresql

dbcli proxy mysql      --listen 127.0.0.1:3307 --target 127.0.0.1:3306
dbcli proxy postgresql --listen 127.0.0.1:5434 --target 127.0.0.1:5432
dbcli proxy mysql      --slow-ms 500 --redact literals
dbcli proxy mariadb    --events ./logs/proxy.jsonl
dbcli proxy analyze --events ./logs/proxy.jsonl --format markdown  # QueryLens report

Options:

  • --listen <addr:port> β€” Proxy listen address
  • --target <addr:port> β€” Real database address (inferred from config / --use if omitted)
  • --events <path> β€” JSONL event log (default: .dbcli/proxy/events.jsonl)
  • --slow-ms <ms> β€” Flag events slower than this threshold as slow: true (default: 1000)
  • --redact none|literals β€” Strip SQL literal values from event records (default: none)
  • --format text|json β€” Startup output format (default: text)

QueryLens: dbcli proxy analyze --format markdown reads the event log offline and produces a shareable Markdown report. It redacts SQL and error-message literals in memory before analysis; use --redact literals while capturing as well to protect the log on disk.


dbcli status

Show non-sensitive configuration summary (permission level, DB system, blacklist counts, config metadata version). Does not print connection credentials β€” intended for AI agents.

Usage:

dbcli status
dbcli status --format text
dbcli status --format json

Options:

  • --format text|json β€” Output format (default: json)

Note: This command reads the default project config path .dbcli (not the global --config flag).


dbcli doctor

Run diagnostic checks on environment, configuration, connection, and data.

dbcli doctor                    # Colored text output
dbcli doctor --format json      # JSON output for AI agents

Checks:

  • Environment: Bun version compatibility, dbcli version (compares with npm registry)
  • Configuration: Config file exists/valid, permission level, blacklist completeness
  • Connection & Data: Database connectivity, schema cache freshness (> 7 days warning), large table warnings (> 1M rows)
  • MongoDB SRV diagnostics: For mongodb+srv:// connections, doctor reports whether the current execution environment can resolve SRV records directly or only through the DNS-over-HTTPS fallback used by dbcli

Options: --format <text|json> Exit code: 0 = all pass or warnings only, 1 = errors found


dbcli completion [shell]

Generate shell completion scripts for tab auto-complete.

dbcli completion bash            # Output bash completion to stdout
dbcli completion zsh             # Output zsh completion to stdout
dbcli completion fish            # Output fish completion to stdout
dbcli completion --install       # Auto-detect shell and install to rc file
dbcli completion --install zsh   # Install for specific shell

Supported shells: bash, zsh, fish

Installed completions cover nested subcommands β€” for example dbcli queries list --<TAB>, dbcli migrate add-column --<TAB>, and dbcli verify safe-backfill --<TAB>.

Inside dbcli shell, command completion follows the current command surface, so newly added commands (q, queries, inspect, verify, proxy, snapshot, …) complete and dispatch automatically.

--install is marker-managed: it writes a single block to your shell rc file and re-running it replaces that block rather than duplicating it.


dbcli upgrade

Check for updates and self-upgrade dbcli.

dbcli upgrade                   # Check and upgrade if newer version available
dbcli upgrade --check           # Only check, do not upgrade

Options: --check β€” check only, don't install

Background checks (stderr, skipped when --quiet or for upgrade / skill):

  • CLI version: dbcli checks the npm registry (cached, about once per 24 hours). If a newer package exists, a one-line hint prints after normal command output.
  • Installed skills: If you used dbcli skill --install <platform>, dbcli compares each installed primary skill file (SKILL.md or dbcli.mdc) to the bundled assets/SKILL.md. When they differ, a short reminder lists which platforms to re-install (dbcli skill --install <platform>). Run dbcli upgrade to see the same skill status together with version info. Re-installing also refreshes reference.md next to the skill.

dbcli shell

Interactive database shell with SQL execution, auto-completion, and syntax highlighting.

Usage:

dbcli shell          # Interactive mode (SQL + dbcli commands)
dbcli shell --sql    # SQL-only mode

Inside the shell:

  • Type SQL statements ending with ; to execute queries
  • Type dbcli commands without the dbcli prefix (e.g., schema users, list)
  • Press Tab for context-aware auto-completion (SQL keywords, table/column names)
  • Use .help for meta commands (.quit, .clear, .format, .history, .timing)
  • Multi-line SQL: input accumulates until ; is found
  • History persists across sessions in ~/.dbcli_history

Permission: Inherits from config. SQL and commands are fully permission/blacklist enforced.

dbcli migrate

Schema DDL operations. All commands default to dry-run β€” use --execute to actually run the SQL.

Usage:

# Create table
dbcli migrate create posts \
  --column "id:serial:pk" \
  --column "title:varchar(200):not-null" \
  --column "body:text" \
  --column "created_at:timestamp:default=now()"

# Execute (actually run the SQL)
dbcli migrate create posts --column "id:serial:pk" --execute

# Drop table (destructive β€” requires --execute --force)
dbcli migrate drop posts --execute --force

# Column operations
dbcli migrate add-column users bio text --nullable --execute
dbcli migrate alter-column users name --type "varchar(200)" --execute
dbcli migrate alter-column users email --rename user_email --execute
dbcli migrate drop-column users temp_field --execute --force

# Index operations
dbcli migrate add-index users --columns email --unique --execute
dbcli migrate drop-index idx_users_email --table users --execute --force

# Constraint operations
dbcli migrate add-constraint orders --fk user_id --references users.id --on-delete cascade --execute
dbcli migrate add-constraint users --unique email --execute
dbcli migrate add-constraint users --check "age >= 0" --execute
dbcli migrate drop-constraint orders fk_orders_user_id --execute --force

# Enum (PostgreSQL only)
dbcli migrate add-enum status active inactive suspended --execute
dbcli migrate alter-enum status --add-value archived --execute
dbcli migrate drop-enum status --execute --force

Column spec format: name:type[:modifier...] β€” Modifiers: pk, not-null, unique, auto-increment, default=<value>, references=<table>.<column>

Options (all subcommands): --execute (run SQL), --force (skip confirmation for DROP), --config <path> Permission: admin only


Query Risk Planning

Use lint for read-only static advice about SQL anti-patterns and optional rewrite drafts. It accepts inline SQL, saved queries, files, globs, and bulk input; it never connects or applies a rewrite:

dbcli lint "SELECT * FROM users WHERE LOWER(email) = '[email protected]'" --format json

Use plan to inspect SQL safety before execution. It reads local dbcli config, permissions, blacklist rules, and cached schema metadata only; it does not connect to the database.

dbcli plan "UPDATE users SET status='inactive'" --format json

Decisions are:

  • ALLOW β€” no obvious risk was detected.
  • WARN β€” inspect warnings before executing.
  • BLOCK β€” unsafe, unsupported, or violates configured safety constraints.

Text output is concise for humans:

Decision: BLOCK
Operation: UPDATE
Target tables: users

Risk factors:
- UPDATE statement has no WHERE clause.

Recommendations:
- Add a WHERE clause.
- Use --dry-run on the actual write command.

JSON output includes suggestedCommands for agents:

dbcli plan "SELECT id FROM users WHERE id = 1 LIMIT 1" --format json

Global Options

All commands support these global options:

Flag Description
--config <path> Path to .dbcli config file (default: .dbcli)
--global Use the user-global registry at ~/.config/dbcli/config.json
--use <connection> Use a named v2 connection for this invocation only (does not change the default)
-v, --verbose Increase verbosity (-v verbose, -vv debug)
-q, --quiet Suppress non-essential output
--no-color Disable colored output (respects NO_COLOR env var)

Internals & Strategy

Schema Update Strategy

dbcli maintains a schema snapshot in your .dbcli config file. This allows AI agents to understand the database structure without constant network overhead. Understanding when this cache updates is key:

  1. Manual Updates:
    • dbcli schema: Performs a full scan of the database.
    • dbcli schema --refresh: Incremental update. Detects changes and updates only the affected tables.
    • dbcli schema --reset: Clears the cache and re-fetches everything.
  2. Automatic Updates (DDL):
    • When you execute DDL through dbcli migrate (e.g., add-column), the CLI automatically re-scans the affected table and updates the .dbcli snapshot after successful execution.
  3. Real-time Validation (Non-cached):
    • Commands like insert, update, delete, and check fetch the latest schema from the database immediately before execution to ensure data integrity, but they do not update the long-term snapshot in .dbcli.

Note: If you change the d