Kalam CLI Command Reference
The Kalam CLI (kalam) is the SQL-first terminal client for KalamDB. It is available as the
native Rust binary and as the npm-distributed wrapper package @kalamdb/cli. This guide documents
the current operational surface: install paths, self-update, doctor diagnostics, login/logout,
instance profiles, live subscriptions, topic consumers, and schema watch automation.
Install and verify
Choose one of these installation options:
Option 1: npm global install
Use this when your machine already manages developer tools through Node/npm. The package downloads the matching native release binary during install.
Option 2: install.sh
Use this when you want a curl-based install path and do not want to involve npm.
Pin an exact release by passing installer flags through sh -s --:
Install the latest GitHub prerelease:
The installer also accepts environment variables, which are often easier in CI:
Supported installer inputs:
| Input | Effect |
|---|---|
--version <version> or KALAM_VERSION | Install an exact release. Leading v is accepted and stripped for artifact lookup. |
--pre-release or KALAM_PRE_RELEASE=1 | Install the latest GitHub prerelease instead of the latest stable release. |
KALAM_INSTALL_DIR | Install into a custom directory. Default is $HOME/.kalam/bin. |
KALAM_NO_MODIFY_PATH=1 | Skip shell profile edits that add the install directory to PATH. |
Option 3: GitHub release binaries
Use prebuilt binaries from releases if you do not want a Rust toolchain:
Option 4: Build from source
After installation, verify your CLI:
kalam version prints the packaged version plus build metadata such as commit, branch, and build
timestamp. kalam doctor gives you a compact status summary by default and a fuller, Flutter-style
detail view when you pass -v.
KalamDB Skills for coding agents
Use KalamDB Skills alongside the CLI so Codex, Claude Code, OpenCode, and Agent Skills-compatible tools can load KalamDB commands, SQL syntax, SDK patterns, and operations guidance:
Release, auth, and instance workflows
Top-level commands are the preferred operational surface for daily CLI management:
What these commands do:
kalam updatedownloads a verified release archive, shows a progress bar while the binary is downloading, verifiesSHA256SUMS, and replaces the installed native binary.kalam doctorchecks the binary path, PATH resolution, config file, stored credentials, healthcheck reachability, and authenticated identity.kalam loginsaves access and refresh tokens for the selected--instanceunless you pass--no-save.kalam whoamicalls/v1/api/auth/mewith the resolved credentials.kalam logoutdeletes saved credentials for one instance or, with--all, every stored instance.kalam token createcreates a service user and prints a fresh access/refresh token pair for automation.
When interactive mode starts, the CLI performs a short update check. If a newer release is
available, it prints a one-time notice and adds an update:<version> segment to the prompt so the
operator can see that the shell is behind the latest release.
Execution modes and precedence
kalam supports four execution modes:
--watch-schema: pollsystem.tablesand run a local command when schema metadata changes.--subscribe/--list-subscriptions: subscription management flow.--consume --topic ...: topic consumer mode.- SQL execution mode:
--file <path>executes file and exits--command <sql>executes one statement and exits- no
--file/--commandstarts interactive shell
Important behavior:
--watch-schemais a standalone mode and requires--run.--consumetakes precedence over--fileand--command.--fileand--commandtogether are invalid.
Connection and authentication options
| Option | Description |
|---|---|
-u, --url <URL> | Full server URL or bare host. Bare loopback inputs default to http://; other bare hosts default to https://. |
-H, --host <HOST> | Host-only alternative to --url; combines with --port. |
-p, --port <PORT> | Port used with --host (default 3000). |
--token <JWT> | JWT auth token. |
--user <USER> | User/password login identifier. |
--password [PASS] | Basic auth password. If passed with no value in interactive mode, CLI prompts. |
--instance <NAME> | Credential profile name (default local). |
URL defaults and resolution:
- If
--urlis set, that value is normalized and used. Bare hosts are accepted. - If
--hostis set, URL becomeshttp://<host>:<port>. - Otherwise CLI uses stored credentials URL for the selected
--instancewhen present. - Final fallback is
http://localhost:2900. - Bare
--urlinputs likelocalhost:2900,127.0.0.1:2900, and[::1]:2900default tohttp://...; other bare hosts likekalam.masky.appdefault tohttps://.... --urlrejects embedded credentials, query parameters, and fragments.
For production-style workflows, use named instances so one CLI install can keep separate URLs and
credentials for dev, staging, and prod.
Example:
OIDC login modes
KalamDB now exposes one configured external OIDC provider. The CLI supports three ways to use it:
Browser login with PKCE
This opens the provider login page in your browser, listens for the local callback on http://127.0.0.1:8787/callback, and exchanges the authorization code through KalamDB.
Direct device login
Use this when the provider exposes a device authorization endpoint and you do not want a local browser callback.
Brokered device login
Use brokered mode when the CLI host can reach KalamDB but cannot reach the OIDC provider directly.
Operational notes:
--brokeredrequires--no-browserkalam login --no-save ...skips writing credentials to disk- when
kalam loginsucceeds in an interactive terminal, the CLI drops straight into the SQL shell - when stdin or stdout is non-interactive,
kalam loginkeeps one-shot behavior and exits after saving credentials
Query execution and output options
| Option | Description |
|---|---|
-c, --command <SQL> | Execute a single SQL statement and exit. |
-f, --file <PATH> | Execute SQL from file and exit. |
--format <table|json|csv> | Output format (default table). |
--json | Shorthand for --format json. |
--csv | Shorthand for --format csv. |
--no-color | Disable ANSI colors. |
--no-spinner | Disable spinner animations. |
--loading-threshold-ms <MS> | Spinner threshold in milliseconds. |
Examples:
Running SQL from the CLI
The CLI is SQL-first: if a statement works through /v1/api/sql, you can send
it unchanged through kalam --command, kalam --file, or the interactive
shell.
Common patterns:
Namespace state in interactive mode
Namespace switching is a SQL statement, not a backslash command:
After a successful USE NAMESPACE chat, SET NAMESPACE chat, or USE chat,
the CLI stores chat locally and sends it as namespace_id on later requests.
That means later unqualified table names resolve to chat.<table> until you
switch again. The prompt also shows the active namespace as ns:<name>.
Table footer metadata
When output format is table, query results end with row count and footer metadata:
As:appears when the server reports the effective user for the statement. This includesEXECUTE AS '<user_id>'and the CLI\asshortcut.Took:is the server-reported execution time in milliseconds.
Interactive meta-commands
In interactive mode, type SQL directly or use backslash meta-commands for CLI-managed operations. --command also accepts these meta-commands, so cluster inspection and administration can stay on the CLI surface instead of requiring backend-rendered strings.
Cluster meta-commands
Core cluster commands:
| Command | Description |
|---|---|
\cluster list / \cluster ls | Render node overview from system.cluster and system.cluster_groups. |
\cluster list groups | Render Raft group details. |
\cluster snapshot | Trigger cluster snapshots and print per-group results. |
\cluster purge --upto <index> | Purge Raft logs up to index. |
\cluster trigger-election | Trigger elections across groups. |
\cluster transfer-leader <node_id> | Request leader transfer to a node. |
\cluster rebalance | Rebalance data-group leaders. |
\cluster stepdown | Request leader stepdown across groups. |
\cluster clear | Clear older snapshot files. |
\cluster join <node_id> <rpc_addr> <api_addr> | Add a node at runtime. |
Examples:
How follower writes are forwarded
KalamDB uses Multi-Raft groups, so a client can send a write to any reachable node.
For the full architecture, see /docs/server/architecture/clustering and /docs/server/architecture/table-types.
Example:
Assume the authenticated or effective user is user-42, and that user hashes to DataUserShard(7).
- The request can land on node 2 even if node 2 is only a follower for
DataUserShard(7). - KalamDB prepares and classifies the SQL once, then derives the target Raft group from the table type and current
user_id. - For user and stream tables, the target group is selected by hashing
user_idinto one ofcluster.user_shardsgroups. - If the receiving node is not leader for that target group, it forwards the original SQL, params, auth header, and request id over gRPC to the leader of that group.
- The leader executes the write, appends it to that group’s Raft log, replicates it to followers, commits it, and returns the result.
- The follower returns that leader-built response to the client.
This means the client does not need to discover the right leader first.
Multi-Raft routing today
- KalamDB runs one metadata Raft group plus multiple user data groups.
- User and stream data are routed by
user_id, so all data for one user is coordinated by the same user-data group leader at a given time instead of scattering that user’s active writes across many leaders. - That locality keeps the cluster faster by reducing cross-group coordination and improving write-path locality.
- Shared tables are not meaningfully sharded yet. Today they route to a single shared data group.
- Better shared-table partitioning is a work in progress. The planned direction is partition-by-key so each shared table can define how rows are partitioned and where they belong.
Credential and instance management
The top-level commands (kalam login, logout, whoami, token create) are the preferred
operator surface now. The flags below are still available for compatibility and scripting.
| Option | Description |
|---|---|
--list-instances | List stored credential instances. |
--show-credentials | Show stored credentials for --instance. |
--update-credentials | Login and refresh stored JWT/refresh token for --instance. |
--delete-credentials | Delete credentials for --instance. |
--save-credentials | Save credentials after successful login when using user/password flow. |
Examples:
Live query subscription options
| Option | Description |
|---|---|
--subscribe <SQL> | Run a live query subscription. |
--subscription-timeout <SECONDS> | Idle timeout after initial data (0 means no timeout). |
--initial-data-timeout <SECONDS> | Maximum wait for initial data batch (0 means no timeout). |
--list-subscriptions | Print current subscription model/capabilities. |
The CLI live-query surface is \live <SELECT ...> in interactive mode and --subscribe "<SELECT ...>" in non-interactive mode. Both routes send a SELECT plus an optional trailing OPTIONS (...) clause to the WebSocket subscription path.
Supported CLI subscription options today:
| Clause | Effect |
|---|---|
OPTIONS (batch_size=<n>) | Limits each initial snapshot batch to at most n rows. If more rows match, the CLI keeps requesting the next batch until startup loading completes. |
OPTIONS (last_rows=<n>) | Rewinds the newest n rows as a single startup batch before live changes begin. |
OPTIONS (from=<seq_id>) | Starts live delivery after a known sequence id. from_seq_id is accepted as an alias. |
Options can be combined in one clause, for example OPTIONS (last_rows=20, batch_size=5, from=1234).
Examples:
Interactive examples:
How to verify batching from the CLI output:
- The CLI prints a
BATCH <n>line for each startup snapshot page. - With
OPTIONS (batch_size=5)and 20 matching rows, you should see four startup batches of 5 rows each. - Startup batches are delivered from oldest to newest in normal batch mode.
last_rowsis different: it is a single-batch rewind of the newest rows, not paginated history replay.
Example output:
Topic consumer options (--consume)
Use this mode to consume topic records directly from a terminal.
| Option | Description |
|---|---|
--consume | Enable topic consumer mode. |
--topic <TOPIC> | Topic name (required with --consume). |
--group <GROUP_ID> | Consumer group (offsets committed when set). |
--from <earliest|latest|OFFSET> | Start position. Supports numeric offset. |
--consume-limit <N> | Maximum number of messages before exit. |
--consume-timeout <SECONDS> | Stop after idle runtime window. |
Examples:
Schema watch options (--watch-schema)
Use this mode when your app has a local schema-generation step such as npm run schema:gen and you want the CLI to rerun it after DDL changes.
| Option | Description |
|---|---|
--watch-schema | Start schema watch mode. |
--namespace <NAME> | Limit changes to one or more namespaces. Repeat it to watch multiple namespaces. |
--table <namespace.table> | Limit changes to one or more specific tables. Repeat it to watch multiple tables. |
--run <COMMAND> | Shell command to execute after schema changes are detected. |
--run-on-start | Run the command once immediately before polling. |
--interval <DURATION> | Poll interval. Default 5s; accepts values like 500ms, 2s, or 1m. |
Examples:
Internally the CLI polls system.tables and checks for rows whose updated_at is newer than the last observed watch timestamp. Repeated namespaces are combined with OR, and repeated tables are added as extra OR branches.
Timeout and runtime tuning options
| Option | Description |
|---|---|
--timeout <SECONDS> | HTTP request timeout (default 30). |
--connection-timeout <SECONDS> | Connection/TLS handshake timeout (default 10). |
--receive-timeout <SECONDS> | Receive timeout (default 30). |
--auth-timeout <SECONDS> | WebSocket auth timeout (default 5). |
--fast-timeouts | Preset tuned for local development. |
--relaxed-timeouts | Preset tuned for high-latency networks. |
--config <PATH> | Config file path (default ~/.kalam/config.toml). |
-v, --verbose | Verbose logging. |
Global utility options
| Option | Description |
|---|---|
-h, --help | Print command help. |
-V, --version | Print CLI version, commit, branch, and build timestamp. Equivalent to kalam version. |
Interactive shell commands by category
After launching interactive mode (kalam with no --command/--file), these backslash commands are available.
Core shell and inspection
| Command | Description |
|---|---|
\help, \? | Show help. |
\quit, \q | Exit CLI. |
\info, \session | Show current CLI session, resolved server, health probe status, server version, cluster, and config details. |
\sessions | Show active PostgreSQL gRPC bridge sessions from system.sessions. |
\history, \h | Open command history menu. |
\health | Run unauthenticated public health probes. |
\stats, \metrics | Query system stats metrics. |
Session introspection
Use \session (or \info) to inspect the current CLI process and server connection: resolved URL, user, connectivity, health probe status, server version, API version, build date, cluster mode, config file, local history, and build metadata.
\health uses the same public /health and /v1/api/healthcheck endpoints documented in the HTTP reference. It does not fall back to authenticated SQL. On remote deployments those endpoints may be localhost-only; in that case the CLI reports the restriction, while \session can still show version/build details learned from cluster metadata.
Use \sessions when you want server-side observability for PostgreSQL bridge traffic. It executes:
That view is focused on live pg_kalam gRPC sessions only. To inspect active explicit transactions across both pg_kalam and native /v1/api/sql requests, query:
See /docs/server/sql-reference/system-views for the view columns and query patterns.
Namespace, schema, impersonation, and formatting
| Command | Description |
|---|---|
\dt, \tables | List tables. |
\d <table>, \describe <table> | Describe table columns. Accepts <table> or <namespace.table> and ignores a trailing ;. |
\as <user_id> <SQL> | Run one statement as a convenience wrapper for EXECUTE AS '<user_id>'. |
\format table|json|csv | Change output format for current session. |
\refresh-tables, \refresh | Refresh autocomplete table metadata. |
Example:
\flush is a shortcut for STORAGE FLUSH:
\flushor\flush allrunsSTORAGE FLUSH ALLusing the current namespace context.\flush table messagesrunsSTORAGE FLUSH TABLE chat.messageswhen the current namespace ischat.\flush table billing.invoicespreserves the explicit namespace you typed.
The CLI rewrites that shortcut to the canonical SQL wrapper:
See /docs/server/sql-reference/impersonation for the delegation rules and role matrix.
Table transfer commands
| Command | Description |
|---|---|
\export <namespace.table> [--user-id <id>] [--output <file.zip>] | Start table export, wait for completion, then download ZIP to local path. |
\import <namespace.table> <file.zip> [--user-id <id>] | Upload ZIP and import into the target table in the selected namespace. |
Notes:
\exportand\importrun asynchronous server jobs and poll until they reach a terminal state.- The CLI shows progress while uploading import ZIP files and downloading exported ZIP files.
- Table type is inferred by the backend from table metadata; do not pass a type flag.
- For user tables,
--user-idis required. If omitted, the backend returns a validation error. <namespace.table>is required for both commands; unqualified table names are rejected.
Examples:
Credentials in interactive mode
| Command | Description |
|---|---|
\show-credentials, \credentials | Show stored credentials for current instance. |
\update-credentials <user> <pass> | Update credentials for current instance. |
\delete-credentials | Delete credentials for current instance. |
Live query commands
| Command | Description |
|---|---|
\live <SQL>, \subscribe <SQL> | Start live query subscription (\subscribe is an alias). |
Topic consumer command (interactive)
| Command | Description |
|---|---|
\consume <topic> [--group NAME] [--from earliest|latest|OFFSET] [--limit N] [--timeout SECONDS] | Consume topic messages directly from interactive shell. |
Example:
Cluster and ingest control commands
The \cluster meta-command renders cluster operations directly from the CLI surface.
| Command | Description |
|---|---|
\flush [all|table <table>] | Run STORAGE FLUSH using the current namespace context. |
\cluster snapshot | Trigger cluster snapshot. |
\cluster purge --upto <index> or \cluster purge <index> | Purge cluster logs up to index. |
\cluster trigger-election or \cluster trigger election | Trigger election. |
\cluster transfer-leader <node_id> or \cluster transfer leader <node_id> | Request leadership transfer to node id; some builds may report it unsupported at runtime. |
\cluster rebalance | Rebalance leaders across data groups. |
\cluster stepdown or \cluster step-down | Step down current leader. |
\cluster clear | Clear older snapshot files while keeping recent ones. |
\cluster list or \cluster ls | Show cluster nodes (system.cluster). |
\cluster list groups | Show cluster groups (system.cluster_groups). |
\cluster join <node_id> <rpc_addr> <api_addr> | Add a node at runtime. |
SQL workflows the CLI should cover
The backslash commands are only part of the surface. Many important CLI
workflows are plain SQL entered through -c, -f, or the interactive shell.
Impersonation
You can use either the \as shortcut or the raw SQL form:
Backup and user export
Run backup and export workflows as normal SQL:
Live queries
The CLI live-query commands take a normal SELECT and run it over the live
subscription channel:
There is no separate live-query SQL keyword to learn for the CLI path; use the
same SELECT you would run normally.
Export user data
SHOW EXPORT returns job rows with a download_url URI path such as
/v1/exports/<user_id>/<export_id>. Prefix that path with the same server base
URL you used for the CLI when downloading the finished ZIP.
Backup and restore
Backup and restore paths are resolved on the server filesystem, not on the machine running the CLI.
- If
BACKUP DATABASE TOends with.tar.gzor.tgz, KalamDB writes a single archive file. - If it does not, KalamDB writes the backup directory layout under that path.
RESTORE DATABASE FROMaccepts either the directory layout or a.tar.gz/.tgzarchive.- Backup and restore require a DBA or System role.
- There is no separate backup download endpoint today; the
TO '<path>'value is the server-side artifact location. - To track the status of the backup you can query the jobs table: select * from system.jobs where job_id = ‘backupjob’;
Topic pub/sub SQL
Use SQL for topic definition, CDC wiring, and explicit offset control:
The --consume flag and \consume command are convenience shells around topic
consumption. Use raw CONSUME FROM and ACK when you want explicit SQL-based
control or when you are scripting the workflow.