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

# Claude Code

> Run Claude Code in a secure Nullspace machine.

The `claude-code` template supports `ANTHROPIC_API_KEY`.

## Run Claude Code

Create a machine from the `claude-code` template, run Claude Code headlessly,
and clean up. The SDK and CLI paths are equivalent — use the one that matches
your workflow.

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  import os
  from nullspace import Machine

  with Machine.create(
      template="claude-code",
      envs={"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"]},
      timeout=600,
  ) as machine:
      result = machine.commands.run(
          'claude --dangerously-skip-permissions -p "Create a hello world HTTP server in Go"',
          shell=True,
          cwd="/workspace",
          timeout=600,
      )
      print(result.stdout)
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine create \
    --template claude-code \
    --env "ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}" \
    --timeout 600
  # machine create prints the id used below as mch_123
  nullspace machine exec mch_123 \
    --cwd /workspace \
    --timeout 600 \
    --shell 'claude --dangerously-skip-permissions -p "Create a hello world HTTP server in Go"'
  nullspace machine kill mch_123
  ```
</CodeGroup>

### Interactive terminal

Open a PTY instead of a headless run to drive Claude Code interactively:

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
nullspace machine pty create mch_123 --cols 120 --rows 30
nullspace machine pty connect mch_123 --session-id ses_123
# then, inside the PTY:
claude
```

Use the `session_id` from `machine pty create` with `--session-id`.

## Work on a cloned repository

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
import os
from nullspace import GitHttpsAuth, Machine

with Machine.create(
    template="claude-code",
    envs={"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"]},
    timeout=600,
) as machine:
    machine.git.clone(
        "https://github.com/your-org/your-repo.git",
        path="/workspace/repo",
        auth=GitHttpsAuth(username="x-access-token", password=os.environ["GITHUB_TOKEN"]),
        depth=1,
    )
    machine.commands.run(
        'claude --dangerously-skip-permissions -p "Find and fix all TODO comments"',
        shell=True,
        cwd="/workspace/repo",
        timeout=600,
        on_stdout=lambda data: print(data, end=""),
    )
    print(machine.git.diff(path="/workspace/repo"))
```

## Structured and streaming output

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
result = machine.commands.run(
    'claude --dangerously-skip-permissions --output-format json -p "Review this codebase and return JSON"',
    shell=True,
    cwd="/workspace/repo",
    timeout=600,
)
print(result.stdout)

machine.commands.run(
    'claude --dangerously-skip-permissions --output-format stream-json -p "Find risks"',
    shell=True,
    cwd="/workspace/repo",
    timeout=600,
    on_stdout=lambda data: print(data, end=""),
)
```

## Resume a session

Claude Code persists conversations in its own CLI state inside the machine. Use
the CLI's session ID with `--resume` when you want follow-up work in the same
machine session.

Nullspace run IDs are not conversation session IDs. Framework session, thread,
checkpoint, or flow state stays app-owned. For Claude Code, store session files
in a volume or app-managed storage when they must survive machine cleanup. Use
volumes, retained machines, hibernate/auto-resume, or an external database for
state that must outlive one disposable machine.

## Related

* [Agent workspace example](../examples/agent)
* [Claude Agent SDK](./claude-agent-sdk)
* [PTY sessions](../access/pty)
* [Templates](../templates/overview)
* [Volumes](../volumes/overview)
