Skip to main content
Use this page when you want to bring a non-OpenClaw runtime, claude-code, codex, hermes, or clawboo-native, online so it can execute board tasks. Each runtime is a RuntimeAdapter: Clawboo lists it, installs its CLI, stores its provider key, and reports its connection state. OpenClaw is connected differently (the Gateway, not a CLI install); see OpenClaw. The whole lifecycle runs from the Runtimes panel (RuntimeConnectionCard), backed by /api/runtimes/*. This page documents what each step does, where keys are stored, and the per-runtime differences.

Prerequisites

The Runtimes panel is always available; every runtime is listed regardless of install or credential state. What changes per runtime is whether it needs a CLI install, an API key, or an interactive terminal login.
  • claude-code, codex, and hermes are external CLIs Clawboo installs for you. clawboo-native ships inside the Clawboo server; there is nothing to install.
  • npm (bundled with Node.js) is required to install claude-code and codex. hermes installs via Python; pipx is preferred, with a pip --user fallback.
  • A provider API key for the runtimes that authenticate head-less (claude-code, hermes, clawboo-native). codex authenticates through an interactive ChatGPT OAuth login instead of a pasted key.

At a glance

Every runtime resolves to one connection state that drives the card UI. The state is derived from installed + hasCredential + the runtime’s auth model, and is recomputed (never echoing any secret) after each action.
StateMeaningCard action
not-installedCLI binary not found on PATH or known user-install dirsInstall (SSE)
needs-authInstalled (api-key runtime) but no key storedPaste key → Connect
needs-loginInstalled (oauth runtime, i.e. codex), no pasted key possibleRun codex login, then Re-check
readyInstalled and credential present (or none auth)Re-check · Disconnect (panel only)
unknownFirst status fetch in flightRe-check

Per-runtime matrix

RuntimeBuilt-inInstallAuthEnv var written to vaultNotes
clawboo-native (Clawboo Native)yesnoneapi-keyANTHROPIC_API_KEY (+ OPENAI_API_KEY, OPENROUTER_API_KEY)In-process harness; multi-provider; any of the three keys (or OLLAMA_BASE_URL) counts as connected
claude-code (Claude Code)nonpm install -g @anthropic-ai/claude-code@2api-keyANTHROPIC_API_KEYHealth binary claude
codex (Codex)nonpm install -g @openai/codex@0oauthnoneConnects via codex login, not a pasted key; health binary codex
hermes (Hermes)nopipx install 'hermes-agent<1'api-keyOPENROUTER_API_KEYPython CLI; installs to the user-site bin (resolved off PATH); health binary hermes

Steps

1. List the runtimes

GET /api/runtimes returns { runtimes, available }. Each runtimes[] entry carries the adapter’s participantKind, capabilities, and health, plus its install/auth status (installed, binPath, builtIn, authKind, envVar, hasCredential, installCommand, docsUrl, connectionState). The available[] list is the full descriptor catalog (no secrets) so the panel can render “available to add” cards for runtimes you have not connected yet. A built-in runtime (clawboo-native) always reports installed: true with binPath: null. A CLI runtime reports installed based on whether resolveRuntimeBin finds its health binary; this probe checks PATH and the well-known user-install dirs (the pip --user / pipx location), which is how Hermes is found even though its Python user-site bin is usually off the server’s PATH.

2. Install the CLI (claude-code, codex, hermes)

POST /api/runtimes/:id/install is a Server-Sent Events stream. The card opens it from the not-installed state and renders the install log in a terminal box. Events:
Event typePayloadMeaning
progress{ step, message }Phase marker (installing, retrying)
output{ line }A line of the installer’s stdout/stderr
error{ code, message }Failure (NPM_MISSING, PYTHON_MISSING, EACCES, SPAWN_THROW, SPAWN_ERROR, EXIT_<code>)
complete{ success: true, warning? }Install finished; warning set if the binary still is not resolvable
  • npm runtimes (claude-code, codex) run npm install -g <pkg>. If npm is not found, the stream emits error with code NPM_MISSING.
  • The pip runtime (hermes) prefers pipx install <pkg>. If pipx is absent it falls back to python -m pip install --user <pkg>, and if it detects a PEP-668 externally-managed environment it retries once with --break-system-packages. If neither pipx nor python is found it emits error with code PYTHON_MISSING.
  • Calling install on a built-in runtime returns 400 (plain JSON, the SSE stream never opens); clawboo-native has nothing to install.
A global npm install can hit EACCES. When the installer’s stderr contains EACCES or “permission denied”, the stream emits an error event suggesting sudo <installCommand>. Prefer a Node version manager (nvm/fnm) or Homebrew over sudo.

3. Connect (api-key runtimes)

POST /api/runtimes/:id/connect with body { apiKey, provider? } stores the key in the encrypted vault and returns the recomputed connectionState. The key is trimmed; an empty key returns 400 ({ error: "apiKey is required" }). The response never echoes the key. The card sends the key from the needs-auth state (the input label is the runtime’s envVar, with a show/hide toggle). On success it clears the input and re-fetches status, which flips the card to ready. For clawboo-native the optional provider field routes the key to the right vault slot. Without it, the key lands in ANTHROPIC_API_KEY; with provider: "openai" or "openrouter" it goes to that provider’s env var (validated against the runtime’s known set), and provider: "ollama" is a keyless no-op (nothing is stored).

4. Connect (codex, oauth)

codex cannot be connected with a pasted key on current versions. POST /api/runtimes/codex/connect is a no-op that returns:
{ "ok": true, "connectionState": "needs-login", "loginCommand": "codex login" }
The card shows the codex login command (with a copy button), you run it in your terminal, then click Re-check. Once codex login has authenticated locally, the adapter run path uses Codex’s own CODEX_HOME; Clawboo does not store a Codex credential in its vault.

5. Health-check a native provider key (optional)

POST /api/runtimes/clawboo-native/healthcheck with body { provider, apiKey } verifies a key before you commit to it (used by the native onboarding flow before seeding a team). It makes a single authenticated GET to the provider’s lightweight models/health endpoint:
providerEndpoint probed
anthropichttps://api.anthropic.com/v1/models
openaihttps://api.openai.com/v1/models
openrouterhttps://openrouter.ai/api/v1/models
ollama<OLLAMA_BASE_URL>/api/tags (keyless)
It returns { ok: true } on a 2xx, or { ok: false, error } on a bad key (401/403 → “Invalid API key.”), an 8-second timeout, or a network failure. The key is used for exactly that one fetch, never persisted to the vault, never logged, never echoed. This route is only valid for clawboo-native; any other runtime id returns 400. An unknown provider, or a missing key for a non-Ollama provider, returns 400.

6. Disconnect

POST /api/runtimes/:id/disconnect deletes the runtime’s stored credential and returns the recomputed connectionState. It keeps the CLI installed, so the card drops from ready to needs-auth. The card’s Disconnect button (panel variant only) confirms first, since you will need to re-enter the key to reconnect. For codex (no envVar) this is a no-op that just re-reports state.

Where keys are stored

API keys live in an encrypted vault at ~/.clawboo/secrets/runtime-keys.json (under resolveClawbooDir(); the CLAWBOO_HOME override applies), keyed by env-var name. Each value is encrypted with AES-256-GCM under a 32-byte master key at ~/.clawboo/secrets/master.key (mode 0600, inside a 0700 dir). CLAWBOO_SECRETS_MASTER_KEY overrides the on-disk key (32-byte base64, 64 hex chars, or a raw 32-char string). At run time the key is resolved by resolveRuntimeKey(envVar), highest priority first:
  1. process.env[envVar]
  2. the encrypted vault (decrypt)
  3. OpenClaw’s ~/.openclaw/.env
This is defense in depth, not protection against a process running as you. The decrypted value is never logged, never returned in an HTTP response body, and never written to SQLite, audit, or observability records; it flows only into a spawned runtime process’s environment. A wrong, rotated, or lost master key fails closed (resolution returns null); it never throws into a request or leaks partial plaintext.
Because resolveRuntimeKey falls back to process.env and OpenClaw’s .env, a runtime can already read as connected without an explicit Connect. For example, if ANTHROPIC_API_KEY is exported in the server’s environment or present in ~/.openclaw/.env, both claude-code and clawboo-native resolve a credential and report ready.

Verify it worked

  • Re-fetch GET /api/runtimes (or click Re-check in the card). The runtime’s connectionState should read ready, and its health.ok should be true.
  • For CLI runtimes, health reports the binary presence; for clawboo-native, health reports whether any routable provider key (or OLLAMA_BASE_URL) resolves.
  • Run a board task on the runtime via POST /api/runtimes/:id/run; the connected key is injected from the vault into the spawned process’s environment.

Troubleshooting

Hermes installs but reads as not-installed. The hermes binary lands in the Python user-site bin, which is usually off the server’s PATH. Clawboo resolves it via resolveRuntimeBin (PATH plus the known user-install dirs), so this is normally handled; but a fresh install’s complete event may carry a warning if the binary is not yet resolvable, in which case restart the server.
Codex shows “Needs login” after a successful codex login. The card does not auto-detect the login; click Re-check to re-fetch status. Codex never reaches ready from a vault key; its auth lives in CODEX_HOME.
POST /api/runtimes/:id with an unknown :id returns 404 ({ error: "unknown runtime '<id>'" }). Only claude-code, codex, hermes, and clawboo-native are valid ids; OpenClaw is not a /api/runtimes runtime.