Today we're releasing the new Cube CLI in preview: a single native binary, cube, that puts Cube's public REST API in the terminal. This post covers why we built a CLI in 2026, what it does, and a demo where one Claude Code prompt goes from a Postgres database to a deployed data model and a working React dashboard.
Inception
In the beginning there was the command line. Neal Stephenson used that as the title of his 1999 essay, but it's also just literally true. Before pixels there were characters: teletypes connected to time-sharing systems in the 1960s, then video terminals, then the Unix shell in the early 1970s with its one big idea that programs should read text, write text, and compose through pipes. Every interface paradigm since (windows, touch, voice) was supposed to replace it. None did. Half a century later, every serious piece of infrastructure still ships a CLI, and the ones that don't get one written by their users.
When AI agents started doing real work, the terminal is the interface they learned first, and that's not an accident. An LLM is a text model. A terminal session is text: the command is text, the output is text, the error message is text. There's no vision model in the loop, no pixel coordinates, no guessing which of three similarly-named buttons to click. The training corpus is saturated with shell transcripts, man pages, CI logs, and README installation sections, so models arrive already fluent. It's the same reason agents are good at SQL: they've read millions of examples of it.
The CLI also happens to be a nearly ideal tool-use protocol. Commands are self-describing (--help is documentation the agent can read at run time), output can be requested as JSON, exit codes make success and failure unambiguous, and everything composes. When a command fails, the error comes back as text in the same channel, and the agent can read it and correct course on the next attempt. That tight feedback loop is exactly what agentic coding tools are built around, and it's why they live in the terminal rather than driving a browser.
So the interface that predates the GUI by two decades is also the native interface of the newest kind of user, and we don't expect that to change. Agent harnesses are terminal programs, CI runners execute shell scripts, and any capability we want agents to use reliably has to be exposed as text first. That's the assumption the new Cube CLI is built on.
Enter the new Cube CLI
The new CLI is written in Rust and ships as one static binary per platform (TLS via rustls, so no OpenSSL dependency, and the Linux builds are fully static musl binaries). It lives in the open-source Cube repository under rust/cube-cli, and you can watch it come together in the recent commits: the initial CLI covering the public API landed in #11289, followed by GitHub import, upload deploys, and self-update in #11291.
Installation is one line on Linux and macOS:
And one line on Windows (PowerShell):
Authentication uses the OAuth 2.0 device flow (RFC 8628): cube login prints a URL and a short code, opens your browser, and waits for approval. Tokens auto-refresh, multiple tenants are supported as named contexts, and for CI you skip the browser entirely and pass an API key via CUBE_API_KEY.
The important design decision is that the CLI is a thin, complete client of Cube's public REST API. It doesn't scrape internal endpoints and it doesn't have private capabilities. Every endpoint of the public API is covered:
| Group | What it controls |
|---|---|
deployments, regions, logs | Create, list, and manage deployments, generate API tokens, check build status, tail pod logs |
deploy | Upload a local project directory: hash files, diff against the server, upload only what changed, trigger one build |
data-model | Files, branches, dev mode, commits |
github | Link a GitHub repo to a deployment and trigger builds from it |
variables, environments | Environment variables and environment tokens |
workbooks, reports, folders, workspace, notifications | The analytics surface: workbooks, reports, folder structure, notifications |
users, groups, attributes, policies, tenant, scim, oidc | Access control, user attributes, resource policies, SCIM provisioning, SSO configuration |
embed, integrations, agents, app, meta | Embed sessions and tenants, OAuth integrations, agents, app config, the metadata API |
The conventions are chosen for both kinds of users. Humans get tables, colors, and shell completions. Agents get --json on every list command, request bodies from a file or stdin with -d @file.json, deterministic exit codes, and --help text on every subcommand that doubles as the agent's documentation. cube deploy reimplements the legacy cubejs deploy flow on top of the public API: it hashes local files, diffs against the server, uploads only the changed ones inside a transaction, and triggers a single build. cube deployments build-status then reports the build state, including compile errors as text an agent can act on.
The React e-commerce demo
To show what this unlocks, we gave Claude Code a Postgres database with a standard e-commerce schema (orders, line items, products, users) and this single prompt:
The agent worked through it the way an engineer would. It ran the install script, ran cube login, and paused while I approved the device code in the browser. The pause is deliberate: the agent never sees a password, and the credential it ends up with is a refreshable token stored in a local config file rather than something pasted into a prompt.
From there it was autonomous. It created a deployment, set the database connection through environment variables, read the Postgres schema, and wrote YAML cube definitions with joins between orders, line items, products, and users, and defined the measures the dashboard needed (revenue as a sum over line item totals, order counts, new user counts by month). It uploaded them with cube deploy and polled build-status until the build passed. When a build fails, build-status returns the compile error as text in the same output, so the agent reads it, fixes the model, and deploys again without a human copying error messages between windows. Then it generated an API token and scaffolded a React app with @cubejs-client/react, wiring its charts to the deployed data model.
The whole run took a few minutes, and my total contribution was one prompt and one browser click. None of the individual steps is novel. What's new is that every step is now reachable through one consistent, documented, text-based interface, so an agent can chain them without a human relaying state between a terminal and a browser tab.
What's next
The Cube CLI is in preview. The direction is straightforward: everything you can control in the Cube UI is getting a public API first, and then a CLI command on top of it. The CLI and the API move together because the CLI is built on nothing but the public contract, which keeps us honest about what the API can actually do.
After an incubation period, we're going to release the full set of public APIs as a stable, documented surface for automation, so the same operations are available to CI pipelines, Terraform-style tooling, and whatever agents you run, with the CLI as the reference client.
To try it, run the install script above, then cube login and cube --help. The full command reference is in the CLI documentation, the source is in the Cube repository, and we'd like to hear what you automate with it in the community Slack.
