CLI

Every command here is a wrapper over an endpoint in the API. It reads repetitively on purpose: a command that did something the API cannot do would be a capability the console and MCP could never have (R-261).

Installing#

The CLI is the same binary as the server (R-253), pointed at an installation over its API. It goes on your own machine rather than on the host, and everything it does can also be done in the console.

macOS, and Linux with Homebrew:

brew install bemeek-io/tap/pando

Debian, Ubuntu, Fedora, Alpine: every release attaches .deb, .rpm and .apk packages, named pando_<version>_linux_<arch>.<format>. Take a version from the releases page and download it:

VERSION=0.2.0   # the release you want
curl -LO https://github.com/bemeek-io/pando/releases/download/v${VERSION}/pando_${VERSION}_linux_amd64.deb
sudo apt install ./pando_${VERSION}_linux_amd64.deb

For .rpm, dnf install the same file; for .apk, apk add --allow-untrusted. On an ARM machine, arm64 in place of amd64.

Anything else: plain tarballs, named pando_<version>_<os>_<arch>.tar.gz, for darwin/amd64, darwin/arm64, linux/amd64 and linux/arm64:

VERSION=0.2.0   # the release you want
curl -LO https://github.com/bemeek-io/pando/releases/download/v${VERSION}/pando_${VERSION}_darwin_arm64.tar.gz
tar xzf pando_${VERSION}_darwin_arm64.tar.gz
sudo mv pando /usr/local/bin/

Every release is published with a checksum file signed by the release workflow; verifying it is described in releasing.md.

From source, with a Go toolchain:

go install github.com/bemeek-io/pando/cmd/pando@latest

Or install nothing. A Compose installation already has the binary in it:

docker compose exec pando pando app list

Connecting#

pando login https://pando.example.com

pando login stores a delegated token under your home directory, which is right for a person at a terminal and no use to CI or a container. Those get the same thing from the environment — mint a token in the console under API and tools, or with pando token create:

export PANDO_SERVER=https://pando.example.com
export PANDO_TOKEN=tok_…

The environment beats the stored file; --server beats both.

Commands#

adapter#

See and configure this installation's adapters

pando adapter

adapter add#

Add an adapter, or change one, by kind

pando adapter add <category>/<kind>

Adds an adapter of a kind from pando adapter kinds. Ordinary settings go in --set KEY=VALUE; a secret setting such as an API key is asked for without echoing it, so it never lands in your shell history (piped in when stdin is not a terminal). Adding with an existing --id changes that adapter. Pando loads adapters at startup: restart it afterwards.

pando adapter add ai/anthropic --set model=claude-sonnet-5

Flag Default What it does
--default true make it the default adapter of its category
--id the adapter's ID (default: the kind's usual prefix and name, e.g. ai_anthropic)
--name what the console calls it (default: the kind's name)
--set [] a setting, KEY=VALUE; repeat for more

adapter kinds#

Show the kinds of adapter this build can run, and their settings

pando adapter kinds

adapter list#

Show the adapters configured here

pando adapter list

app#

Work with apps

pando app

app add#

Create an app from a repository

pando app add <source-url>
Flag Default What it does
--name name for the app (defaults to the repository name)

app delete#

Delete an app, keeping a final backup of its data

pando app delete <app>

Deletes an app. Its storage is backed up first and the backup is kept until you discard it — not aged out.

If the backup fails the app is not deleted, because a failed backup means the data is not safe. Pass --discard-data to delete without one.

Flag Default What it does
--discard-data delete without keeping a backup of the app's storage

app favorite#

Pin an app to the top of your launcher

pando app favorite <app>

app icon#

Set the image on an app's launcher tile

pando app icon
app icon clear#

Remove an app's image, so its tile shows the map generated for it

pando app icon clear <app>
app icon set#

Set an app's image from a PNG, JPEG, WebP or GIF file

pando app icon set <app> <image-file>

Sets the image shown on the app's tile in everyone's launcher.

PNG, JPEG, WebP or GIF, at most 256 KB. SVG is not accepted. A square image a few hundred pixels across is plenty.

app list#

List the apps you can manage

pando app list

app rename#

Change an app's display name

pando app rename <app> <new-name>

Changes the name shown for the app in the console and on everyone's launcher.

The app's ID and address do not change.

app restart#

Restart an app's workloads, changing nothing

pando app restart <app>

Restarts the workloads in place.

Nothing is rebuilt and nothing is re-read: this is the same version, started again. To ship a change, deploy.

app show#

Show an app

pando app show <app>

app start#

Start an app that was stopped

pando app start <app>

app status#

What each part of an app is doing right now

pando app status <app>

What each part of an app is doing right now.

An app can be made of several parts, and "degraded" is the app's answer for all of them together. This is the per-part answer: which are running, which are restarting and how many times, and which health check is failing. The names are also what pando logs --workload takes.

app stop#

Stop an app without deleting it

pando app stop <app>

Stops an app.

Nothing is removed: its storage, its configuration and its address are kept, and pando app start brings back the version that was running. A stopped app stays stopped — it is the app's desired state, not a one-off act, so it survives Pando itself restarting.

app unfavorite#

Unpin an app from your launcher

pando app unfavorite <app>

app usage#

What each part of an app is using right now: CPU, memory and disk

pando app usage <app>

What each part of an app is using right now, beside its limits (R-245).

CPU is in cores; a part with no limit may use what the host has. A reading, not a history.

audit#

Read the audit log

pando audit

Lists what was done on this installation, newest first. The filters combine.

--since and --until take a time (2026-09-21T09:00:00Z) or a duration back from now (24h, 30m), so --since 24h is the last day.

Flag Default What it does
--action actions starting with this, e.g. app. or grant.delete
--actor who did it: a user or token ID, or system, reconciler or detection
--actor-kind what kind of actor: user, token, system or anonymous
--app events on this app
--before the page before this cursor, as printed after a full page
--involving events where this ID is the actor or the target, e.g. a user ID
--limit 0 how many events (default 100, at most 500)
--since from this time, or this long ago (24h)
--target the ID of the thing it was done to
--target-kind what kind of thing it was done to, e.g. user, role, app
--until up to this time, or this long ago

backup#

Back up and restore this installation

pando backup

backup create#

Take a backup of the whole installation

pando backup create

backup list#

List backups

pando backup list

backup restore#

Replace this installation from a backup

pando backup restore <backup-id>
Flag Default What it does
--yes skip the typed confirmation (for scripts that already have one)

backup verify#

Check a backup is complete, without restoring it

pando backup verify <backup-id>

config#

Show the server's startup configuration and where each setting came from

pando config

Lists every setting the server started with, its value, and where it was set: an environment variable, the config file, or the default. Host policy fields set there are listed separately; they cannot be changed with pando policy set while they are set. Secrets are never shown.

deploy#

Deploy an app, or a directory on this machine

pando deploy <app|path>

With an app ID, deploys that app. With a path, packs the directory, uploads it as the app's source, and deploys that.

The second form exists for R-262's agent workflow: something that has just generated an app cannot commit and push, but it can run a command.

Flag Default What it does
--app deploy a directory as an existing app, instead of creating one
--env [] KEY=VALUE, set when a new directory's setup is accepted; repeat for more (e.g. --env API_URL=https://api)

exec#

Run a command inside a running app

pando exec <app> [--workload <name>] [-- <command>...]

Opens a terminal inside a running workload.

This is the most privileged thing you can do to an app: what runs here can read the app's database directly and read its injected environment, including secrets. The command is recorded in the audit log; what happens inside the session is not.

Flag Default What it does
--workload which part of the app to open a terminal in (default: the one its URL points at)

export#

Print an app's spec

pando export <app>

grant#

Share an app, or stop sharing it

pando grant

grant add#

Give someone access to an app

pando grant add <app>
Flag Default What it does
--anyone share with anyone on the internet, without signing in
--group group ID to share with
--passcode with --anyone: only those who enter this passcode
--plane data data (use the app) or control (manage it)
--role role ID, for control-plane grants
--user user ID to share with

grant list#

Show who an app is shared with

pando grant list <app>

grant passcode#

Change the passcode on an app shared with everyone, or remove it

pando grant passcode <app> <grant-id> [passcode]

Sets a new passcode on the app's grant to everyone; everyone let in by the old one is asked again. With no passcode, removes it: the app is then open to anyone.

grant remove#

Take a grant away

pando grant remove <app> <grant-id>

grant role#

Change the role a grant for managing an app carries

pando grant role <app> <grant-id> <role-id>

group#

Work with groups and what they hold

pando group

group add-member#

Add an account to a group; it then holds what the group holds

pando group add-member <group-id> <user-id>

group apps#

Show the apps a group has access to, and its role on each

pando group apps <group-id>

group list#

Show every group, its members and its installation role

pando group list

group remove-member#

Remove an account from a group

pando group remove-member <group-id> <user-id>

group role#

Give a group an installation role, or take it away with --clear

pando group role <group-id> [role-id]
Flag Default What it does
--clear take the group's installation role away

login#

Sign in and store a token for this machine

pando login [server-url]

Signs in with a username and password, then creates a token and stores it. The token acts as you and holds nothing you do not.

Flag Default What it does
--username username to sign in as

logs#

Read an app's logs

pando logs <app>

Read an app's logs.

An app made of several parts — a web service, a worker, a database it brought with it — has a log per part. Without --workload this is the primary one, which is the part the app's address resolves to. pando app status <app> lists the names.

Flag Default What it does
-f, --follow keep the connection open and print new lines
-w, --workload which part of the app to read (default: the primary one)

mcp#

Run an MCP server over stdio, for agents

pando mcp

Exposes Pando's API as MCP tools, using the token from pando login.

An agent is a principal like any other: nothing here bypasses authorization, and every action lands in the audit log under the token's owner. The most dangerous actions — running commands in apps, reading secret values, changing who has access — are refused by host policy for tokens by default, and are not offered as tools.

plan#

Show what a deploy would do, without doing it

pando plan <app>

policy#

Read and set host policy

pando policy

policy set#

Replace the policy with a document read from stdin

pando policy set

Reads a whole policy document as JSON on stdin and replaces the current one. Replaces rather than merges: a merge would make it impossible to remove a rule.

policy show#

Print the installation's policy

pando policy show

restart#

Restart Pando, loading its adapters and configuration file again

pando restart

Restart Pando. Requests in flight finish first, and apps behind Pando are unreachable for the seconds it takes. Adapters and the configuration file are read again; environment variables are not.

Flag Default What it does
--wait 1m30s how long to wait for Pando to come back; 0 returns at once

rollback#

Roll an app back to an earlier spec

pando rollback <app>
Flag Default What it does
--to 0 spec revision to roll back to (defaults to the previous one)

secret#

Manage an app's secrets

pando secret

secret list#

List which secrets are set, without their values

pando secret list <app>

secret set#

Set a secret value, read from the terminal

pando secret set <app> <key>

section#

Group the apps in your launcher into sections

pando section

section add#

Move an app into a section

pando section add <section-id> <app>

section create#

Make a section

pando section create <name>

section delete#

Delete a section. Its apps go back to Your apps

pando section delete <section-id>

section list#

The apps you can open, by section

pando section list

section remove#

Move an app out of a section, back to Your apps

pando section remove <section-id> <app>

section rename#

Rename a section

pando section rename <section-id> <name>

slot#

Fill an app's service slots

pando slot

slot set#

Say how a slot is filled

pando slot set <app> <key>
Flag Default What it does
--bind bind to an existing service
--literal use this value directly
--provision let Pando create the service

token#

Manage your API tokens

pando token

token list#

List your tokens

pando token list

token revoke#

Revoke a token

pando token revoke <token-id>

user#

Work with accounts

pando user

user apps#

Show the apps an account has access to, and its role on each

pando user apps <user-id>

user create#

Create a local account with a generated password

pando user create <username>

Creates a local account and prints the password Pando generated for it, once. Give it to the account holder yourself; by default they choose their own at first sign-in.

Flag Default What it does
--email the account's email address
--name the name shown in the console and the audit log
--no-change-required do not require a new password at first sign-in

user reset-password#

Give an account a new generated password

pando user reset-password <user-id>

Sets a new generated password on a local account, ends every session it holds, and prints the password once. By default its holder chooses their own at the next sign-in.

Flag Default What it does
--no-change-required do not require a new password at the next sign-in

user update#

Change an account's username, name or email

pando user update <user-id>
Flag Default What it does
--email the account's email address
--name the name shown in the console and the audit log
--username the name the account signs in with