Headless Mode

Run CCP non-interactively from CI, dev VMs, scripts, and AI agents.

Headless Mode

CCP is designed to run unattended in CI pipelines, ephemeral dev VMs, and AI-agent loops. One env var puts the CLI into headless mode, an auth token can be passed in via the environment, and identity flags let you target specific resources without prompts.

Enabling Headless Mode

Set CCP_HEADLESS=1 in the environment:

export CCP_HEADLESS=1

This is the single canonical switch. With it set, every interactive prompt is auto-confirmed, every TTY-only command (ccp db connect) errors fast, and styled output is replaced with terse one-line [ccp] ... logs suitable for log capture.

CCP also auto-detects non-TTY stdin/stderr and behaves the same way. Prefer the env var when running under PTYs (tmux, screen, expect-style wrappers) where TTY detection can falsely report interactive.

Per-command escape hatches still exist — ccp dev --headless, ccp deploy --yes, ccp db destroy --yes — but CCP_HEADLESS=1 covers all of them at once.

Destructive commands run without confirmation in headless mode. ccp remove, ccp undeploy, ccp db destroy, ccp db backup delete, and ccp domain remove all execute immediately. This is intentional for automation; double-check the target ID before invoking.

Authentication

CCP resolves a session token in this order:

  1. CCP_SESSION_TOKEN env var (preferred for headless)
  2. OS keychain (macOS Keychain, Linux secret service)
  3. ~/.cluster/ccp-session.json

The recommended headless flow is to authenticate once on a workstation, export the token, and pass it into the runtime environment:

# On the operator's machine (interactive)
TOKEN=$(ccp auth print-access-token)

# In the headless environment
export CCP_SESSION_TOKEN="$TOKEN"
ccp deploy --prod

If CCP_SESSION_TOKEN is expired, CCP attempts a silent refresh; if refresh fails, it errors with Not logged in and you'll need to re-export a fresh token.

For scripted login when you have an OTP code in hand, pass --email and --code together. --code skips the OTP send step and assumes the code was already issued:

ccp auth login --email me@example.com --code 123456

Plain ccp auth login (no --code) will hang or error in a non-TTY context — always pair email and code together when scripting.

Identity Flags

Identity flags name which resource a command operates on. They're orthogonal to headless mode — passing --org-id doesn't enable headless, and CCP_HEADLESS=1 won't pick a resource for you.

FlagUsed byResolved from
--org-id <id>ccp deploy, ccp link.cluster/config.json if omitted
--function-id <id>ccp deploy, ccp link, ccp db create.cluster/config.json if omitted
--db-id <id>ccp db exec, migrate, connect, backup *, destroy.cluster/config.json if omitted
--token <token>ccp db exec, migrate, connect.cluster/config.json if omitted
--store-idccp store *.cluster/config.json if omitted

When a required ID is missing and can't be resolved from config, CCP errors clearly rather than guessing. The exception: if exactly one org or store exists on your account, CCP will pick it.

Always commit .cluster/config.json. It's how subsequent invocations (and other VMs) find the function.

Reference Matrix

With CCP_HEADLESS=1 set:

CommandHeadless-safeRequired input
ccp init <name>yespositional <name>
ccp devyes
ccp buildyes
ccp deployyespopulated config, or nothing — unlinked, it auto-creates a function (single-org auto-picks; --org-id for multi-org)
ccp linkyes--org-id + --function-id
ccp list / lsyeslinked project; outside one, --org-id or a single-org account
ccp removeyes (destructive)linked project
ccp promote <id>yesdeployment ID
ccp undeploy <id>yes (destructive)deployment ID
ccp store createyesorg from config or single-org account
ccp store put / get / ls / rmyesstore from config or single-store org
ccp db createyeslinked project or --function-id
ccp db ls / info / exec / migrateyeslinked project or --db-id
ccp db destroy <id>yes (destructive)DB ID
ccp db connectnouse ccp db exec instead
ccp db backup create / lsyeslinked project or --db-id
ccp db backup restore <id>yes (destructive)backup ID
ccp db backup delete <id>yes (destructive)backup ID
ccp domain ls / add / link / unlinkyesflags as needed
ccp domain remove <domain>yes (destructive)domain
ccp auth loginyes--email + --code
ccp auth print-access-token / export-access-token / logoutyeslogged-in session

ccp db connect is the only command that's incompatible with headless mode — it opens a TUI psql shell. Use ccp db exec '<SQL>' for one-off statements.

Typical Agent Workflow

# In an ephemeral dev VM (CCP_HEADLESS=1 and CCP_SESSION_TOKEN already in env)

cd /workspace
ccp init my-app --template react
cd my-app

# ... agent edits code, runs tests ...

# First deploy auto-creates + links the function (single-org account → no flags;
# multi-org → add --org-id), and writes the IDs to config:
ccp deploy --prod

# Persist the link before VM teardown:
git add .cluster/config.json
git commit -m "link function"
git push

# Later, in a fresh VM with the same repo:
git clone "$REPO" && cd my-app
ccp deploy --prod   # reuses .cluster/config.json

Reference for AI Agents

ccp print-skill prints an authoritative reference for the CLI when used by an AI agent. It's embedded in the binary, so it stays in sync with the version of ccp you have installed:

ccp print-skill

The output is a markdown document covering authentication, project shape, every command's headless behavior, and common pitfalls. Pipe it into an agent's context, or save it as SKILL.md in your project to give a coding agent a complete reference for working with CCP.

Common Pitfalls

  • Don't commit: .env, node_modules/, or .cluster/index.js (build output).
  • Always commit: .cluster/config.json — the persistent link to the remote function across VMs.
  • Token expiry: if CCP_SESSION_TOKEN is expired and silent refresh fails, re-export a fresh token from the operator's machine.
  • No git integration: CCP doesn't commit or push for you. Persist .cluster/config.json manually after the first deploy or link.
  • Build artifacts (.cluster/index.js, bundled assets) regenerate on each ccp deploy / ccp build — safe to delete from a clean checkout.

On this page