Claude in a box
- Use it however you want: Run Claude from your terminal as a CLI, or drop it into an existing Docker Compose stack as a service.
- No API key, no extra billing: claudebox uses your existing Claude subscription and authenticates with your current Claude credentials, so personal use feels seamless.
- Real agent, strong isolation: Claude gets its full toolset inside the container—file editing, shell access, code analysis, and more; without access to your host machine or the open internet beyond Anthropic’s APIs.
- Docker — Install Docker Desktop
- Claude CLI — installed and authenticated (
curl -fsSL https://claude.ai/install.sh | bash, then runclaudeonce to log in)
claudebox uses your Claude subscription. It reads local credentials (Keychain on macOS, ~/.claude/.credentials.json on Linux) to authenticate inside the container. Credentials are resolved in order: CLAUDE_CODE_OAUTH_TOKEN env var, then platform credential store.
For: running prompts and agentic tasks in a sandboxed container from your terminal.
curl -fsSL https://raw.githubusercontent.com/ArmanJR/claudebox/main/install.sh | bashclaudebox prompt "explain how DNS works" # run a single prompt
claudebox prompt --json "explain DNS" # full JSON output
claudebox prompt --verbose "explain DNS" # container logs + output
claudebox server # start the HTTP API server
claudebox server --openai # start with OpenAI-compatible API
claudebox stop # stop the server
claudebox logs # view server logs
claudebox status # check if server is running
claudebox version # show CLI version
claudebox update # update the CLIWorks on macOS and Linux. Handles authentication automatically and refreshes expired tokens before launching the container.
| Variable | Default | Purpose |
|---|---|---|
CLAUDEBOX_PORT |
3000 |
Host port |
CLAUDEBOX_IMAGE |
ghcr.io/armanjr/claudebox:latest |
Docker image |
CLAUDEBOX_NAME |
claudebox |
Container name |
CLAUDE_CODE_OAUTH_TOKEN |
— | Skip auto-detection, use this token directly |
CLAUDEBOX_API_KEY |
— | API key for /v1/* endpoints (used with --openai) |
For: adding Claude as an agent alongside other services in your Docker Compose stack.
First, extract your OAuth token (re-run when it expires):
curl -fsSL https://raw.githubusercontent.com/ArmanJR/claudebox/main/setup-auth.sh | bashservices:
claudebox:
image: ghcr.io/armanjr/claudebox:latest
cap_add:
- NET_ADMIN
ports:
- "3000:3000"
env_file:
- path: .env.claude
required: trueThen docker compose up -d. Other services in the same network reach Claude at http://claudebox:3000.
Send a prompt to Claude and get a JSON response.
{
"prompt": "your prompt here",
"options": {
"model": "sonnet",
"maxTurns": 10,
"maxBudgetUsd": 1.0,
"systemPrompt": "you are a helpful assistant",
"appendSystemPrompt": "additional instructions",
"allowedTools": ["Read", "Edit", "Bash"],
"cwd": "/workspace"
}
}All fields in options are optional.
Response: Claude Code's JSON output (includes result, session_id, usage, total_cost_usd, etc.)
Returns {"status": "ok", "activeRequests": 0}.
| Variable | Default | Purpose |
|---|---|---|
PORT |
3000 |
Server listen port |
MAX_CONCURRENT |
4 |
Max parallel Claude processes |
OPENAI_COMPAT |
— | Set to 1 to enable /v1/* routes (set automatically by --openai) |
CLAUDEBOX_API_KEY |
— | If set, all /v1/* requests require Authorization: Bearer <key> |
Start the server with --openai (CLI) or set OPENAI_COMPAT=1 (Docker) to expose /v1/chat/completions and /v1/models. This lets you use claudebox with any OpenAI-compatible client.
# CLI
claudebox server --openai
# Docker Compose — add to environment
OPENAI_COMPAT=1Accepts the standard OpenAI chat completions request format and translates it to Claude Code invocations.
curl http://localhost:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "sonnet",
"messages": [
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Explain DNS in one sentence"}
]
}'Returns a standard OpenAI-shaped response:
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "sonnet",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "..."},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 100, "completion_tokens": 50, "total_tokens": 150}
}Supported features:
| Feature | How it maps |
|---|---|
messages[role=system] |
Concatenated into --system-prompt |
| Multi-turn conversation | Serialized into structured prompt with history |
model |
Passed through to Claude (sonnet, opus, haiku, or full model IDs) |
response_format (json_schema / json_object) |
Injected into prompt + validated; retries once on failure |
Base64 images (data:image/...;base64,...) |
Decoded to temp files, read by Claude's Read tool |
Not supported: streaming, function calling / tools, external image URLs, temperature / top_p, n > 1.
Lists available Claude models.
If CLAUDEBOX_API_KEY is set, all /v1/* requests must include Authorization: Bearer <key>. The existing /prompt and /health endpoints are unaffected.
Network isolation — iptables firewall blocks all outbound traffic except Anthropic API domains (baked into the image). To allow additional domains, mount a custom allowlist:
-v /path/to/allowed-domains.txt:/etc/allowed-domains.txt:roWorkspace — /workspace is writable so Claude can create and edit files. Mount context files read-only at /workspace/context for reference (put your CLAUDE.md there).
IP-based firewall — Domain allowlisting resolves IPs at container start. If Anthropic's CDN/load-balancer IPs rotate during the container's lifetime, connections will fail. Restart the container to re-resolve. This is an inherent limitation of iptables-based filtering.
docker compose up -d --buildTo pin a specific Claude Code version:
docker compose build --build-arg CLAUDE_CODE_VERSION=2.1.80MIT