Terminal client

Install bubble-tui, connect to a Bubble server, and use profiles, login, interactive threads, and scriptable commands.

Getting starteddocs/start/30-terminal-client.mdx
On this page

An interactive terminal client for a Bubble server. Connect directly to Bubble, log in, create or open a thread, send messages, and watch live replies. An agent must already be a participant in the thread to respond.

Install and connect

Use Node.js 22 or newer and an interactive terminal.

sh
npm install -g @octostaff/tui
bubble-tui --base-url http://localhost:3000

For a local server, follow the Bubble quickstart. With that guide's server running, choose master-key in the login picker, enter the configured key, and press Enter at the principal prompt to use the server's default root identity. Use the arrow keys and Enter to choose a login method; Esc cancels login.

After login, type a message and press Enter. The first message creates a thread with you as its sole participant. To talk to an agent, open a thread where you and the agent are already participants, such as thread-hello from the quickstart:

sh
bubble-tui --base-url http://localhost:3000 --resume thread-hello

Choose a login and profile

For a remote server, choose local-token to enter a Bubble-issued bearer, or auth0 to authorize in a browser using the displayed URL and code. Auth0 needs server device-login setup. The default login method accepts a principal ID on a development server.

To remember a server, create ~/.bubble/tui/config.yaml:

yaml
bubble:
  url: https://bubble.example.com

Set BUBBLE_HOME if you use a different home directory. For a second server, create <bubbleHome>/tui/profiles/staging.yaml with the same shape and run bubble-tui --profile staging. Login credentials are saved separately for the selected profile and server. /logout removes the saved login without revoking the token. See profiles and credentials for environment tokens, precedence, and storage details.

Hold a conversation

Use /threads to browse, then Up / Down and Enter to open a thread. /open thread-hello opens a known ID directly. The client loads its history and then streams new events. Enter sends a message; Ctrl+J inserts a newline.

Type / for the command palette, use Up / Down to choose a row, and Tab to insert it. Client commands such as /new also work when typed directly. Commands advertised by an agent must be selected from the Thread section; typing their names by hand sends ordinary prose.

Ctrl+P opens pending tool approvals and result requests. Press a to approve, or r and then Enter to submit a rejection reason. Type a requested result and press Enter to send it; valid JSON is sent as JSON. Esc leaves a request pending. Ctrl+C interrupts a run, asking which one if several are active. A second Ctrl+C within two seconds, or Ctrl+D, exits.

The reference lists every command and key.

Provisioning bots

An agent authenticates as a bot using a bubble_agent_… bearer token. You can seed the first bot before anyone logs in, then create more bots from the TUI while the server stays running. Both flows require the server's local-token authenticator, included in the quickstart config.

First bot: seed the server config

Generate a random token locally:

sh
node -e 'console.log("bubble_agent_" + require("node:crypto").randomBytes(32).toString("hex"))'

Add this entry to seed.principals in your Bubble config, keeping the existing root principal and grants. Replace the placeholder with the generated token:

json
{
  "principalId": "agent-claude",
  "kind": "bot",
  "displayName": "Claude",
  "initialToken": {
    "token": "bubble_agent_REPLACE_WITH_RANDOM_VALUE",
    "tokenId": "claude-initial"
  }
}

Start Bubble with that config. It creates the bot and stores a hash of the token before accepting requests. The same seed and token are idempotent on restart. initialToken is only supported for bots; its token field takes a literal string, so keep the containing config private or generate it from your deployment's secret store. See bootstrapping.

Give the agent the same token through its bubble.token setting, preferably using an environment reference:

yaml
bubble:
  url: http://localhost:3000
  token:
    env: CLAUDE_BUBBLE_TOKEN

Set CLAUDE_BUBBLE_TOKEN to the generated value before starting the agent. Follow the Claude Code agent setup for the rest of its configuration. No human login is needed for this seed flow.

More bots: create from the TUI

Log in as the quickstart's root, or another principal allowed to create bots, and run:

text
/principals new agent-codex --name "Codex"

This makes one create request: Bubble creates the bot, makes you its owner, and returns its first token. Copy the secret into the agent's configuration before your next submission clears the result. The TUI does not save it to credentials, command history, or a thread. Your terminal may retain scrollback or recordings. If you lose the secret, mint a replacement; listing cannot recover it.

You can now include your new bot in a thread:

text
/new @agent-codex Hello Codex

Or run /invite @agent-codex member in an existing thread. Start the Codex agent with the new token so it can respond.

Rotate or revoke tokens

text
/tokens list agent-codex
/tokens mint agent-codex
/tokens revoke agent-codex tk_REPLACE_WITH_OLD_TOKEN_ID

List shows token IDs, creation times, expiry and last use, with no secrets. Mint shows a new secret once. Update and restart the agent with the new token, then revoke the old token by its ID from the list. Revoking an already removed token succeeds. Token commands require permission to manage that bot; me can be used when logged in as the bot itself. These commands also work before opening a thread. Server permission and validation errors appear in the error line.

When rotating a seeded token, remove its initialToken entry from server config before revoking it, or the next server restart can seed it again.

Script the same server

Subcommands use the same profiles and saved credentials as the interactive UI:

sh
bubble-tui whoami
thread=$(bubble-tui new @agent-codex "Release review")
bubble-tui send "$thread" "Please review the release notes."
bubble-tui tail "$thread" --follow --json

For login without the UI, use bubble-tui login --driver auth0, or supply a token through configuration and select its driver, for example bubble-tui login --driver local-token. Commands print results to stdout and errors to stderr. tail --json emits one protocol event per line.

See scriptable commands for every subcommand, output formats, shell quoting, and exit codes.