> ## Documentation Index
> Fetch the complete documentation index at: https://docs.archil.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code

> Run Claude Code headlessly in an Archil sandbox, with its workspace and session history on an Archil disk.

[Claude Code](https://code.claude.com/docs) is Anthropic's coding agent. In an Archil [sandbox](/compute/sandboxes/introduction) it gets a Linux VM of its own, so you can let it work without permission prompts. Its workspace and session history live on an Archil disk, so the work outlives the sandbox, and a new sandbox can pick up the same conversation.

## Prerequisites

Export your Archil API key, a region where sandboxes are available (`aws-us-east-1`, `aws-us-west-2`, or `aws-eu-west-1`), and an [Anthropic API key](https://console.anthropic.com/settings/keys), then install the SDK:

```bash theme={null}
export ARCHIL_API_KEY=key-...
export ARCHIL_REGION=aws-us-east-1
export ANTHROPIC_API_KEY=sk-ant-...
```

<CodeGroup>
  ```bash TypeScript theme={null}
  npm init -y && npm pkg set type=module
  npm install disk tsx
  ```

  ```bash Python theme={null}
  pip install archil
  ```
</CodeGroup>

## Run Claude Code in a sandbox

This script creates a disk, starts a sandbox with the disk mounted at `/workspace`, installs Claude Code, and gives it a task in print mode (`claude -p`), which works until the task is done, prints the answer, and exits. Then it deletes the sandbox; everything the agent made is on the disk.

<CodeGroup>
  ```typescript start.ts theme={null}
  import * as archil from "disk";

  const env = {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
    CLAUDE_CONFIG_DIR: "/workspace/.claude", // keep sessions on the disk
    IS_SANDBOX: "1", // sandboxes run as root; allows --dangerously-skip-permissions
  };

  const { disk } = await archil.createDisk({ name: "claude-code-workspace" });
  const sandbox = await archil.createSandbox({ name: "claude-code", mounts: [{ disk, path: "/workspace" }] });
  await sandbox.exec("npm install -g @anthropic-ai/claude-code");

  const result = await sandbox.exec(
    'claude -p "Create a hello-world Express app with a test, and run the test. Reply in two sentences." ' +
      "--model claude-sonnet-5 --dangerously-skip-permissions",
    { cwd: "/workspace", env },
  );
  console.log(result.stdout);

  await sandbox.stop();
  await sandbox.delete();
  ```

  ```python start.py theme={null}
  import os

  import archil

  env = {
      "ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"],
      "CLAUDE_CONFIG_DIR": "/workspace/.claude",  # keep sessions on the disk
      "IS_SANDBOX": "1",  # sandboxes run as root; allows --dangerously-skip-permissions
  }

  disk = archil.create_disk(name="claude-code-workspace").disk
  sandbox = archil.create_sandbox(
      name="claude-code", mounts=[archil.SandboxMountSpec(disk=disk, path="/workspace")]
  )
  sandbox.exec("npm install -g @anthropic-ai/claude-code")

  result = sandbox.exec(
      'claude -p "Create a hello-world Express app with a test, and run the test. Reply in two sentences." '
      "--model claude-sonnet-5 --dangerously-skip-permissions",
      cwd="/workspace",
      env=env,
  )
  print(result.stdout)

  sandbox.stop()
  sandbox.delete()
  ```
</CodeGroup>

Run it with `npx tsx start.ts` or `python start.py`. The agent's wording varies from run to run. One run printed:

```text theme={null}
Created a hello-world Express app at `/workspace/hello-express` (`app.js` serving "Hello, World!" at `/`, plus `server.js` to run it) with a supertest/Jest test in `app.test.js`. Ran `npm test` and the test passed (1/1).
```

## Pick up where you left off

Claude Code's project and session history are on the disk, so any sandbox that mounts it can continue the conversation. This script starts a new sandbox on the same disk and runs Claude Code with `--continue`, which resumes the most recent conversation in `/workspace`.

<CodeGroup>
  ```typescript continue.ts theme={null}
  import * as archil from "disk";

  const env = {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
    CLAUDE_CONFIG_DIR: "/workspace/.claude",
    IS_SANDBOX: "1",
  };

  const [disk] = await archil.listDisks({ name: "claude-code-workspace" });
  const sandbox = await archil.createSandbox({ name: "claude-code", mounts: [{ disk, path: "/workspace" }] });
  await sandbox.exec("npm install -g @anthropic-ai/claude-code");

  const result = await sandbox.exec(
    'claude --continue -p "Add a /health route with a test and run all the tests. Reply in two sentences." ' +
      "--model claude-sonnet-5 --dangerously-skip-permissions",
    { cwd: "/workspace", env },
  );
  console.log(result.stdout);

  await sandbox.stop();
  await sandbox.delete();
  ```

  ```python continue.py theme={null}
  import os

  import archil

  env = {
      "ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"],
      "CLAUDE_CONFIG_DIR": "/workspace/.claude",
      "IS_SANDBOX": "1",
  }

  [disk] = archil.list_disks(name="claude-code-workspace")
  sandbox = archil.create_sandbox(
      name="claude-code", mounts=[archil.SandboxMountSpec(disk=disk, path="/workspace")]
  )
  sandbox.exec("npm install -g @anthropic-ai/claude-code")

  result = sandbox.exec(
      'claude --continue -p "Add a /health route with a test and run all the tests. Reply in two sentences." '
      "--model claude-sonnet-5 --dangerously-skip-permissions",
      cwd="/workspace",
      env=env,
  )
  print(result.stdout)

  sandbox.stop()
  sandbox.delete()
  ```
</CodeGroup>

```text theme={null}
Added a `/health` route returning `{ status: 'ok' }` with a corresponding test in `app.test.js`. All tests pass (2/2).
```

## Going further

* **Stream output.** Pass `onOutput: ({ data }) => process.stdout.write(data)` to `exec` (in Python, `on_output=lambda out: sys.stdout.buffer.write(out.data)`) to watch the agent as it works. Add `--output-format stream-json --verbose` to get one JSON event per line.
* **Work interactively.** Start `claude` without `-p` in a pseudo-terminal with `sandbox.run`; see [Opening interactive shells](/compute/sandboxes/introduction#opening-interactive-shells).

<Accordion title="Use Vercel AI Gateway instead of an Anthropic key">
  Claude Code can send its requests through [Vercel AI Gateway](https://vercel.com/docs/ai-gateway/coding-agents/claude-code). Export `AI_GATEWAY_API_KEY` instead of `ANTHROPIC_API_KEY`, and replace the `ANTHROPIC_API_KEY` line in `env` with these lines. `ANTHROPIC_API_KEY` must be an empty string, because Claude Code prefers it over `ANTHROPIC_AUTH_TOKEN`. On the Developer plan, sandboxes can't reach the gateway, because it isn't on the [managed allowlist](/compute/sandboxes/firewall#developer-plan-allowlist); use your provider key instead.

  <CodeGroup>
    ```typescript TypeScript theme={null}
    ANTHROPIC_BASE_URL: "https://ai-gateway.vercel.sh/claude-code",
    ANTHROPIC_AUTH_TOKEN: process.env.AI_GATEWAY_API_KEY!,
    ANTHROPIC_API_KEY: "",
    ```

    ```python Python theme={null}
    "ANTHROPIC_BASE_URL": "https://ai-gateway.vercel.sh/claude-code",
    "ANTHROPIC_AUTH_TOKEN": os.environ["AI_GATEWAY_API_KEY"],
    "ANTHROPIC_API_KEY": "",
    ```
  </CodeGroup>
</Accordion>

## Clean up

Each script deletes its sandbox when it finishes, so only the disk is left. Delete it:

<CodeGroup>
  ```typescript cleanup.ts theme={null}
  import * as archil from "disk";

  const [disk] = await archil.listDisks({ name: "claude-code-workspace" });
  await disk.delete();
  ```

  ```python cleanup.py theme={null}
  import archil

  [disk] = archil.list_disks(name="claude-code-workspace")
  disk.delete()
  ```
</CodeGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="OpenCode" icon="terminal" href="/guides/agents/opencode">
    Run OpenCode headlessly in a sandbox.
  </Card>

  <Card title="OpenAI Codex" icon="terminal" href="/guides/agents/codex">
    Run the Codex CLI headlessly in a sandbox.
  </Card>

  <Card title="Coding agent in a sandbox" icon="code" href="/guides/agents/coding-agent">
    Build your own coding agent with the AI SDK instead.
  </Card>

  <Card title="Persistent sandboxes" icon="box" href="/compute/sandboxes/introduction">
    Lifecycle, services, network access, and forking in detail.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.