Install the CLI
The Gavana CLI is a JSON-first command-line client for the Canvas API. It reads and changes canvases, works with assets, explicitly runs Recipes and deterministic Image Actions, queues image and video generation, and observes every execution through shared Run and Job interfaces — without opening a browser.
Prerequisites
Node.js 20 or newer.
node --versionInstall
npm install --global @gavana.ai/cli
gavana --helpThe npm command works once the package owner publishes the release. If the public package is not yet resolvable from your machine, install from a checkout of the Gavana repository instead — only if you have repository access:
npm install
npm run canvas:cli:install
command -v gavana
gavana --helpThe package installs four commands: gavana, gavana-canvas, and — as compatibility aliases for existing scripts — craftboard and craftboard-canvas. They are the same program.
Use of the published CLI is subject to the current Gavana Terms of Service .
Choose a login
| Situation | Use |
|---|---|
| Interactive use on your own machine | Browser OAuth: gavana auth login |
| Interactive, inspection only | gavana auth login --read-only |
| CI, a server, or anything unattended | A Personal Access Token via stdin |
| A remote or headless machine | gavana auth login --no-browser, then open the printed URL yourself |
Browser OAuth (default)
gavana auth loginThe CLI starts a loopback callback server, opens Gavana, asks you to approve exact scopes, and returns through the callback. Nothing is typed anywhere.
gavana auth login --read-onlyRead-only requests only canvas:read, asset:read, and element:read. The default requests canvas:read, canvas:write, asset:read, element:read, element:write, image:generate, video:generate, and job:manage. The resulting normal CLI authorization has no automatic expiry; use gavana auth logout or revoke it in Personal Access Tokens when that machine should no longer have access.
On macOS the resulting revocable token goes into Keychain under the service name ai.gavana.cli. Other platforms — and any custom config path — use a mode-0600 file. The login times out after three minutes if you do not complete it.
Personal Access Token via stdin
Never pass a token as a command argument. Use the prompt for your shell so the value never reaches shell history or the process table.
zsh (the default shell on current macOS):
read -rs 'GAVANA_AGENT_TOKEN?Paste Agent Access token: '; printf '\n'; printf '%s' "$GAVANA_AGENT_TOKEN" | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin; unset GAVANA_AGENT_TOKENBash:
read -rsp 'Paste Agent Access token: ' GAVANA_AGENT_TOKEN; printf '\n'; printf '%s' "$GAVANA_AGENT_TOKEN" | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin; unset GAVANA_AGENT_TOKENPowerShell:
$secureToken = Read-Host 'Paste Agent Access token' -AsSecureString
$token = [System.Net.NetworkCredential]::new('', $secureToken).Password
$token | gavana auth login --base-url 'https://app.gavana.ai' --token-stdin
Remove-Variable token, secureTokenVerify
gavana auth statusA working setup reports authenticated, the profile name, the base URL, a masked token, the auth type, and the granted scopes. If a scope you expected is missing, the token or consent did not include it — fix that now rather than discovering it mid-task.
gavana doctordoctor checks four things and exits 0 only if all pass:
| Check | Passes when |
|---|---|
node | Node.js major version is 20 or newer |
credentials | A token is available from the config file, environment, or command line |
base_url | The base URL is HTTPS, or HTTP on a loopback address |
authentication | Gavana accepts the credential |
If credentials fails it tells you where it looked. If authentication fails it includes the error code and the requestId — that is the one value to share with support.
Named profiles
Profiles keep accounts and environments apart. Each has its own token and base URL.
gavana auth login --profile work
gavana auth login --profile staging --base-url https://staging.example.com
gavana config list # all profiles, which is active, which are configured
gavana config get work # one profile's details
gavana config use work # change the active profile
gavana canvas list --profile staging # one-off overrideProfile precedence, highest first: the --profile flag, then GAVANA_PROFILE, then CRAFTBOARD_PROFILE, then the stored active profile, then default.
Profile names are 1–64 characters, must start with a letter or digit, and may contain letters, digits, dots, underscores, and dashes.
Log out of one profile without touching the others:
gavana auth logout --profile staginglogout revokes the token at Gavana when the profile was created by browser OAuth, then removes the profile locally. Removing the last profile deletes the config file.
Where configuration lives
~/.config/gavana/agent.jsonThe directory is created with mode 0700 and the file with mode 0600, written atomically through a temporary file.
Resolution order for the config path:
GAVANA_AGENT_CONFIG_FILECRAFTBOARD_AGENT_CONFIG_FILE$XDG_CONFIG_HOME/gavana/agent.json~/.config/gavana/agent.json
When no explicit config file is requested, the CLI also falls back to reading a legacy ~/.config/craftboard/agent.json. A Gavana config always wins.
macOS Keychain. On macOS the token is stored in Keychain rather than the file, and the file records credentialStore: "macos-keychain" instead. Keychain is skipped — and the token written to the mode-0600 file — when GAVANA_CLI_KEYCHAIN=false, when a custom config file path is set, or when XDG_CONFIG_HOME is set.
Environment variables
| Variable | Effect | Legacy alias |
|---|---|---|
GAVANA_BASE_URL | Overrides the saved base URL | CRAFTBOARD_BASE_URL |
GAVANA_AGENT_TOKEN | Overrides the saved token | CRAFTBOARD_AGENT_TOKEN |
GAVANA_PROFILE | Selects the profile | CRAFTBOARD_PROFILE |
GAVANA_AGENT_CONFIG_FILE | Overrides the config file path | CRAFTBOARD_AGENT_CONFIG_FILE |
GAVANA_CLI_KEYCHAIN | Set to false to skip macOS Keychain | — |
GAVANA_WEBHOOK_SECRET | Default webhook signing secret | CRAFTBOARD_WEBHOOK_SECRET |
GAVANA_ENABLE_LEGACY_CAMPAIGN_COMMANDS | Set to true to re-enable the retired campaign group | CRAFTBOARD_ENABLE_LEGACY_CAMPAIGN_COMMANDS |
Environment values override saved configuration; explicit flags override both.
Shell completion
gavana completion zsh >> ~/.zshrc
gavana completion bash >> ~/.bashrc
gavana completion fish > ~/.config/fish/completions/gavana.fishWith no shell argument, the CLI infers one from $SHELL and falls back to zsh.
First real command
gavana canvas list --limit 5 --output humanThen pick a canvas handle from the result and read it:
gavana canvas get canvas:OWNER_UID:CANVAS_IDSecurity notes
- Never paste a literal
cba_…token into a shell command. Use the stdin prompt above. - Do not copy the CLI profile into a repository, a chat message, or a support request. Share only the
requestIdfrom an error. - Use a distinct token per machine so you can revoke access individually.
- HTTPS is required for remote origins. Plain HTTP is accepted only for
localhost,127.0.0.1, and::1. - Installing the CLI does not install the local MCP adapter. See Connect a client when you need it.
Related
- CLI Reference — every command group in detail
- Create an Agent Access Token
- The safety contract
- Troubleshooting