Skip to main content
Use this page when you want a Boo backed by Claude Code, Anthropic’s coding agent. Clawboo wraps the Claude Agent SDK so a Claude Code run executes a durable board task in its own worktree, reports up, and resumes across runs. Claude Code is one of the four non-OpenClaw runtimes. Like the others, it is a RuntimeAdapter: Clawboo installs its CLI, stores your ANTHROPIC_API_KEY in the encrypted vault, and reports its connection state. This page covers the bits specific to Claude Code; for the shared install/connect/disconnect lifecycle see Connecting runtimes.

Prerequisites

Node 22+ and npm (bundled with Node); Claude Code installs via npm install -g. An Anthropic API key, or an existing local claude login (the SDK falls back to the logged-in CLI’s own auth when no key is in the vault). On an install from npm you also need @anthropic-ai/claude-agent-sdk installed alongside Clawboo — see step 3.
  • The Clawboo dashboard running (clawboo).
  • A board task to run on, created via the board (you can also drive it directly with POST /api/runtimes/claude-code/run).

Capabilities

The adapter declares its capabilities() so the host routes the run by construction (it never branches on the runtime id). Claude Code’s are: Because runtimeClass is wrapped-oneshot and there is no nativeHome claim, the host provisions no persistent home for Claude Code. The SDK runs against your real HOME / Keychain auth; nothing native accrues per identity. (Contrast Hermes, which keeps a persistent home that compounds skills and memory across runs.)

Steps

1. Install the CLI

From the Runtimes panel, click Install on the Claude Code card. The card opens an SSE install stream that runs:
The package is pinned to the current major (@2) so a future major-incompatible publish is never auto-installed. The health binary the panel probes for is claude. If npm is missing the stream emits an error with code NPM_MISSING.
A global npm install can hit EACCES on a system Node. The installer detects “permission denied” in stderr and suggests sudo npm install -g @anthropic-ai/claude-code@2; but prefer a Node version manager (nvm/fnm) or Homebrew over sudo.

2. Connect your key

Click Connect on the card (from the needs-auth state) and paste an Anthropic API key. The key is stored in the encrypted vault under ANTHROPIC_API_KEY and the card flips to ready. The connect response never echoes the key. The equivalent REST call:
You can skip the explicit Connect if a credential already resolves. At run time the key is resolved by resolveRuntimeKey('ANTHROPIC_API_KEY') in priority order: process.env.ANTHROPIC_API_KEY → the encrypted vault → OpenClaw’s ~/.openclaw/.env. If any of those holds the key, the card reads ready without a paste.

3. Install the Agent SDK (published installs)

Clawboo drives Claude Code through the Claude Agent SDK, which is a separate package from the claude CLI installed in step 1. If you are running Clawboo from source (the monorepo), it is already there and you can skip this. If you installed Clawboo from npm, it is not: the published tarball deliberately does not declare it, because the SDK’s per-platform optional dependency is a ~210 MB claude binary that every install would otherwise download for a runtime most users never touch. Install it alongside Clawboo so Node can resolve it from the server bundle:
The SDK has to sit next to Clawboo in the same node_modules tree, which is why a global Clawboo pairs with a global SDK. A one-off npx clawboo runs out of npm’s throwaway cache directory, so there is nowhere to add the SDK — install Clawboo globally (or as a project dependency) if you want to use the Claude Code runtime.
Without it, the runtime card still reads ready (that reflects the claude binary plus your key), but a run fails immediately with a message naming the missing package and the command above.

4. Run a board task on it

With the runtime ready, dispatch a board task:
The server-side executor runner claims the task, provisions a worktree from repoPath, spawns the Claude Agent SDK with the connected key injected into the child env, drives the SDK’s message stream as a normalized event stream, then writes the report-up summary and AGENT_HANDOFF.json. See the /api/runtimes/:id/run reference for the full request/response shape.

How the driver works

The pure adapter lives in @clawboo/adapter-claude-code; the real driver that talks to the SDK lives server-side in claudeCodeDriver.ts. They are split deliberately so the adapter stays dependency-light (its only dependency is @clawboo/executor) and contract-testable against an in-memory fake.

The SDK is lazy-imported, and optional

@anthropic-ai/claude-agent-sdk is not bundled into the shipped server and not required at boot. The driver imports it lazily, inside the run, through a helper that turns a resolution failure into the remediation above rather than a raw resolver error:
A default Clawboo install therefore carries no Claude Code dependency in its boot graph; the SDK is loaded only when a Claude Code run actually starts. The driver’s structural types are deliberately decoupled from the SDK’s deep generated types (which reference a different zod major). It is also not a declared dependency of the published clawboo package, so an install from npm does not ship it — see Install the Agent SDK above. The reason is size: the SDK’s per-platform optional dependency is a ~210 MB claude binary, and npm installs optional dependencies by default, so declaring it would add that to every install for a runtime most users never touch. The clean-install gate treats it as a documented optional external for the same reason (OPTIONAL_EXTERNALS in scripts/lib/bundle-externals.mjs), and the driver turns Node’s bare Cannot find package into the instruction that fixes it rather than surfacing a resolver error as the run’s failure summary.

Message translation

For each run the driver builds the SDK query() options from the run context: cwd (the worktree), model, resume, the MCP server config built from mcpBaseUrl, disallowedTools (the child tool blocklist), and a scrubbed child env with the provider key merged on top. It then translates each SDK message into the adapter’s ClaudeNativeEvent union, which the pure mapClaudeEvent maps into the normalized RuntimeEvent stream: The system/init message carries the native session id and model; assistant content blocks become text (and thinking blocks become reasoning-channel text); tool_use blocks become tool-call; tool results become tool-result; and the terminal result message becomes a cost event plus a done (or error) event.

Real USD cost, passed through

Claude Code reports a real total_cost_usd per run. The mapper passes it straight through as a concrete costUsd on the cost and done events, not an estimate. (Contrast Codex, which emits no USD and is estimated.)

max_turns is a clean terminal, not an error

When a run hits its turn ceiling the SDK signals result.subtype === 'error_max_turns'. The driver surfaces this as a distinct maxTurns flag, and the mapper emits a done event with reason: 'max_turns', not an error. This is a clean “ran out of room” terminal. The host treats it as a rotation signal: it spins up a fresh successor session carrying a handoff note (not the heavy transcript) and continues, rather than failing the task. The 200k-token contextWindowTokens also drives a proactive watermark so the host can rotate before the window fills, bounded by maxRotations.

Session resume across runs

The adapter’s sessionCodec serializes the native Claude session id (captured from the init/result frames). On a later same-runtime run, the executor runner threads that id back into the run context, and the driver sets the SDK’s resume option, a genuine continuation of the prior session. A cross-runtime pickup (a different runtime resuming the task) rides the prose handoff in AGENT_HANDOFF.json instead.

Headless permissions

The run is a headless worker, so the driver sets permissionMode: 'bypassPermissions' and allowDangerouslySkipPermissions: true. This is safe because Clawboo gates risky tools externally (the board, approvals) and the run is confined to an isolated per-task worktree; the SDK requires the explicit opt-in alongside bypassPermissions. The driver also strips Clawboo’s own server secrets (gateway token, access-gate token, vault master key) from the child env before merging the provider key, so the spawned agent does not inherit them.

Verify it worked

  • The Runtimes card reads ready and GET /api/runtimes reports the Claude Code entry with connectionState: "ready" and health.ok: true. For a CLI runtime, health reflects whether the claude binary resolves on PATH or a known user-install dir.
  • After a POST /api/runtimes/claude-code/run, the task advances on the board, the worktree carries the file changes plus an AGENT_HANDOFF.json, and the run’s report-up summary lands as a board comment.

Troubleshooting

The run fails immediately saying @anthropic-ai/claude-agent-sdk is missing. The card reads ready because that reflects the claude binary plus your key, but the Agent SDK is a separate, deliberately-not-shipped package. Install it alongside Clawboo (npm install -g @anthropic-ai/claude-agent-sdk for a global Clawboo) and re-run the task — see step 3.
The run starts but cannot authenticate. With no key in the vault, the SDK falls back to the logged-in claude CLI’s auth, which lives under your real HOME/Keychain. If the Clawboo server runs with an isolated HOME (a sandboxed dev/e2e environment), that login is invisible. Set ANTHROPIC_API_KEY (env or vault) for deterministic API-key auth, or run the server at your normal HOME.
A task keeps hitting max_turns. This is not a failure; the run terminated cleanly because it exhausted its turn budget. The host rotates the session and continues. If the chain hits maxRotations without finishing, the task is released back to todo for a retry. Raise maxRotations on the run body to allow a longer chain.
POST /api/runtimes/claude-code/run returns 409. The task could not be atomically claimed; another worker won it. Per the board’s atomic-claim contract, a 409 is data, not a transient error: do not retry it. See the board.

See also

Last modified on August 4, 2026