Claude — For Claude Code CLI with the Claude JSON protocol
Use this SDK to build interactive CLIs, full-stack applications, or custom integrations that communicate with agents via Axons.Repository:runloopai/agent-axon-client-ts
ANTHROPIC_API_KEY environment variable (for Claude protocol only)
2
Import the protocol module
The SDK exports two protocol-specific modules:
// For ACP agents (OpenCode, Goose, etc.)import { ACPAxonConnection, PROTOCOL_VERSION } from "@runloop/agent-axon-client/acp";// For Claude Code CLIimport { ClaudeAxonConnection } from "@runloop/agent-axon-client/claude";// Core SDK for devbox and axon managementimport { RunloopSDK } from "@runloop/api-client";
See the complete working example at acp-app with UI modeled after Cursor’s chat interface, supporting streaming blocks, inline tool calls with diffs, and plan views.
This minimal example uses the Runloop SDK to create a devbox with Claude Code mounted on it. Claude Code runs inside the devbox and processes your prompt; the SDK sends the prompt and prints the streamed response. This all is orchestrated by an Axon.
import { RunloopSDK } from "@runloop/api-client";import { ClaudeAxonConnection } from "@runloop/agent-axon-client/claude";import type { SDKMessage } from "@anthropic-ai/claude-agent-sdk";// Setupconst runloop = new RunloopSDK();console.log("Starting devbox...");const axon = await runloop.axon.create({ name: "hello-world-session" });const devbox = await runloop.devbox.create({ mounts: [ { type: "broker_mount", axon_id: axon.id, protocol: "claude_json", launch_args: [], }, ], blueprint_name: "runloop/agents", environment_variables: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY || "", },});console.log(`Devbox ready: ${devbox.id}`);// Connectconst client = new ClaudeAxonConnection(axon, devbox, { // Optional: specify model // model: "claude-haiku-4.5-20250929"});console.log("Connecting to Claude...");await client.connect();console.log("Connected.\n");// Send a single prompt and print the responseconsole.log("Sending prompt: 'Say hello world'\n");await client.send("Say hello world");for await (const msg of client.receiveResponse()) { renderMessage(msg);}function renderMessage(msg: SDKMessage): void { switch (msg.type) { case "assistant": for (const block of msg.message.content) { if (block.type === "text") { process.stdout.write(block.text); } } break; case "result": console.log(); if (msg.is_error) { console.error(`Error: ${msg.subtype}`); } else { const cost = msg.total_cost_usd; const turns = msg.num_turns; const duration = (msg.duration_ms / 1000).toFixed(1); console.log(`--- ${turns} turn(s), ${duration}s, $${cost.toFixed(4)} ---`); } break; }}// Cleanupconsole.log("\nDisconnecting...");await client.disconnect();console.log("Done.");process.exit(0);
Key concepts:
ClaudeAxonConnection — Wraps the Axon and provides Claude protocol methods
connect() — Establishes connection and initializes session automatically
send() — Sends a user message to Claude
receiveResponse() — Async iterator yielding SDKMessage objects for streaming
Message types — assistant, system, result, rate_limit_event for different response types
The Claude module supports the same full-stack architecture as ACP, with streaming over WebSocket to React frontends. The flow is identical except for protocol-specific message types.Key differences from ACP:
Automatic session initialization on connect()
Async iterator pattern instead of callbacks
Different message types (assistant, system, result vs ACP session updates)
Control request/response pattern for permissions and user questions
See the complete working example at claude-app with similar architecture to the ACP app but Claude-specific message handling.
for await (const msg of client.receiveResponse()) { switch (msg.type) { case "assistant": // Assistant response with content blocks (text, thinking, tool_use) break; case "system": // System messages (init, task_started, task_progress, task_notification) break; case "result": // Turn completion with cost, duration, and error status break; case "rate_limit_event": // Rate limit information break; }}
# Clone the repositorygit clone https://github.com/runloopai/agent-axon-client-tscd agent-axon-client-ts/examples# Install dependencies and buildbun install && bun run build# Set API keysexport RUNLOOP_API_KEY=your_runloop_api_keyexport ANTHROPIC_API_KEY=your_anthropic_api_key # Claude examples only# Run any examplecd acp-hello-worldbun run acp-hello-world.ts# Or with optionsbun run acp-cli.ts --agent goose --verbosebun run claude-hello-world.ts --model haiku-4.5