ribo CLI Reference
ribo is the command-line tool for tissue.systems. The name comes from the ribosome — the molecular machine inside every living cell that reads genetic instructions and assembles proteins from them. In the same way, ribo reads your ribo.toml and assembles a running Cell from your code.
Complete reference for every ribo command.
ribo login
Authenticate with tissue.systems. Opens a browser for the OAuth flow, then stores a token locally.
ribo login
Token is saved at ~/.config/ribo/token.json — the same path on every platform (macOS included; there is no Library/Application Support variant).
Flags
| Flag | Description |
|---|---|
--auth-server <url> |
Auth server URL (default: https://auth.tissue.systems) |
--key <token> |
Skip the browser — save a pre-issued API key directly |
# Standard browser login
ribo login
# Save a key directly (CI, scripts)
ribo login --key eyJhbGciOiJIUzI1NiJ9...
# Authenticate against a different auth server (e.g. staging)
ribo login --auth-server https://auth.staging.tissue.systems
ribo logout
Remove a stored token.
ribo logout [--server <url>]
Flags
| Flag | Description |
|---|---|
--server <url> |
Log out from this server only. Omit to remove credentials for all servers. |
ribo logout # forget all stored tokens
ribo logout --server https://api.tissue.systems # forget one server's token
RIBO_TOKEN
Set the RIBO_TOKEN environment variable to authenticate without a stored token file. Any command that requires auth reads RIBO_TOKEN first and skips the disk lookup entirely.
export RIBO_TOKEN=tok_a1b2c3...
ribo deploy
ribo list
ribo db exec myapp "SELECT * FROM users"
RIBO_TOKEN is the standard way to authenticate in CI/CD pipelines, automated scripts, and containerised environments where running ribo login interactively is not possible.
Obtaining a token
Create a scoped API token with ribo token create:
ribo token create "github-actions" --scope cells:write --scope cells:read
# → tok_a1b2c3d4e5f6...
Store the token as a secret in your CI environment (RIBO_TOKEN). It never expires unless you revoke it with ribo token revoke.
Precedence
RIBO_TOKEN outranks every other credential source. The full order is:
RIBO_TOKEN— process-scoped--profile <name>— one command- the nearest bound ancestor directory — see
ribo profile - the default profile —
ribo login
Because it is an environment variable, RIBO_TOKEN is already isolated per process: parallel CI jobs on one runner cannot clobber each other's credentials.
Example: GitHub Actions
- name: Deploy Cell
env:
RIBO_TOKEN: ${{ secrets.RIBO_TOKEN }}
run: ribo deploy
ribo deploy
Deploy a Cell from a ribo.toml configuration file. If a build command is defined, it runs first.
ribo deploy [--config <path>] [--server <url>]
Flags
| Flag | Default | Description |
|---|---|---|
--config <path> |
./ribo.toml |
Path to the config file |
--server <url> |
TISSUE_SERVER, else [server] url from ribo.toml, else https://api.tissue.systems |
Management API URL |
Output
account Acme Corp (acct_3f8c1a2b4d6e8f00) [pinned]
server https://api.tissue.systems
deployed my-cell
address 33ed412f7x2kp
kind js
url https://my-cell.strand-9c.tissue.dev
local http://localhost:8080/33ed412f7x2kp
c3 DB→my-database
text GREETING
vault JWT_SECRET
g7 STORE→raw-uploads
files ASSETS→33ed412f-assets (18 files)
pulse 0 * * * *
account— the account the deploy targets, and whether the project is[pinned]or[unpinned]to it (seeribo account pin)server— the management API the deploy was sent tourl— the Cell's permanent public URLlocal— the path-based URL the Cell would have on a local runtimeaddress— stable ID assigned on first deploy; never changes between redeploysc3— c3 bindings (binding name → database name)text/vault— text and vault binding names (each line only shown if declared)g7— g7 bindings (binding name → bucket name)files— FILES bindings (binding name → bucket name, file count)pulse— comma-separated cron schedules (only shown if[[pulse]]is declared)
Examples
ribo deploy
ribo deploy --config ./prod/ribo.toml
ribo deploy --server http://localhost:8082
ribo list
List all your deployed Cells.
ribo list [--server <url>]
ADDRESS NAME URL
33ed412f7x2kp my-cell https://my-cell.strand-9c.tissue.dev
33ed412fq81mz another-cell https://another-cell.strand-9c.tissue.dev
Columns: address, name, public URL. If you have no Cells, prints No cells deployed.
ribo delete
Remove a deployed Cell permanently. The URL stops working immediately.
ribo delete <name-or-address> [--server <url>]
ribo delete my-cell
ribo delete ab1cd2
ribo invoke
Call a named function exported by a deployed Cell and print the response. The Cell is resolved by name (or address) and the request is sent as an HTTP POST.
ribo invoke <name-or-address> <function> [--args '<json-array>'] [--server <url>]
Arguments
| Argument | Description |
|---|---|
<name-or-address> |
The Cell to invoke, by name or address |
<function> |
The exported function name to call |
Flags
| Flag | Default | Description |
|---|---|---|
--args <json> |
none | A JSON array of arguments to pass to the function |
--server <url> |
http://localhost:8080 |
Runtime URL to send the invocation to |
The response body is pretty-printed when it is valid JSON, otherwise printed as-is. A non-2xx status causes ribo to exit non-zero.
# Call with no arguments
ribo invoke my-cell ping
# Pass a JSON array of arguments
ribo invoke my-cell add --args '[2, 3]'
# → 5
# JSON responses come back pretty-printed, one element per line
ribo invoke spellcheck suggest --args '["wrold"]'
# → [
# "world"
# ]
ribo addr
Look up the address of a deployed Cell by name.
ribo addr <name>
ribo addr my-cell
# → dd0d1cd5kq5bs
Returns the address only if the Cell has already been deployed. Useful for scripting or verifying which address a name maps to.
ribo db
Manage c3 SQLite databases. See c3 Overview for usage in Cells.
For ribo db — and the other grouped commands (bucket, vault, token, sensor, domain, account) — --server is a global flag on the group and works in either position: ribo db --server <url> list and ribo db list --server <url> both parse. The synopses below show it before the subcommand, but placing it after works just as well.
ribo db create
ribo db [--server <url>] create <name>
Create a new database. Names must be lowercase alphanumeric with hyphens.
ribo db create myapp
ribo db create analytics
ribo db list
ribo db [--server <url>] list
List all your databases.
myapp
analytics
ribo db drop
ribo db [--server <url>] drop <name>
Delete a database and all its data. Irreversible.
ribo db exec
ribo db [--server <url>] exec <name> ["<sql>"] [--file <path>]
Run a SQL statement or load a .sql file. Output is pretty-printed JSON for inline queries. Use --file for multi-statement migrations — it uses execute_batch internally, so it handles any number of statements efficiently in a single request.
Flags
| Flag | Description |
|---|---|
--file <path>, -f <path> |
Path to a .sql file. Executes all statements in the file. Use this for schema migrations and bulk data loads. |
ribo db exec myapp "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, email TEXT UNIQUE)"
ribo db exec myapp "INSERT INTO users (email) VALUES ('hello@example.com')"
ribo db exec myapp "SELECT * FROM users"
# → [
# {
# "id": 1,
# "email": "hello@example.com"
# }
# ]
ribo db exec myapp "SELECT COUNT(*) as total FROM users"
ribo db exec myapp "PRAGMA table_info(users)"
# Load a schema or seed file (any number of statements)
ribo db exec myapp --file schema.sql
ribo db exec myapp --file ./migrations/001_init.sql
ribo bucket
Manage g7 object storage buckets. See g7 Overview and Managing Buckets for details.
ribo bucket create
ribo bucket [--server <url>] create <name> [--public]
Create a new bucket. Names must be lowercase alphanumeric with hyphens. Creating a bucket that already exists is an error. The name g7-token is reserved and cannot be used.
Flags
| Flag | Description |
|---|---|
--public |
Allow anonymous (unauthenticated) GET/HEAD on objects in this bucket. Off by default — buckets are private. |
ribo bucket create avatars
ribo bucket create raw-uploads
ribo bucket create public-assets --public # objects are world-readable
ribo bucket list
ribo bucket [--server <url>] list
List all your buckets.
avatars
raw-uploads
processed-images
ribo bucket ls
ribo bucket [--server <url>] ls <name>
List the objects (files) stored in a bucket.
ribo bucket ls my-files
42318 images/avatar.png
198432 images/banner.jpg
81920 reports/2026-05.pdf
Columns: size in bytes (right-aligned), key. An empty bucket prints (empty).
ribo bucket cp
ribo bucket [--server <url>] cp <src> <dst> [-r|--recursive]
Copy files between your machine and a bucket — no S3 client or credentials needed. One of <src>/<dst> is a local path; the other is a bucket:key reference. The direction (upload vs download) is inferred from which side carries the bucket: prefix.
When the destination key is empty or ends with /, the source file name is appended. Pass -r to copy a whole directory tree (uploads) or every object under a key prefix (downloads).
# upload a single file
ribo bucket cp ./photo.jpg my-files:photos/photo.jpg
ribo bucket cp ./photo.jpg my-files:photos/ # key becomes photos/photo.jpg
# download a single object
ribo bucket cp my-files:photos/photo.jpg ./photo.jpg
ribo bucket cp my-files:photos/photo.jpg ./out/ # writes ./out/photo.jpg
# recursive (directory ⇄ key prefix)
ribo bucket cp -r ./dist my-files:site/ # upload a tree
ribo bucket cp -r my-files:site/ ./restore # download a tree
Each object must fit in a single request — the per-object ceiling is 100 MiB (see Limitations).
ribo bucket sync
ribo bucket [--server <url>] sync <src> <dst> [--delete] [--dry-run]
One-way sync between a local directory and a bucket prefix. As with cp, the direction is inferred from which side is the bucket: reference. A file is transferred only when it is missing at the destination, when sizes differ, or when sizes match but the content differs (local MD5 compared against the object's etag) — unchanged files are skipped.
| Flag | Effect |
|---|---|
--delete |
Remove destination files/objects that no longer exist at the source |
--dry-run |
Print the planned uploads, downloads, and deletions without making any changes |
ribo bucket sync ./dist my-files:site/ # push a build, skip unchanged files
ribo bucket sync ./dist my-files:site/ --delete # mirror exactly (prune removed files)
ribo bucket sync my-files:backups/ ./restore # pull a tree down
ribo bucket sync ./dist my-files:site/ --dry-run # preview only
ribo bucket rm
ribo bucket [--server <url>] rm <bucket>:<key> [-r|--recursive]
Delete a single object. With -r, delete every object under the given key prefix. To delete a bucket itself (and all its contents), use ribo bucket drop instead.
ribo bucket rm my-files:photos/photo.jpg # one object
ribo bucket rm -r my-files:photos/ # everything under photos/
ribo bucket drop
ribo bucket [--server <url>] drop <name>
Delete a bucket and all its objects. Irreversible.
ribo bucket drop old-uploads
ribo bucket set
ribo bucket [--server <url>] set <name> (--public | --private)
Change an existing bucket's public-read setting. Exactly one of --public or --private is required.
| Flag | Description |
|---|---|
--public |
Allow anonymous GET/HEAD on objects in the bucket |
--private |
Disallow anonymous access (the default for new buckets) |
ribo bucket set avatars --public # make existing objects world-readable
ribo bucket set avatars --private # lock it back down
ribo bucket token
Manage the g7 API bearer token for your account. This token authenticates direct calls to the g7 object storage HTTP API (Cells using a g7 binding don't need it — they go through a service binding). The token is shown in full only once, at creation or rotation.
ribo bucket token create # mint a token (if none exists)
ribo bucket token rotate # replace the token, invalidating the old one
ribo bucket token show # show token metadata (prefix, created/rotated dates) — never the token itself
ribo bucket token revoke # delete the token
ribo bucket token create
# ✓ Created token: g7_live_a1b2c3...
# This is the only time the full token is shown — store it securely.
# Prefix for future reference: g7_live_a1b2
ribo bucket token show
# Prefix: g7_live_a1b2
# Created: 2026-05-25T12:00:00Z
ribo vault
Manage a Cell's vault — encrypted secrets stored server-side and injected into the Cell at dispatch time. Use the vault for API keys, signing secrets, database credentials, and any value too sensitive to put in ribo.toml (where it would be committed to source control).
A vault entry is consumed by a type = "vault" binding in ribo.toml. The binding declares only the key name; the value is set separately with ribo vault set and never appears in your config or in command output once stored:
[[bindings]]
type = "vault"
binding = "JWT_SECRET" # env.JWT_SECRET at runtime
See ribo.toml Reference → vault for the binding side, and the Vault Security Model for how stored values are protected (encryption at rest, dispatch-time injection, auditing, rotation).
Set vault values before deploying. A
vaultbinding must have its value set withribo vault setbefore you runribo deploy. If the value is missing at deploy time, the binding is stored as a placeholder and the Cell receives that placeholder string instead of the real secret — a silent failure (e.g. JWT verification that never succeeds). The<cell>argument is the cell name as written in[cell] nameinribo.toml.
ribo vault set
ribo vault [--server <url>] set <cell> <key> [--env <VAR>]
Set (or overwrite) a vault value. By default ribo prompts for the value with hidden input, so the secret never appears on screen or in your shell history. Alternatively, read it from an environment variable with --env, or pipe it on stdin.
Flags
| Flag | Description |
|---|---|
--env <VAR> |
Read the value from environment variable VAR instead of prompting |
# Interactive — prompts for hidden input
ribo vault set my-cell JWT_SECRET
# Value for JWT_SECRET: ********
# ✓ Set vault value JWT_SECRET for my-cell
# Non-interactive — read from an env var (CI / scripts)
export JWT_SECRET="s3cr3t-signing-key"
ribo vault set my-cell JWT_SECRET --env JWT_SECRET
# Pipe a value on stdin
echo -n "s3cr3t-signing-key" | ribo vault set my-cell JWT_SECRET
ribo vault list
ribo vault [--server <url>] list <cell>
List the vault key names set for a Cell. Values are never shown — there is no command that reveals a stored secret.
ribo vault list my-cell
# JWT_SECRET
# STRIPE_API_KEY
# DATABASE_URL
If no entries exist, prints No vault entries.
ribo vault delete
ribo vault [--server <url>] delete <cell> <key>
Remove a single vault entry. The next deploy of the Cell will no longer inject that binding.
ribo vault delete my-cell STRIPE_API_KEY
# ✓ Deleted vault value STRIPE_API_KEY for my-cell
ribo token
Manage API tokens (tok_ credentials) for the /v1 management API. API tokens are the recommended way to authenticate scripts, CI/CD pipelines, and MCP integrations — they carry an explicit list of scopes and can be revoked individually without affecting your interactive ribo login session. Set a token as RIBO_TOKEN to use it.
ribo token create
ribo token [--server <url>] create <name> [--scope <SCOPE>]...
Create a new API token. The full token value is printed once at creation — store it securely, it cannot be retrieved again.
Arguments
| Argument | Description |
|---|---|
<name> |
A descriptive name for the token (e.g. "CI pipeline") |
Flags
| Flag | Description |
|---|---|
--scope <SCOPE> |
A scope to grant. Repeat the flag to grant multiple scopes. A token with no scopes can do nothing. |
Scopes follow a resource:action form. The available scopes are:
| Resource | Actions |
|---|---|
cells |
read, write, delete |
databases |
read, write, delete |
buckets |
read, write, delete |
vault |
read, write |
domains |
read, write, delete |
account |
read, write |
ribo token create "github-actions" --scope cells:write --scope cells:read
# ✓ Created token: github-actions
# id: tok_a1b2c3
# scopes: cells:write, cells:read
# token: tok_a1b2c3d4e5f6...
# This is the only time the full token is shown — store it securely.
ribo token list
ribo token [--server <url>] list
List your API tokens with their ID, name, scopes, creation time, and last-used time. The token values themselves are never shown.
ribo token list
# tok_a1b2c3
# name: github-actions
# scopes: cells:write, cells:read
# created: 2026-05-25T12:00:00Z
# used: 2026-05-26T08:14:00Z
ribo token revoke
ribo token [--server <url>] revoke <id>
Revoke a token by its ID (the tok_... value shown in ribo token list). The token stops working immediately.
ribo token revoke tok_a1b2c3
# ✓ Revoked token tok_a1b2c3
Who may revoke what. A token can always revoke itself, whatever its scopes — so a script that thinks it has been compromised can retire its own credential with nothing granted in advance. Revoking a different token is account management and requires account:write; without it the request is refused with 403. This means a narrowly-scoped token that leaks (a cells:read CI token, say) cannot lock you out of your own account by revoking everything else.
Your interactive ribo login session holds every scope, so ribo token revoke <any-id> works normally from your own terminal.
ribo sensor
Manage IoT/sensor devices registered under a Cell. A device is an external client (a microcontroller, gateway, or script) that publishes telemetry over MQTT, which the platform ingests and routes to your Cell. Each device gets its own credentials and can be revoked independently. See Managing Devices for the full device lifecycle, including enable/disable and token rotation (available via the REST API).
ribo sensor add
ribo sensor [--server <url>] add <cell>
Register a new device under a Cell. Prints the device_id, the MQTT password token, and the topic prefix. The token is shown once — save it immediately.
ribo sensor add my-cell
# ✓ Registered device for my-cell
#
# device_id dev_a1b2c3
# token <secret>
# topic tissue/<account_id>/dev_a1b2c3/<metric>
#
# Save the token now — it is not shown again.
# Connect over MQTT/TLS: username=dev_a1b2c3 password=<token>
ribo sensor list
ribo sensor [--server <url>] list <cell>
List the devices registered to a Cell, with their auth type and enabled status.
ribo sensor list my-cell
# DEVICE AUTH ENABLED
# dev_a1b2c3 token true
ribo sensor delete
ribo sensor [--server <url>] delete <cell> <device-id>
Revoke a device. Its credentials stop working immediately.
ribo sensor delete my-cell dev_a1b2c3
# ✓ Deleted device dev_a1b2c3
ribo domain
Manage custom domains for a Cell — serve a Cell from your own hostname (app.example.com or a bare apex like example.com) in addition to its *.tissue.dev address. See Custom Domains for the full walkthrough, including the DNS records each step needs.
A domain is globally unique — it can be attached to only one account at a time. Connecting one is a three-step flow: register, prove ownership with a TXT record, then point DNS at the Cell. TLS is provisioned automatically once DNS resolves.
ribo domain add
ribo domain [--server <url>] add <domain> [--cell <name>] [--config <path>]
Register a domain on a Cell. The Cell is taken from [cell] name in ribo.toml (--config points at a different config file, default ribo.toml), or pass --cell to target another Cell. Prints the TXT ownership challenge and the CNAME target to point at.
ribo domain add app.example.com
# ✓ Registered app.example.com for cell my-api
# status: pending
#
# Add these DNS records at your provider:
#
# 1. Ownership (TXT)
# name _tissue-challenge.app.example.com
# value 3f8c1a...e2d9
#
# 2. Routing (CNAME — or ALIAS/ANAME for an apex)
# name app.example.com
# target my-api.strand-9c.tissue.dev
#
# Then run: ribo domain verify app.example.com
ribo domain list
ribo domain [--server <url>] list
List the custom domains registered to your account, with their status and the Cell each is attached to. The CELL column shows the Cell's address, not its name.
ribo domain list
# DOMAIN STATUS CELL
# app.example.com active 33ed412f7x2kp
# example.com verified 33ed412f7x2kp
Status is one of pending → verified → active, or failed if ownership is lost.
ribo domain verify
ribo domain [--server <url>] verify <domain>
Re-check a domain's DNS and advance its status — from pending to verified once the TXT challenge is seen, and to active once DNS points at the Cell and TLS is provisioned. Run it after adding each DNS record; DNS changes can take a few minutes to propagate.
ribo domain verify app.example.com
# ✓ app.example.com — active
ribo domain rm
ribo domain [--server <url>] rm <domain>
Remove a custom domain. It stops serving immediately, and the name is freed for reuse.
ribo domain rm app.example.com
# ✓ Removed app.example.com
ribo account
Manage which account your CLI acts on, for logins that belong to more than one. The active account is carried inside your auth token and determines where ribo deploy sends Cells and which databases, buckets, and vault secrets you see. Switching re-mints the token.
ribo account list
ribo account [--server <url>] list
List every account your login can act on. The active one is marked with *.
ribo account list
# ACCOUNT ID ROLE
# * Acme Corp acct_3f8c1a2b4d6e8f00 owner
# Personal acct_9zp5k1m3n5p7r9t1 owner (personal)
ribo account whoami
ribo account [--server <url>] whoami
Show the currently active account (name, id, and your role). Run this before a production deploy or delete to confirm you're acting on the right account.
ribo account whoami
# Acme Corp (acct_3f8c1a2b4d6e8f00) — owner
ribo account switch
ribo account [--server <url>] switch <name-or-id>
Switch the active account, re-minting your stored token. Accepts an account name (case-insensitive) or an acct_... id. Subsequent commands act on the new account until you switch again.
ribo account switch "Acme Corp"
# Switched to "Acme Corp" (acct_3f8c1a2b4d6e8f00).
ribo account pin
ribo account pin [--show] [--config <path>]
Write the active account into the local ribo.toml as an account_id pin, so the project can only be deployed to that account. --show prints what would be written without modifying the file.
ribo account pin
# Pinned Acme Corp (acct_3f8c1a2b4d6e8f00) in ribo.toml.
The pin is an assertion, not a selector — it never changes which account is used, it only aborts a deploy that would land in the wrong one. On a mismatch, ribo deploy stops before uploading anything:
ribo deploy
# Error: Refusing to deploy: account mismatch.
#
# ribo.toml pins Acme Corp (acct_3f8c1a2b4d6e8f00)
# active account Personal (acct_9zp5k1m3n5p7r9t1)
# ...
ribo profile
Manage directory-bound credentials. A profile is a named login bound to a directory; commands run in that directory, or any subdirectory, authenticate as that profile. This is how two shells — or two agents — work on two different accounts at the same time without either one clobbering the other's login.
For the full explanation and recipes, see Accounts & Profiles.
ribo profile <subcommand>
--profile <name> is also a global flag on every other command: ribo --profile acme deploy runs that one command as acme, ignoring any directory binding.
ribo profile create
ribo profile create <name> [--from-current] [--key <token>] [--auth-server <url>]
Log in and store the credential under <name>.
Flags
| Flag | Description |
|---|---|
--from-current |
Adopt the credential already in the default login instead of authenticating again |
--key <token> |
Skip the browser — store a pre-issued API key under this profile |
--auth-server <url> |
Auth server URL (default: https://auth.tissue.systems) |
ribo profile create acme # browser login, stored as "acme"
ribo profile create acme --from-current # capture the login you already have
ribo profile create ci --key tok_a1b2c3... # store an API token as a profile
--from-current copies the default login's credentials for every server it holds, while ribo account switch only re-mints the one it targeted. If more than one server is copied, ribo prints a note telling you to verify the others with ribo --profile <name> account whoami --server <url>.
ribo profile activate
ribo profile activate <name> [dir]
Bind a directory — and every subdirectory beneath it — to a profile. Defaults to the current directory.
cd ~/work/acme-site && ribo profile activate acme .
# ✓ /Users/you/work/acme-site → "acme".
# Applies to this directory and every subdirectory.
The most specific binding wins: with ~/work bound to outer and ~/work/acme bound to acme, a command in ~/work/acme/site uses acme.
ribo profile deactivate
ribo profile deactivate [dir]
Remove that directory's own binding. If a parent directory still binds it, ribo says what the directory now resolves to rather than letting you assume it fell back to the default login.
ribo profile list
ribo profile list
Every profile with its account, its servers, and its bound directories. The profile in effect for the current directory is marked with *. Bindings whose profile no longer exists are listed separately as dangling — commands in those directories fail rather than silently using your default login.
ribo profile delete
ribo profile delete <name>
Remove the profile and unbind every directory that pointed at it. The orphaned directories are listed.
ribo profile which
ribo profile which [--server <url>]
Show what this directory will authenticate as, and why. No side effects — safe to run anywhere, and the right thing to put at the top of a deploy script or an agent's checklist.
ribo profile which
# directory /Users/you/work/acme-site
# credential profile "acme" (bound at /Users/you/work/acme-site)
# server https://api.tissue.systems
# account Acme Corp (acct_3f8c1a2b4d6e8f00)
The credential line always names the origin: RIBO_TOKEN, profile "x" (--profile), profile "x" (bound at /dir), or the default profile. When RIBO_TOKEN is set, ribo adds an explicit note that it overrides all profiles.
Global behaviour
Default server: Commands that talk to the management API default to https://api.tissue.systems. Override per-command with --server, or for a whole session with the TISSUE_SERVER environment variable — it is honoured by every command: ribo deploy, ribo list, ribo delete, ribo addr, ribo invoke (for its address lookup), and all the grouped commands. Precedence is --server → TISSUE_SERVER → [server] url in ribo.toml (read by ribo deploy and ribo domain add) → the built-in default:
export TISSUE_SERVER=http://localhost:8082 # applies to every command
One nuance: ribo invoke sends the invocation itself to the runtime, which defaults to http://localhost:8080 unless --server is passed — only its management-API lookup of the Cell's address reads TISSUE_SERVER.
Authentication: every command requires a valid token — this includes ribo deploy, ribo list, ribo delete, ribo invoke, ribo addr (which resolves the name via GET /v1/cells on the management API — it is not an offline lookup), and all ribo db, ribo bucket, ribo vault, ribo token, ribo domain, and ribo sensor subcommands. Run ribo login or set RIBO_TOKEN.
Which credential: resolved in the order RIBO_TOKEN → --profile <name> → nearest bound ancestor directory → the default login. --profile is a global flag accepted by every command, and it redirects writes as well as reads — ribo --profile acme account switch "…" re-mints the credential inside that profile. Run ribo profile which to see what the current directory resolves to. Credentials live in ~/.config/ribo/token.json (default login) and ~/.config/ribo/profiles.json (profiles and bindings), both written 0600 inside a 0700 directory.
Cell addresses: Each Cell gets a stable address on first deploy (e.g. dd0d1cd5kq5bs). The address never changes across redeploys and is used in internal routing and the management API.
Cell URLs: Cells are accessible at https://<cell-name>.<account-subdomain>.tissue.dev (e.g. my-cell.strand-9c.tissue.dev). The URL is shown after every ribo deploy.