Command-line mode
Run RED headless to query, script, and seed dev/staging databases.
RED runs headless from a terminal for the things you don't want a window for: running a query in a script, executing a migration, or seeding a dev/staging database from another connection. It's the same binary and the same backend as the app - a subcommand runs the command and exits; a bare launch opens the desktop app as usual.
Still evolving
The verbs below are stable in shape, but flags and output may still change before the first stable release.
Invocation
red <command> [args] # runs headless, then exits
red # no command → opens the desktop appBuilding from source? Pass args through Cargo:
cargo run -p red -- query mydb "SELECT 1"Referencing a connection
Every verb takes a connection as its first argument. It resolves, in order:
- A saved connection by name (the ones you manage in the app) - credentials are read from the OS keychain, exactly like the GUI.
- An inline DSN - handy in CI where nothing is saved:
red query "postgres://user:pass@host:5432/shop" "SELECT count(*) FROM orders"
red exec "sqlite:///abs/path/app.db" -f schema.sqlList what's saved with red connections (add --json for scripting).
Verbs
| Command | What it does |
|---|---|
red connections [list] [--json] | List saved connections |
red test <conn> | Check a connection can be reached |
red query <conn> [sql] | Run a query, stream rows to stdout |
red exec <conn> [sql] | Run statements / a script (writes, DDL) |
red copy <src> <table> --to <dst> | Copy one table into another |
red migrate <src> --to <dst> | Migrate whole tables into another connection |
red mcp <conn> | Serve RED's read-only tools to an MCP client over stdio |
red reset [--yes] | Remove all RED data: config, cached data, keychain secrets |
-q / --quiet is global. Every verb takes --help.
Querying
query streams the result to stdout in the format you pick - table (default),
csv, tsv, or json:
red query mydb "SELECT id, name FROM users LIMIT 5"
red query mydb --format csv "SELECT * FROM users" > users.csv
red query mydb --format json "SELECT * FROM users" | jq '.[].name'SQL can come from an argument, a file with -f, or piped on stdin:
red query mydb -f report.sql
echo "SELECT now()" | red query mydb -f -Executing statements and scripts
exec runs writes and DDL - the primary way to seed a database. A
multi-statement script is split and run one statement at a time, each in its own
transaction:
red exec staging -f seed.sql
red exec staging "UPDATE feature_flags SET enabled = true"
cat schema.sql | red exec staging -f -Risky and destructive statements are confirmed on the terminal, the same way
they are in the app. Pass --yes to skip the prompt in a script or CI run -
query takes it too. See Safety and guards.
Copying and migrating
The headline for populating dev/staging. Both open a source and a target connection (same engine or across engines) and stream rows through in bounded chunks - no intermediate dump file.
copy moves one table. Use --create to make the target table from the
source's columns if it doesn't exist, --as to rename it, --target-schema to
place it, and --mode to append (default) or replace:
# create staging.users from prod and fill it
red copy prod users --to staging --create
# refresh an existing table (clear, then insert)
red copy prod users --to staging --mode replacemigrate moves many tables at once - create-fresh, foreign-key ordered,
skipping any table that already exists on the target. Without --tables it moves
the whole schema:
# migrate an entire database into staging
red migrate prod --to staging
# just a few tables
red migrate prod --to staging --tables users,orders,line_itemsPreview first with --dry-run
copy --dry-run prints the target, write mode, and the resolved column
mapping; migrate --dry-run prints which tables would be created vs skipped -
neither writes anything.
MCP server
red mcp <connection> is a headless stdio MCP server. Point Claude Code (or
any MCP client) at it and the client gets RED's read-only database tools -
schema, describe, profile, SELECT, explain - grounded in that connection, with
no GUI and no ports:
red mcp prod-readonlyWrites are withheld and a tool-call budget bounds a runaway client, like the
in-app path. It honours your [ai] policy: a connection whose assistant you
disabled serves nothing, and the gate fails closed if the policy can't be read.
See AI assistant.
Removing RED's data
red reset deletes RED's config and cached-data directories and every keychain
secret - connection passwords, SSH secrets, AI keys - in one step. It shows what
will be removed and prompts first; --yes skips the prompt for CI teardown. The
binary itself is left alone.
Scripting conventions
CLI mode is built to compose in pipelines and CI:
- Data goes to stdout, progress and summaries go to stderr - so
red query … | psql …stays clean. -q/--quietsilences progress and success lines (errors still print).- Exit codes let a script branch on the failure class:
| Code | Meaning |
|---|---|
0 | Success |
2 | Usage error (bad args, unknown connection, no SQL) |
3 | Connection failure (auth, unreachable host, untrusted SSH host) |
4 | Runtime failure (a query, exec, copy, or migrate error) |
Run red <command> --help for the full flag list of any verb.