{"id":"a99725d0-7d31-4d53-8f75-c59e38f54f2c","entityType":"agent","slug":"clawhub-psyb0t-claudebox","name":"claudebox","canonicalUrl":"https://www.xpersona.co/agent/clawhub-psyb0t-claudebox","canonicalPath":"/agent/clawhub-psyb0t-claudebox","generatedAt":"2026-10-10T07:53:42.762Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T04:35:01.162Z","emptyReason":null},"description":"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces. Skill: claudebox Owner: psyb0t Summary: Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces. Tags: latest:2.5.0 Version history: v2.5.0 | 2026-10-07T17:20:21.602Z | auto cluedebox v2.5.0 changelog: - Updated reference documentation in references/setup.md. - Removed skill-card.md file. - No changes to command-line interface or functionality—docu","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.7K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s17fq93tmpky791n7516jcn08n83sfn2:claudebox","sourceUrl":"https://clawhub.ai/psyb0t/claudebox","homepage":"https://clawhub.ai/psyb0t/skills/claudebox","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/psyb0t/claudebox","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/psyb0t/skills/claudebox","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":65,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces. Skill: claudebox Owner: psyb0t Su"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:35:01.162Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:35:01.162Z","emptyReason":null},"stars":null,"forks":null,"downloads":1681,"packageName":null,"latestVersion":"2.5.0","tractionLabel":"1.7K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T04:35:01.161Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T04:35:01.162Z","lastCrawledAt":"2026-10-10T04:35:01.161Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T04:35:01.161Z","lastVerifiedAt":null,"highlights":[{"version":"2.5.0","createdAt":"2026-10-07T17:20:21.602Z","changelog":"cluedebox v2.5.0 changelog: - Updated reference documentation in references/setup.md. - Removed skill-card.md file. - No changes to command-line interface or functionality—documentation only. - Skill description, usage, and security guidance remain unchanged.","fileCount":4,"zipByteSize":17693},{"version":"2.4.7","createdAt":"2026-10-07T13:40:17.890Z","changelog":"cluedebox 2.4.7 - Clarified that the standard wrapper now mounts `/var/run/docker.sock` for host Docker control; server Compose examples omit this mount. - Revised and clarified security/sandboxing and MCP server notes for increased precision, warning against use with untrusted inputs or as a sandbox. - Updated API mode and server interaction notes, including precedence and simultaneous mode behavior. - Streamlined and reworded \"When to use\" and \"When NOT to use\" sections. - Removed obsolete skill-card.md documentation file.","fileCount":4,"zipByteSize":17344},{"version":"2.4.6","createdAt":"2026-09-26T01:26:11.718Z","changelog":"- Removed the file: skill-card.md - Updated SKILL.md with no user-facing changes detected in visible content (likely formatting, comments, or metadata updates)","fileCount":4,"zipByteSize":17165},{"version":"2.4.5","createdAt":"2026-09-23T20:13:55.570Z","changelog":"- Removed the skill-card.md file. - No functional or user-facing changes to the claudebox skill itself.","fileCount":4,"zipByteSize":17475},{"version":"2.4.4","createdAt":"2026-09-23T18:51:10.246Z","changelog":"- Removed the file: skill-card.md - No user-facing or functional changes; documentation content and core interface remain unchanged.","fileCount":4,"zipByteSize":17260},{"version":"2.4.3","createdAt":"2026-09-14T11:50:15.656Z","changelog":"clauedebox 2.4.3 brings updated wrapper usage instructions and streamlines server and sibling command behavior. - Clarifies that `claudebox` should be called directly for interactive and one-shot use; avoids manual `docker run` construction. - Adds guidance for starting API/MCP servers and passing environment variables, emphasizing use of `CLAUDEBOX_ENV_*`. - Details sibling box invocation (e.g., `codexbox`, `pibox`), including wrapper coordination and state isolation. - Removes references to generic usage outside the wrapper; highlights security and installation best practices. - Removes the now-obsolete `skill-card.md` file for a cleaner skill package.","fileCount":4,"zipByteSize":17420},{"version":"2.4.2","createdAt":"2026-09-14T00:14:17.534Z","changelog":"- Updated invocation syntax for one-shot exec mode: now requires explicit -p flag (`claudebox -p \"prompt\"`). - SKILL.md and references/setup.md updated to clarify new usage. - Removed the obsolete skill-card.md file. - Minor copy edits and improved consistency in documentation.","fileCount":4,"zipByteSize":16805},{"version":"2.4.1","createdAt":"2026-09-13T16:12:50.084Z","changelog":"- Updated setup documentation in references/setup.md. - Removed skill-card.md file. - No changes to core functionality or public API.","fileCount":4,"zipByteSize":16740}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17fq93tmpky791n7516jcn08n83sfn2:claudebox","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T07:53:42.759Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-psyb0t-claudebox/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T04:35:01.162Z","emptyReason":null},"readme":"Skill: claudebox\n\nOwner: psyb0t\n\nSummary: Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\n\nTags: latest:2.5.0\n\nVersion history:\n\nv2.5.0 | 2026-10-07T17:20:21.602Z | auto\n\ncluedebox v2.5.0 changelog:\n\n- Updated reference documentation in references/setup.md.\n- Removed skill-card.md file.\n- No changes to command-line interface or functionality—documentation only.\n- Skill description, usage, and security guidance remain unchanged.\n\nv2.4.7 | 2026-10-07T13:40:17.890Z | auto\n\ncluedebox 2.4.7\n\n- Clarified that the standard wrapper now mounts `/var/run/docker.sock` for host Docker control; server Compose examples omit this mount.\n- Revised and clarified security/sandboxing and MCP server notes for increased precision, warning against use with untrusted inputs or as a sandbox.\n- Updated API mode and server interaction notes, including precedence and simultaneous mode behavior.\n- Streamlined and reworded \"When to use\" and \"When NOT to use\" sections.\n- Removed obsolete skill-card.md documentation file.\n\nv2.4.6 | 2026-09-26T01:26:11.718Z | auto\n\n- Removed the file: skill-card.md\n- Updated SKILL.md with no user-facing changes detected in visible content (likely formatting, comments, or metadata updates)\n\nv2.4.5 | 2026-09-23T20:13:55.570Z | auto\n\n- Removed the skill-card.md file.\n- No functional or user-facing changes to the claudebox skill itself.\n\nv2.4.4 | 2026-09-23T18:51:10.246Z | auto\n\n- Removed the file: skill-card.md\n- No user-facing or functional changes; documentation content and core interface remain unchanged.\n\nv2.4.3 | 2026-09-14T11:50:15.656Z | auto\n\nclauedebox 2.4.3 brings updated wrapper usage instructions and streamlines server and sibling command behavior.\n\n- Clarifies that `claudebox` should be called directly for interactive and one-shot use; avoids manual `docker run` construction.\n- Adds guidance for starting API/MCP servers and passing environment variables, emphasizing use of `CLAUDEBOX_ENV_*`.\n- Details sibling box invocation (e.g., `codexbox`, `pibox`), including wrapper coordination and state isolation.\n- Removes references to generic usage outside the wrapper; highlights security and installation best practices.\n- Removes the now-obsolete `skill-card.md` file for a cleaner skill package.\n\nv2.4.2 | 2026-09-14T00:14:17.534Z | auto\n\n- Updated invocation syntax for one-shot exec mode: now requires explicit -p flag (`claudebox -p \"prompt\"`).\n- SKILL.md and references/setup.md updated to clarify new usage.\n- Removed the obsolete skill-card.md file.\n- Minor copy edits and improved consistency in documentation.\n\nv2.4.1 | 2026-09-13T16:12:50.084Z | auto\n\n- Updated setup documentation in references/setup.md.\n- Removed skill-card.md file.\n- No changes to core functionality or public API.\n\nv2.4.0 | 2026-09-13T08:14:02.883Z | auto\n\nclauedbox 2.4.0\n\n- Removed the file `skill-card.md` from the project.\n- No changes to core functionality or user-facing features.\n- Documentation and skill logic remain unchanged.\n\nv2.3.12 | 2026-09-13T02:43:08.361Z | auto\n\n- Removed the file: `skill-card.md`\n- No user-facing feature changes or additions\n- Documentation and functional descriptions remain unchanged\n\nv2.3.11 | 2026-09-06T21:21:13.122Z | auto\n\n- Removed the file skill-card.md.\n- No user-facing functionality or documentation changes.\n\nv2.3.10 | 2026-09-04T15:32:44.200Z | auto\n\n- Removed the file skill-card.md.\n- No user-facing features or behavior changed.\n\nv2.3.9 | 2026-08-13T17:55:12.551Z | auto\n\n- Removed the skill-card.md file from the repository.\n- No changes were made to functionality or documentation in SKILL.md.\n\nv2.3.8 | 2026-08-09T15:26:19.753Z | auto\n\n- Removed the skill-card.md file.\n- No user-facing changes to core functionality or documentation in this release.\n\nv2.3.7 | 2026-08-01T21:44:43.066Z | auto\n\n- Removed redundant skill-card.md file for clarity and maintenance.\n- No functional or user-facing changes; all features and documentation remain unchanged.\n\nv2.3.6 | 2026-07-28T01:15:39.600Z | auto\n\n- Removed the file skill-card.md.\n- No user-facing feature changes. Documentation or metadata only.\n\nv2.3.3 | 2026-07-27T16:08:49.795Z | auto\n\nclauedbox 2.3.3\n\n- Removed the file: skill-card.md\n- No other changes to functionality or configuration\n- No visible impact to end users; update is limited to documentation cleanup\n\nv2.3.2 | 2026-07-27T14:34:56.772Z | auto\n\n- Removed the file skill-card.md.\n- No other functional or documentation changes in this release.\n\nv2.3.1 | 2026-07-26T13:20:17.679Z | auto\n\n- Removed the file: skill-card.md\n- No changes to functionality; this update cleans up project documentation by deleting an unused file.\n\nv2.3.0 | 2026-07-26T10:20:34.336Z | auto\n\n- Removed the file skill-card.md.\n- No user-facing feature or behavior changes.\n- Internal documentation or metadata only.\n\nv2.2.3 | 2026-07-26T03:36:43.345Z | auto\n\ncluedebox 2.2.3 changelog:\n\n- Updated security guidance: clarified that deleting workspace files is irreversible and recommended only deleting task-created files at the user's request.\n- No other feature or behavioral changes documented.\n\nv2.2.2 | 2026-07-26T02:39:22.171Z | auto\n\nclaudebox 2.2.2\n\n- Added explicit security and safety notes to documentation, emphasizing default authentication behavior, file deletion, and container access risks.\n- Clarified that if auth tokens are unset for API/MCP/Telegram, those surfaces are left unauthenticated.\n- Updated description to target installation, configuration, and scripting, rather than generic use as a coding task runner.\n- Improved setup references, with clearer install and configuration guidance in SKILL.md and references/setup.md.\n- Removed outdated `skill-card.md` file.\n\nv2.2.1 | 2026-07-25T23:39:14.081Z | auto\n\n- Removed the file skill-card.md.\n- No changes to functionality or features; documentation or metadata only.\n\nv2.2.0 | 2026-07-25T23:07:01.646Z | auto\n\ncluedebox 2.2.0 introduces detailed multi-surface documentation and clarifies usage recipes.\n\n- Expanded and clarified documentation for all 7 programmatic modes (interactive shell, exec, HTTP API, OpenAI adapter, MCP, Telegram, cron).\n- Added \"When To Use\" and \"When NOT To Use\" guidance, covering practical use cases and limitations.\n- Explained mode/flag environment variables, per-surface authentication, and common docker deployment considerations.\n- Outlined the security model and workspace/session isolation behavior for advanced use.\n- Provided concrete CLI/API examples and configuration snippets for every supported interface.\n\nArchive index:\n\nArchive v2.5.0: 4 files, 17693 bytes\n\nFiles: references/setup.md (15669b), skill-card.md (2250b), SKILL.md (26250b), _meta.json (128b)\n\nFile v2.5.0:SKILL.md\n\n---\nname: claudebox\ndescription: \"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\"\nhomepage: https://github.com/psyb0t/docker-claudebox\nuser-invocable: true\nmetadata:\n  { \"openclaw\": { \"emoji\": \"📦\", \"primaryEnv\": \"CLAUDEBOX_URL\", \"requires\": { \"bins\": [\"docker\", \"curl\"] } } }\n---\n\n# claudebox\n\nClaude Code — the agentic coding CLI from Anthropic — running in an isolated Docker container with dev tools, passwordless sudo, docker-in-docker, and `--permission-mode bypassPermissions` on by default. Built as a thin child image of `psyb0t/aicodebox`; every server-mode surface (API / OpenAI adapter / MCP / Telegram / Cron) is inherited from that base.\n\n## Agent execution\n\nUse `claudebox` when it is on `PATH`. Run it from the workspace the user\nnamed. Do not assemble a new `docker run` command for routine interactive or\none-shot work. The wrapper owns the workspace mount, `~/.claude`, SSH state,\nimage selection, and session lifecycle.\n\n```bash\nclaudebox                                      # interactive Claude Code\nclaudebox -p \"inspect this workspace\"          # one-shot work\nclaudebox -p \"emit events\" --output-format stream-json\nCLAUDEBOX_FULL=1 claudebox -p \"run the full suite\"\n```\n\nFor a wrapper-started server, prefix container variables with\n`CLAUDEBOX_ENV_`. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` passes\n`CLAUDEBOX_API_MODE=1` into the container. Bare `CLAUDEBOX_API_MODE` is not\nforwarded and does not start the server.\n\nStart a local API and MCP server only when the user asks for one. Authenticate\nClaude first, then use distinct bearer tokens for the two surfaces:\n\n```bash\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE_TOKEN=your-api-token \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token \\\nclaudebox\n```\n\nUse an HTTP or MCP endpoint only when the user asks for a service or provides\nan already-running remote URL. MCP plugins connect to a server. They do not\nreplace the local wrapper.\n\nIf `claudebox`, `codexbox`, and `pibox` were installed in the same command\ndirectory, a box can invoke a sibling command directly. The parent wrapper\npasses the real host paths and the sibling wrapper file. Do not set\n`AICODEBOX_HOST_*`, copy wrapper files, or manually mount another box's state\ndirectory. If the sibling command is absent, ask the user to install it or to\nchoose another approach.\n\n## Security & safety\n\n- **No auth when the per-mode token is unset.** `CLAUDEBOX_API_MODE_TOKEN` and `CLAUDEBOX_MCP_MODE_TOKEN` each default to no auth if unset — see [HTTP REST API mode](#http-rest-api-mode) and [MCP server mode](#mcp-server-mode) for details and the exact capability exposed unauthenticated in each case.\n- **File operations include removal.** Deleting a workspace file has no undo — only remove files the current task created, and only when the user asked.\n- **The standard wrapper mounts `/var/run/docker.sock`** so Claude can control the host Docker daemon. Server Compose examples omit it. See [Server modes (API / OpenAI / MCP / Telegram / Cron)](references/setup.md#server-modes-api--openai--mcp--telegram--cron), and do not use the wrapper for untrusted prompts.\n- **`--permission-mode bypassPermissions` is on by default** — Claude has full, unrestricted shell/file/docker access inside the container by design (see [When NOT To Use](#when-not-to-use)). Don't treat the container boundary as a sandbox for untrusted input unless you've isolated the container itself.\n- **Install script is piped from curl into bash by default** — a safer download-inspect-run alternative is documented alongside it; see [references/setup.md](references/setup.md#quick-install-cli-wrapper).\n\nThe image exposes interactive, command, HTTP, MCP, Telegram, and cron surfaces. The entrypoint selects one foreground mode, except that Telegram and cron run together. API mode takes precedence if it is set with another foreground mode:\n\n- **Interactive shell** — `claudebox` drops you into the native `claude` CLI, container-backed, with automatic session resumption.\n- **One-shot exec**: `claudebox -p \"prompt\" [flags]`, non-interactive, prompt in / structured output out, for scripts and CI.\n- **HTTP REST API** — `CLAUDEBOX_API_MODE=1`. `POST /run`, async runs polled via `GET /run/result?runId=`, `GET/PUT/DELETE /files/{path}`, workspace isolation.\n- **OpenAI-compatible endpoint** — same API-mode server, `/openai/v1/chat/completions` + `/openai/v1/models`. Streaming SSE, multi-turn, multimodal image input.\n- **MCP server** — `CLAUDEBOX_MCP_MODE=1`, 5 tools over streamable HTTP. Mounts at `/mcp/` on the API port when `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone as a sidecar process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), coexisting with Telegram/Cron/interactive mode.\n- **Telegram bot** — `CLAUDEBOX_TELEGRAM_MODE=1`, per-chat isolated workspaces, file/photo/video/voice ingestion, slash commands.\n- **Cron scheduler** — `CLAUDEBOX_CRON_MODE=1`, YAML-defined jobs on five or six field cron schedules with durable per-job artifacts.\n\nFor installation and configuration, see [references/setup.md](references/setup.md).\n\n## When To Use\n\n- Run Claude Code from a script, Makefile target, or CI pipeline without a TTY (`claudebox -p \"explain this diff\" --output-format json`).\n- Expose Claude Code as an HTTP backend other services can `POST /run` against, with workspace isolation for multi-tenant use.\n- Point an OpenAI SDK / LiteLLM at a self-hosted agentic backend instead of a plain model API — every completion runs the full Claude Code CLI (file I/O, shell, tools), not just text generation.\n- Let another MCP-aware agent, such as Claude Desktop, another Claude Code instance, or an agent framework, use this Claude Code instance as a tool over `/mcp/`.\n- Run Claude from Telegram to ask questions and share files from your phone.\n- Schedule recurring Claude jobs (nightly cleanup, hourly repo checks) with per-run history and optional Telegram result delivery.\n\n## When NOT To Use\n\n- Real-time token-by-token streaming for tool-calling or JSON-schema-constrained runs — the OpenAI adapter buffers those (computes the full answer, replays as one SSE burst). Only plain chat (no `tools`, no `response_format` schema) streams incrementally.\n- Multiple concurrent requests against the *same* workspace — API mode enforces one active Claude process per workspace and returns `409` on conflict. Use distinct `workspace` subpaths for parallel work.\n- Treating `--permission-mode bypassPermissions` as sandboxed-safe for untrusted input — Claude has full container access by design (shell, docker-in-docker, mounted SSH keys). Isolate the container itself if the input is untrusted.\n- Treating the MCP server as a sandbox. `run_prompt` has the same container authority as Claude, including mounted files and optional Docker access.\n\n## Interactive shell mode\n\nDrop-in replacement for the native `claude` command, container-backed:\n\n```bash\nclaudebox                  # interactive session, --continue applied automatically\nclaudebox --no-continue    # start a fresh session instead of resuming\nclaudebox --update         # opt in to a Claude Code CLI update this run\n```\n\nUtility commands pass through without entering interactive mode:\n\n```bash\nclaudebox --version         # claude CLI version\nclaudebox doctor            # health checks\nclaudebox auth              # manage authentication\nclaudebox mcp <args...>     # manage MCP servers, e.g. `claudebox mcp list`\nclaudebox setup-token       # interactive OAuth token setup\nclaudebox stop              # stop the running interactive container for this workspace\nclaudebox clear-session     # delete session history for this workspace\n```\n\nNo mode flag needed — this is the default when you run `claudebox` with no `CLAUDEBOX_*_MODE` env vars set. Auth: `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN` (see [Auth](#auth)).\n\n## One-shot exec mode\n\nNon-interactive prompt-in/response-out. Pass `-p` for scripts, CI, cron, or\nanywhere without a TTY:\n\n```bash\nclaudebox -p \"explain this codebase\"                                       # plain text (default)\nclaudebox -p \"explain this codebase\" --output-format json                  # structured JSON\nclaudebox -p \"list all TODOs\" --output-format stream-json | jq .           # complete native NDJSON\nclaudebox -p \"explain this codebase\" --model opus                          # pick a model\nclaudebox -p \"review this\" --system-prompt \"You are a security auditor\"    # replace system prompt\nclaudebox -p \"review this\" --append-system-prompt \"Focus on SQL injection\" # append to system prompt\nclaudebox -p \"debug this\" --effort max                                     # max reasoning effort\nclaudebox -p \"start over\" --no-continue                                    # fresh session\nclaudebox -p \"keep going\" --resume abc123-def456                           # resume a specific session\n\n# JSON-schema-constrained output\nclaudebox -p \"extract the author and title\" --output-format json \\\n  --json-schema '{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\"]}'\n```\n\n`--continue` is applied automatically so successive runs in the same workspace\nshare context. Use `--no-continue` for a clean slate or `--resume <session_id>`\nfor a specific one. Model aliases: `haiku`, `sonnet`, `opus`, `opusplan`,\n`sonnet[1m]`. The wrapper requires `-p` to select this mode.\n\n## HTTP REST API mode\n\n`CLAUDEBOX_API_MODE=1` starts a long-lived FastAPI server (default port `8080`, `CLAUDEBOX_API_MODE_PORT` to override). Bearer auth via `CLAUDEBOX_API_MODE_TOKEN` (unset = no auth).\n\nWith `CLAUDEBOX_API_MODE_TOKEN` unset the API surface is unauthenticated — anyone who can reach it gets full `/run` (arbitrary-prompt agentic execution) and `/files` (read/write anywhere under `/workspace`) access. Set the token and bind to loopback / behind an authenticating proxy before exposing it beyond localhost.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_API_MODE_TOKEN=your-secret-token\n  - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan  # optional — overrides the adapter's built-in default list\n```\n\n```bash\ncurl -X POST http://localhost:8080/run \\\n  -H \"Authorization: Bearer your-secret-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"what does this repo do\", \"workspace\": \"myproject\"}'\n```\n\nKey `/run` body fields: `prompt` (required), `workspace` (subpath under `/workspace`), `model`, `systemPrompt`, `appendSystemPrompt`, `jsonSchema`, `eventMode`, `outputFormat` (legacy), `noContinue`, `resume`, `fireAndForget`, `async`, `includeRaw` (raw stdout/stderr), `extraArgs`, `toolsAllowlist`, `noTools`, and `timeoutSeconds`. The Claude adapter always requests complete native records. Use `\"eventMode\": \"full\"` to return them in the stable `{sequence, attempt, backend, eventType, event}` envelope. `thinking` maps `low`, `medium`, `high`, `xhigh`, and `max` to Claude Code's `--effort` flag. `off` and `none` keep Claude Code's default. Every response carries a `runId`. Returns `409` if the target workspace is already busy.\n\n**Async runs** — `\"async\": true` returns immediately with a `runId`; poll it:\n\n```bash\ncurl -X POST http://localhost:8080/run -H \"Authorization: Bearer token\" -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"refactor this codebase\", \"workspace\": \"myproject\", \"async\": true}'\n# → {\"runId\": \"abc123\", \"workspace\": \"/workspace/myproject\", \"status\": \"running\"}\n\ncurl \"http://localhost:8080/run/result?runId=abc123\" -H \"Authorization: Bearer token\"\n# running → {\"runId\":..., \"status\": \"running\"}; completed → full result JSON (then purged from cache)\n```\n\nCompleted/failed/cancelled results are returned once then purged; unread results expire after 6 hours. `GET /run/result?runId=X` 404s on unknown/already-read/expired IDs.\n\n**File operations** — all paths relative to `/workspace`, path traversal blocked with `400`:\n\n```bash\ncurl \"http://localhost:8080/files\" -H \"Authorization: Bearer token\"                          # list root\ncurl \"http://localhost:8080/files/myproject/src\" -H \"Authorization: Bearer token\"            # list dir\ncurl \"http://localhost:8080/files/myproject/src/main.py\" -H \"Authorization: Bearer token\"    # download\ncurl -X PUT \"http://localhost:8080/files/myproject/src/main.py\" -H \"Authorization: Bearer token\" --data-binary @main.py\ncurl -X DELETE \"http://localhost:8080/files/myproject/src/old.py\" -H \"Authorization: Bearer token\"\n```\n\n`DELETE /files/{path}` removes a file under `/workspace` (no undo). Confirm the target path first, only remove files the current task created, and on a shared instance don't touch another caller's workspace — see [Security & safety](#security--safety).\n\n**Introspection and lifecycle:**\n\n```bash\ncurl http://localhost:8080/healthz                                                          # {\"ok\": true, \"adapter\": \"claude\"} — no auth\ncurl http://localhost:8080/status -H \"Authorization: Bearer token\"                           # {busyWorkspaces, runs}\ncurl -X DELETE \"http://localhost:8080/run/abc123\" -H \"Authorization: Bearer token\"            # cancel a run by id\n```\n\n## OpenAI-compatible endpoint mode\n\nSame API-mode server (`CLAUDEBOX_API_MODE=1`); no separate flag. `chat/completions`-shaped adapter for LiteLLM, OpenAI SDKs, or any client speaking that wire format. Every request runs the full agentic CLI, not just text generation — Claude can read/write files and run shell commands as part of answering.\n\n```bash\ncurl http://localhost:8080/openai/v1/models\n# {\"object\":\"list\",\"data\":[{\"id\":\"haiku\",...},{\"id\":\"sonnet\",...},{\"id\":\"opus\",...},{\"id\":\"opusplan\",...}]}\n\ncurl -X POST http://localhost:8080/openai/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"haiku\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}]}'\n\n# streaming\ncurl -X POST http://localhost:8080/openai/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"haiku\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}],\"stream\":true}'\n```\n\nModel aliases match the CLI (`haiku`/`sonnet`/`opus`/`opusplan`); provider prefixes are stripped (`claudebox/haiku` → `haiku`). `role: \"system\"` messages become `--system-prompt`. Single-user-message requests are the fast path (sent directly as the prompt); multi-turn conversations are serialized to a JSON file under `_oai_uploads/` in the workspace so Claude Code can read the full history. Multimodal `image_url` content (data URLs or `http(s)://`) is downloaded/decoded to the workspace and referenced by path.\n\nFor every native Claude record in an OpenAI stream, send\n`\"stream_options\": {\"include_aicodebox_events\": true}`. Claudebox emits a\nnamed `aicodebox.native` SSE event before normal OpenAI chunks. Its payload is\n`{sequence, attempt, backend, eventType, event}`. Standard chunks remain\nunchanged, so the extension stays opt-in for strict OpenAI SSE clients.\n\n`temperature` and `max_tokens` are accepted for OpenAI-client compatibility but have no effect on this adapter. `reasoning_effort` maps to the `claude --effort` flag: `low`, `medium`, `high`, `xhigh`, and `max` pass through, `minimal` maps to `low`, `none` or `off` keeps the default, and any other value is rejected. The `thinking` field on `/run` and MCP `run_prompt` works the same way.\n\n**Tool calling and structured output are supported, not ignored** — `tools`/`tool_choice` engage a client-executed function-calling bridge (Claude Code acts as a pure function-calling model, emits `tool_calls` for the *client* to run), and `response_format` (`json_object` or `json_schema`) constrains the final answer turn. Both can combine in one request. Because a tool call or schema-checked answer only exists once the full response is computed, `stream:true` combined with `tools` or a schema `response_format` returns a **buffered** single-shot SSE stream instead of token-incremental deltas — only plain chat (no tools, no schema) streams token-by-token.\n\nCustom headers for claudebox-specific behavior (canonical `x-aicodebox-*`, with legacy `X-Claude-*` aliases still accepted):\n\n| Header | Description |\n| --- | --- |\n| `x-aicodebox-workspace` (`X-Claude-Workspace`) | Workspace subpath under `/workspace` |\n| `x-aicodebox-continue` (`X-Claude-Continue`) | `1`/`true`/`yes` to continue the previous session |\n| `x-aicodebox-append-system-prompt` (`X-Claude-Append-System-Prompt`) | Text appended to the system prompt |\n| `x-aicodebox-json-schema` | JSON-schema string — fallback for clients that can't set `response_format` in the body (body field wins if both are set) |\n| `x-aicodebox-resume` | Resume a specific session id |\n| `x-aicodebox-tools-allowlist` | CSV or JSON array restricting Claude Code's own internal tools |\n| `x-aicodebox-no-tools` | Disable Claude Code's own internal tools (auto-defaulted on when in client tool-calling mode) |\n\nLiteLLM example:\n\n```python\nimport litellm\n\nresponse = litellm.completion(\n    model=\"claudebox/haiku\",\n    messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n    api_base=\"http://localhost:8080/openai/v1\",\n    api_key=\"your-secret-token\",  # any string if no API token is configured\n)\nprint(response.choices[0].message.content)\n```\n\n## MCP server mode\n\n`CLAUDEBOX_MCP_MODE=1` exposes a [Model Context Protocol](https://modelcontextprotocol.io/) server over streamable HTTP, using `CLAUDEBOX_MCP_MODE_TOKEN` as its bearer token (independent of the API token, no fallback; empty/unset = no auth). Where it listens depends on whether API mode is also on:\n\nWith `CLAUDEBOX_MCP_MODE_TOKEN` unset the MCP surface is unauthenticated — anyone who can reach it gets full tool access (run prompts, read/write/remove files under `/workspace`). Set the token and bind to loopback / behind an authenticating proxy before exposing it beyond localhost.\n\n- **`CLAUDEBOX_API_MODE=1` + `CLAUDEBOX_MCP_MODE=1`** (the setup the rest of the README documents) — MCP mounts at `/mcp/` on the API port, no extra process.\n- **`CLAUDEBOX_MCP_MODE=1` alone** (or combined with Telegram/Cron/interactive mode) — MCP runs as an independent background process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), serving at the port root, not under `/mcp`.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_MCP_MODE=1\n  - CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"claudebox\": {\n      \"url\": \"http://localhost:8080/mcp/\",\n      \"headers\": { \"Authorization\": \"Bearer your-mcp-token\" }\n    }\n  }\n}\n```\n\nClients that can't set headers can pass the token as a query param instead: `http://localhost:8080/mcp/?apiToken=your-mcp-token`. Wire it into Claude Code directly:\n\n```bash\nclaude mcp add --transport http claudebox http://localhost:8080/mcp/ \\\n  --header \"Authorization: Bearer your-mcp-token\"\n```\n\n**Available tools:**\n\n| Tool | Description |\n| --- | --- |\n| `run_prompt` | Run a prompt through Claude Code. Args: `prompt`, `workspace`, `model`, `system_prompt`, `append_system_prompt`, `no_continue` (default `true`), `resume`, `thinking` (`low`, `medium`, `high`, `xhigh`, and `max` map to Claude Code effort), `json_schema`. Returns the assistant's text. |\n| `list_files` | List files/dirs under a workspace path. |\n| `read_file` | Read a file's text content. |\n| `write_file` | Write content to a file (creates parent dirs). |\n| `delete_file` | Delete a file (refuses directories). |\n\n`delete_file` removes a file under `/workspace` (no undo). Confirm the target path first and only remove files the current task created — see [Security & safety](#security--safety).\n\nRaw JSON-RPC for debugging (streamable-HTTP handshake — `initialize` then reuse the returned `mcp-session-id`):\n\n```bash\ncurl -s -D - -X POST \"http://localhost:8080/mcp/\" \\\n  -H \"Authorization: Bearer your-mcp-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"debug\",\"version\":\"1\"}}}'\n# capture the mcp-session-id response header, then:\ncurl -s -X POST \"http://localhost:8080/mcp/\" \\\n  -H \"Authorization: Bearer your-mcp-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -H \"mcp-session-id: <session-id-from-above>\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}'\n```\n\n## Telegram bot mode\n\n`CLAUDEBOX_TELEGRAM_MODE=1` runs a conversational bot with per-chat isolated workspaces. Configure an explicit allowlist before exposing the bot. When `telegram.yml` is absent and `TELEGRAM_CHAT_ID` is unset, the compatibility fallback permits every chat.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_TELEGRAM_MODE=1\n  - CLAUDEBOX_TELEGRAM_MODE_TOKEN=123456:ABC-DEF   # from @BotFather\n```\n\n`$HOME/.aicodebox/telegram.yml` (mounted into the container):\n\n```yaml\nallowed_chats:\n  - 123456789    # your DM (positive = user id)\n  - -987654321   # a group chat (negative)\n\ndefault:\n  model: sonnet\n  effort: high\n  continue: true\n\nchats:\n  123456789:\n    workspace: my-project\n    model: opus\n    system_prompt: \"You are a senior engineer\"\n```\n\nPer-chat settings: `workspace`, `model`, `effort`, `continue`, `system_prompt`, `append_system_prompt`, and `allowed_users` for a group-chat allowlist.\n\nBot commands: any text message is a prompt; sending a file/photo/video/voice saves it to the workspace (caption becomes the prompt); `/model [name]`, `/effort [level]`, `/system_prompt [text]`, `/append_system_prompt [text]`, `/fetch <path>`, `/cancel`, `/status`, `/config`, `/reload`. Claude sends files back with `[SEND_FILE: relative/path]` in its response text.\n\n`effort` (config field and `/effort` command) is passed to the `claude` CLI as `--effort`. `off` keeps Claude Code's default effort.\n\n## Cron scheduler mode\n\n`CLAUDEBOX_CRON_MODE=1` runs YAML-defined Claude jobs on cron schedules. Five fields give minute resolution and six fields give second resolution. `docker logs` shows every tick.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_CRON_MODE=1\n  - CLAUDEBOX_CRON_MODE_FILE=/home/aicode/.aicodebox/cron.yaml\n  - CLAUDEBOX_WORKSPACE=/workspace\n```\n\n`cron.yaml`:\n\n```yaml\nmodel: haiku                       # default for all jobs; per-job \"model\" overrides\njobs:\n  - name: hourly_repo_check\n    schedule: \"0 * * * *\"          # 5-field standard cron\n    instruction: |\n      Look at the git log for the last hour. Summarize commits.\n  - name: every_30_seconds\n    schedule: \"*/30 * * * * *\"     # 6-field sub-minute\n    instruction: Write the current UTC timestamp to ./status.txt.\n```\n\nRoot defaults and per-job overrides support `model`, `effort`, `thinking`, `system_prompt`, `append_system_prompt`, and `telegram_chat_id`. A job also supports `workspace` and `no_continue`. `telegram_chat_id` requires `CLAUDEBOX_TELEGRAM_MODE_TOKEN`; set it to `0` in a job to disable a root default. `{system_datetime}` and `{job_name}` work in `instruction`, `system_prompt`, and `append_system_prompt`. Claude maps `effort` and `thinking` to its `--effort` flag.\n\nEach run writes `meta.json`, `stdout.log`, `stderr.log`, and `result.txt` under `$HOME/.aicodebox/cron/history/<workspace-slug>/<YYYYMMDD-HHMMSS>-<job-name>/`. The scheduler appends a summary to `$HOME/.aicodebox/cron/<job-name>.jsonl`. Set `CLAUDEBOX_CRON_MODE_HISTORY_DIR` to change the whole cron state root. Same-name overlaps are skipped. Combine with `CLAUDEBOX_TELEGRAM_MODE=1` to post results and reply to a finished run. See [references/setup.md](references/setup.md#cron--telegram-combined-mode).\n\n## Auth\n\nInteractive/exec/cron/CLI-driven modes need an Anthropic credential:\n\n```bash\nclaudebox setup-token                                        # interactive OAuth setup, one-time\nCLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN> claudebox -p \"do stuff\" # then reuse the token\n# or\nANTHROPIC_API_KEY=<YOUR_API_KEY> claudebox -p \"do stuff\"\n```\n\nServer modes gate their own HTTP surface independently, each with its own bearer token (unset = open):\n\n| Mode | Token var |\n| --- | --- |\n| API / OpenAI adapter | `CLAUDEBOX_API_MODE_TOKEN` |\n| MCP | `CLAUDEBOX_MCP_MODE_TOKEN` (separate from the API token, no fallback) |\n| Telegram | `CLAUDEBOX_TELEGRAM_MODE_TOKEN` (the bot token itself, not a bearer secret) |\n\nAll of these still need the underlying Anthropic credential (`CLAUDE_CODE_OAUTH_TOKEN` / `ANTHROPIC_API_KEY`) set in the container env to actually talk to the model.\n\n## Typical Workflows\n\n### Pipe a code review through CI\n\n```bash\nclaudebox -p \"review this diff for security issues\" --output-format json --model sonnet | jq -r .result\n```\n\n### Drive claudebox from another agent over MCP\n\n```bash\nclaude mcp add --transport http claudebox http://localhost:8080/mcp/ \\\n  --header \"Authorization: Bearer $CLAUDEBOX_MCP_MODE_TOKEN\"\n```\n\n### Fire-and-poll a long refactor over HTTP\n\n```bash\nRUN_ID=$(curl -s -X POST http://localhost:8080/run -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"refactor the auth module\", \"workspace\": \"myproject\", \"async\": true}' | jq -r .runId)\n\nuntil curl -s \"http://localhost:8080/run/result?runId=$RUN_ID\" -H \"Authorization: Bearer $TOKEN\" | jq -e '.status != \"running\"' >/dev/null; do\n  sleep 5\ndone\ncurl -s \"http://localhost:8080/run/result?runId=$RUN_ID\" -H \"Authorization: Bearer $TOKEN\" | jq\n```\n\n### Point LiteLLM at claudebox as an OpenAI-compatible backend\n\n```python\nimport litellm\nlitellm.completion(model=\"claudebox/sonnet\", messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n                    api_base=\"http://localhost:8080/openai/v1\", api_key=API_TOKEN)\n```\n\n### Nightly cleanup job with Telegram notification\n\n```yaml\ntelegram_chat_id: -1001234567890\njobs:\n  - name: nightly_cleanup\n    schedule: \"0 3 * * *\"\n    instruction: Find files older than 7 days under ./tmp and delete them. Report what you removed.\n```\n\nFor install steps, docker run/compose invocations, the full env-var reference, port list, and container management commands, see [references/setup.md](references/setup.md).\n\nFile v2.5.0:_meta.json\n\n{\n  \"ownerId\": \"kn79dhvmpjng4rp2jjk8k0v5xx80ccbk\",\n  \"slug\": \"claudebox\",\n  \"version\": \"2.5.0\",\n  \"publishedAt\": 1791393621602\n}\n\nFile v2.5.0:references/setup.md\n\n# claudebox setup\n\n## Requirements\n\n- Docker installed and running. That's it — the wrapper handles the rest.\n- An Anthropic credential: `CLAUDE_CODE_OAUTH_TOKEN` (via `claudebox setup-token`) or `ANTHROPIC_API_KEY`.\n\nFor ordinary agent work, use the installed `claudebox` command from the target\nworkspace. Do not replace it with a hand-written Docker invocation. The\nwrapper handles the workspace, state, SSH, image, and nested launch context.\n\n## Quick Install (CLI wrapper)\n\nSafer path — download, inspect, then run:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh -o install.sh\nless install.sh   # read it before running anything you downloaded\nbash install.sh\n\n# full image variant\nexport CLAUDEBOX_FULL=1 && bash install.sh\n\n# custom binary name\nbash install.sh claude\n```\n\nDownloading and reading the script before running it is the recommended flow, especially in an agent-driven or CI context — it runs with your privileges.\n\nThe installer pulls the image, generates an ed25519 SSH key at `~/.ssh/claudebox/id_ed25519` for git operations inside the container, creates `~/.claude`, and installs the wrapper to `/usr/local/bin/claudebox` (override with `CLAUDEBOX_INSTALL_DIR` / `CLAUDEBOX_BIN_NAME`). Add the generated public key to GitHub/GitLab for git push/pull to work from inside the container.\n\n```bash\nclaudebox                                  # interactive\nclaudebox -p \"inspect this workspace\"      # one-shot\nCLAUDEBOX_FULL=1 claudebox -p \"run tests\"  # temporary full image\n```\n\nFor a wrapper-started server, use `CLAUDEBOX_ENV_` before every variable that\nmust reach the container. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` starts API mode.\n\nInstall `claudebox`, `codexbox`, and `pibox` in the same command directory,\nnormally `/usr/local/bin`, when one box needs to launch another. The parent\nmounts only sibling wrapper files read-only. A sibling wrapper then runs through\nthe host Docker daemon and mounts its own host data directory.\n\nManual setup without piping to bash: `mkdir -p ~/.claude`, generate the SSH key yourself, `docker pull psyb0t/claudebox:latest` (or `:latest-full`), then fetch `wrapper.sh` and install it as your `claudebox` binary.\n\n## Image Variants\n\n| | `psyb0t/claudebox:latest` (minimal, default) | `psyb0t/claudebox:latest-full` |\n| --- | --- | --- |\n| Base | Ubuntu 24.04, git/curl/wget/jq, Node.js 24 LTS, Python 3.14 + uv, Docker CE | same, plus everything below |\n| Go | — | 1.26 toolchain (golangci-lint, gopls, delve, staticcheck, gofumpt, gotests, impl, gomodifytags) |\n| Python | — | 3.14 via pyenv (flake8, black, isort, pyright, mypy, vulture, pytest, poetry, pipenv) |\n| Node dev tools | — | eslint, prettier, typescript, yarn, pnpm, framework CLIs |\n| C/C++ | — | gcc, g++, make, cmake, clang-format, valgrind, gdb |\n| DevOps | — | terraform, kubectl, helm, gh |\n| DB clients | — | sqlite3, psql, mysql, redis-cli |\n| Shell utils | — | ripgrep, bat, exa, fd-find, ag, htop, tmux, shellcheck, shfmt |\n\nMinimal has passwordless sudo, so Claude installs whatever else it needs via `apt-get`/`pip`/`npm` on the fly — smaller pull, slower first task. Use `/aicodebox-init.d/*.sh` hooks to pre-install tooling on first container create instead of burning tokens on package management.\n\n`CLAUDEBOX_FULL=1` at install time bakes the full-variant choice into the wrapper permanently; at runtime it overrides per-invocation. Pre-v2 `CLAUDEBOX_MINIMAL=1` is a no-op (minimal is already the default).\n\n## docker run / docker-compose\n\n### Interactive / exec (via the wrapper — recommended)\n\nThe installed `claudebox` wrapper handles container naming, volume mounts, SSH key mounting, and auth forwarding automatically. Don't hand-roll `docker run` for interactive/exec use — install the wrapper instead (see Quick Install above).\n\n### Server modes (API / OpenAI / MCP / Telegram / Cron)\n\n```yaml\n# docker-compose.yml\nservices:\n  claudebox:\n    image: psyb0t/claudebox:latest\n    init: true\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:8080:8080\"\n    environment:\n      - CLAUDEBOX_API_MODE=1\n      - CLAUDEBOX_API_MODE_TOKEN=${CLAUDEBOX_API_MODE_TOKEN:?set this in .env}\n      - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan\n      - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:?set this in .env}\n    volumes:\n      - ./claude-state:/home/aicode/.aicodebox\n      - /your/projects:/workspace\n    mem_limit: 2g\n    cpus: 2\n    pids_limit: 512\n    logging:\n      driver: local\n      options:\n        max-size: 10m\n        max-file: \"3\"\n```\n\nThis server example intentionally omits `/var/run/docker.sock`. That socket grants the container control over every host container. Add it only for a trusted workload that requires host Docker access.\n\nAdd `CLAUDEBOX_MCP_MODE=1` and `CLAUDEBOX_MCP_MODE_TOKEN` alongside `CLAUDEBOX_API_MODE=1` to mount MCP on the same port. API mode takes precedence over Telegram and cron if more than one foreground mode is set. Telegram and cron are the only foreground pair that run together.\n\n## Runtime boundaries\n\nSet Docker memory, CPU, PID, and log limits for long running containers. This image installs Claude Code during first start and changes identity during boot, so `read_only: true` and `cap_drop: [ALL]` are not safe copy-paste defaults. Test the exact image and startup path before adding them.\n\n## Environment Variable Reference\n\nAll wrapper/installer config uses the `CLAUDEBOX_*` prefix; the entrypoint aliases each to `AICODEBOX_*` (the base image's canonical names) when the target is unset — `AICODEBOX_*` wins if both are set. Legacy pre-v2 `CLAUDE_*` / `CLAUDE_MODE_*` names still work as fallbacks.\n\n### Wrapper / installer\n\n| Variable | Description | Default |\n| --- | --- | --- |\n| `CLAUDEBOX_GIT_NAME` / `CLAUDEBOX_GIT_EMAIL` | Git identity inside the container | _(none)_ |\n| `CLAUDEBOX_DATA_DIR` | Host path for the `.claude` data dir | `~/.claude` |\n| `CLAUDEBOX_SSH_DIR` | Host path for the SSH key directory | `~/.ssh/claudebox` |\n| `CLAUDEBOX_INSTALL_DIR` | Wrapper binary install location (install-time) | `/usr/local/bin` |\n| `CLAUDEBOX_BIN_NAME` | Wrapper binary name (install-time) | `claudebox` |\n| `CLAUDEBOX_IMAGE` | Override the Docker image | `psyb0t/claudebox:latest` |\n| `CLAUDEBOX_FULL` | Use the `latest-full` toolchain image instead of minimal | _(none)_ |\n| `CLAUDEBOX_CONTAINER_NAME` | Override the per-workspace container name | derived from `$PWD` |\n| `CLAUDEBOX_MAX_MEM` | Per-container memory limit | `10g` |\n| `CLAUDEBOX_ENV_*` | Forward arbitrary vars into the container (prefix stripped) | _(none)_ |\n| `CLAUDEBOX_MOUNT_*` | Mount extra host directories | _(none)_ |\n\nAuth/in-container settings route through `CLAUDEBOX_ENV_*`:\n\n```bash\nCLAUDEBOX_ENV_ANTHROPIC_API_KEY=your-api-key claudebox -p \"do stuff\"\nCLAUDEBOX_ENV_CLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN> claudebox -p \"do stuff\"\nCLAUDEBOX_ENV_DEBUG=true claudebox -p \"do stuff\"          # structured JSON debug logging\n```\n\nExtra mounts:\n\n```bash\nCLAUDEBOX_MOUNT_DATA=/data claudebox -p \"process the data\"                   # same path both sides\nCLAUDEBOX_MOUNT_1=/opt/configs CLAUDEBOX_MOUNT_2=/var/logs claudebox -p \"go\" # multiple mounts\nCLAUDEBOX_MOUNT_STUFF=/host/path:/container/path claudebox -p \"do stuff\"     # explicit src:dst\nCLAUDEBOX_MOUNT_RO=/data:/data:ro claudebox -p \"read the data\"               # read-only\n```\n\n### Server modes\n\n| Variable | Description | Default |\n| --- | --- | --- |\n| `CLAUDEBOX_API_MODE` | `1` to start the HTTP API server | _(none)_ |\n| `CLAUDEBOX_API_MODE_PORT` | API server port | `8080` |\n| `CLAUDEBOX_API_MODE_TOKEN` | Bearer token for `/run`, `/files`, `/status`, `/openai/*` | _(none — no auth)_ |\n| `CLAUDEBOX_AVAILABLE_MODELS` | CSV of model aliases surfaced at `/openai/v1/models`. Optional — claudebox's adapter has a built-in default (`haiku,sonnet,opus,opusplan`); set this to override it. The API server only refuses to boot if the resolved list ends up empty. | _(none — adapter default applies)_ |\n| `CLAUDEBOX_AVAILABLE_EFFORTS` | CSV of effort levels surfaced to Telegram `/effort` picker | adapter default |\n| `CLAUDEBOX_MCP_MODE` | `1` to expose MCP. Mounts at `/mcp/` on the API port if `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone on its own port | _(none)_ |\n| `CLAUDEBOX_MCP_MODE_PORT` | Port for the standalone MCP process (only used when API mode is off) | `8081` |\n| `CLAUDEBOX_MCP_MODE_TOKEN` | Bearer token for MCP (independent of the API token, no fallback) | _(none — no auth)_ |\n| `CLAUDEBOX_MCP_MODE_ALLOWED_HOSTS` | Comma-separated MCP `Host` allowlist. Add each reverse-proxy host name. | loopback hosts |\n| `CLAUDEBOX_MCP_MODE_ALLOWED_ORIGINS` | Comma-separated MCP browser Origin allowlist. Add each reverse-proxy origin. | loopback HTTP origins |\n| `CLAUDEBOX_TELEGRAM_MODE` | `1` to start the Telegram bot | _(none)_ |\n| `CLAUDEBOX_TELEGRAM_MODE_TOKEN` | Bot token from [@BotFather](https://t.me/BotFather) | _(none)_ |\n| `CLAUDEBOX_TELEGRAM_MODE_CONFIG` | Path to `telegram.yml` inside the container | `/home/aicode/.aicodebox/telegram.yml` |\n| `CLAUDEBOX_CRON_MODE` | `1` to start the cron scheduler | _(none)_ |\n| `CLAUDEBOX_CRON_MODE_FILE` | Path to the cron YAML inside the container | _(none)_ |\n| `CLAUDEBOX_CRON_MODE_HISTORY_DIR` | Cron state root for artifacts, summaries, and Telegram reply metadata | `/home/aicode/.aicodebox/cron` |\n| `CLAUDEBOX_WORKSPACE` | Absolute workspace path (cwd for every mode) | `/workspace` |\n| `CLAUDEBOX_ALWAYS_SKILLS_DIR` | Where `SKILL.md` files are scanned for always-active injection | `/home/aicode/.claude/.always-skills` |\n| `CLAUDEBOX_SYSTEM_HINT_FILE` | Text prepended to `--append-system-prompt` on every call | `/home/aicode/.claude/system-hint.txt` |\n| `DEBUG` | `1`/`true` for structured JSON debug logging | _(none)_ |\n\nLegacy fallbacks still accepted: the v1 `CLAUDEBOX_MODE_API`/`CLAUDEBOX_MODE_API_PORT`/`CLAUDEBOX_MODE_API_TOKEN`, `CLAUDEBOX_MODE_TELEGRAM`, `CLAUDEBOX_MODE_CRON`/`CLAUDEBOX_MODE_CRON_FILE`, and the older `CLAUDE_MODE_API`/`CLAUDE_MODE_API_PORT`/`CLAUDE_MODE_API_TOKEN`, `CLAUDE_MODE_TELEGRAM`, `CLAUDE_MODE_CRON`/`CLAUDE_MODE_CRON_FILE`, `CLAUDE_WORKSPACE`, `CLAUDE_TELEGRAM_BOT_TOKEN`, `CLAUDE_TELEGRAM_CONFIG`. A canonical `CLAUDEBOX_*` name wins over its legacy spelling.\n\n## Ports\n\n| Port | Service |\n| --- | --- |\n| 8080 (default, `CLAUDEBOX_API_MODE_PORT`) | HTTP API + OpenAI adapter, and MCP (`/mcp/`) if `CLAUDEBOX_MCP_MODE=1` is also set |\n| 8081 (default, `CLAUDEBOX_MCP_MODE_PORT`) | Standalone MCP at `/`, only when `CLAUDEBOX_MCP_MODE=1` is set without `CLAUDEBOX_API_MODE=1` |\n\nMCP either mounts onto the API port or runs on its own port — never both at once, depending on whether API mode is also enabled. Loopback hosts work by default. A proxy or public endpoint must set the exact `CLAUDEBOX_MCP_MODE_ALLOWED_HOSTS` and browser `CLAUDEBOX_MCP_MODE_ALLOWED_ORIGINS` values it sends.\n\n## Cron + Telegram Combined Mode\n\nSet both `CLAUDEBOX_CRON_MODE=1` and `CLAUDEBOX_TELEGRAM_MODE=1` in the same container: a single workspace shared between the cron scheduler (background) and the bot (foreground); when the bot exits, the scheduler is killed too.\n\n- Cron jobs post results to Telegram automatically when `telegram_chat_id` is set (root default and/or per-job override) in `cron.yaml`.\n- Reply to a cron notification message to interrogate that run — the bot detects the reply, looks up the original job (name, timestamp, instruction, result), and prepends that context to a fresh session.\n\nOnly a reply to a cron notification receives that recorded job context. Ordinary Telegram messages do not receive cron history.\n\nSent message IDs and job context are stored in `$HOME/.aicodebox/cron/telegram_messages.json` and are automatically pruned to the last 200 entries.\n\n## MCP Servers claudebox Itself Can Use\n\nIndependent of exposing claudebox *as* an MCP server (MCP mode above), Claude Code running inside claudebox can also *consume* MCP servers you configure — same mechanism as any Claude Code install:\n\n| Scope | Path | Notes |\n| --- | --- | --- |\n| Project | `<workspace>/.mcp.json` | Checked into git, shared by the team |\n| User | `~/.claude.json` under `mcpServers` | Global, every project on the host |\n| Local | `~/.claude.json` per-project section | Default scope of `claude mcp add` |\n\n```bash\nclaudebox mcp add --scope project my-server -- npx -y @some/mcp-server\nclaudebox mcp add --scope user my-server -- npx -y @some/mcp-server\n```\n\nRun `/mcp` inside an interactive session to inspect what's loaded. This is how cron and Telegram modes reach external systems (post to Discord/Slack/email/webhooks) — configure the server, reference it from the job instruction or chat.\n\n## Customization\n\n- **Custom scripts (`~/.aicodebox/bin`)**: any executable placed here is on PATH ahead of everything else, in every mode, in init scripts and in `docker exec` shells. With the `claudebox` wrapper this is your host `~/.claude/bin`: the wrapper mounts `~/.claude` and the entrypoint points `~/.aicodebox` at it. A compose setup that mounts its own directory at `/home/aicode/.aicodebox` uses that directory's `bin/` instead.\n- **Init hooks (`~/.aicodebox/init.d/*.sh`)**: run once per container, the first time it starts, after the image's own `/aicodebox-init.d/` scripts. They run in filename order as `aicode`, which has passwordless sudo, so `sudo apt-get install …` works for pre-installing tools on the minimal image. A restart does not run them again; a new container does. A failing script is logged and the rest still run. With the wrapper this is your host `~/.claude/init.d`.\n- **Always-active skills (`~/.claude/.always-skills/`)**: every `SKILL.md` found (recursive, alphabetical) is appended to `--append-system-prompt` on every invocation, across all modes, prefixed with `[Skill file: <path>]`.\n\n## Gotchas\n\n- `--permission-mode bypassPermissions` is the default — Claude has full, unrestricted access to the container. Override per-request via `RunRequest.extra_args` at the API layer.\n- SSH keys are mounted from the host for git push/pull. Don't share your container or image with untrusted parties.\n- Host paths are preserved — a project at `/home/you/project` mounts at the same path inside the container, so Docker volume mounts Claude creates from within it resolve correctly against the host.\n- UID/GID of the `aicode` user auto-adjusts to match the host directory owner at startup.\n- Wrapper-started interactive and programmatic containers mount the Docker socket by design. The server Compose example above deliberately does not.\n- Two containers per workspace: `claude-<path>` for interactive (TTY), `claude-<path>_prog` for one-shot exec (no TTY). Both share mounted volumes and data.\n- API-mode workspace busy tracking: one active Claude process per workspace; concurrent requests to the same workspace get `409`.\n- If `telegram.yml` is absent, `TELEGRAM_CHAT_ID` becomes the only allowed chat. If both are absent, the compatibility fallback permits every chat. Use an explicit allowlist before exposing the bot.\n- Claude Code CLI auto-updates are disabled inside the container by default; opt in with `claudebox --update`.\n\n## Management\n\n```bash\ndocker logs -f <container>       # tail logs (structured JSON in server modes)\nclaudebox stop                   # stop the interactive container for this workspace\nclaudebox clear-session          # delete session history for this workspace\ndocker pull psyb0t/claudebox:latest       # update (minimal)\ndocker pull psyb0t/claudebox:latest-full  # update (full)\n```\n\nFile v2.5.0:skill-card.md\n\n## Description:\n\nInstall and run Claude Code in a Docker-backed workspace, or connect to its HTTP, MCP, Telegram, and scheduled-job interfaces.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[psyb0t](https://clawhub.ai/user/psyb0t)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use Claudebox to run Claude Code locally or from automation, and to configure authenticated services for remote or scheduled agent tasks.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Unauthenticated HTTP or MCP endpoints can expose agent execution and workspace file control.\n\nMitigation: Set separate API and MCP tokens; bind services to loopback or protect them with an authenticated proxy.\n\nRisk: Agent tasks can access host Docker or mounted credentials when run through the standard wrapper.\n\nMitigation: Keep untrusted prompts out of privileged runtimes; isolate workspaces and omit the Docker socket when it is unnecessary.\n\nRisk: Installing remote scripts or using mutable images can run unreviewed code.\n\nMitigation: Inspect the installer and image provenance before use, and prefer pinned images and packages.\n\nRisk: File-control operations can delete workspace files without an undo path.\n\nMitigation: Confirm target paths and only delete files the current task created when removal was requested.\n\n## Reference(s):\n\n- [Claudebox setup guide](references/setup.md)\n- [Claudebox project homepage](https://github.com/psyb0t/docker-claudebox)\n- [Claudebox release on ClawHub](https://clawhub.ai/psyb0t/skills/claudebox)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration]\n\n**Output Format:** [Markdown with shell commands and configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Agent responses may include text, code, and structured results from the configured runtime.]\n\n## Skill Version(s):\n\n2.5.0 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v2.4.7: 4 files, 17344 bytes\n\nFiles: references/setup.md (14830b), skill-card.md (2079b), SKILL.md (26250b), _meta.json (128b)\n\nFile v2.4.7:SKILL.md\n\n---\nname: claudebox\ndescription: \"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\"\nhomepage: https://github.com/psyb0t/docker-claudebox\nuser-invocable: true\nmetadata:\n  { \"openclaw\": { \"emoji\": \"📦\", \"primaryEnv\": \"CLAUDEBOX_URL\", \"requires\": { \"bins\": [\"docker\", \"curl\"] } } }\n---\n\n# claudebox\n\nClaude Code — the agentic coding CLI from Anthropic — running in an isolated Docker container with dev tools, passwordless sudo, docker-in-docker, and `--permission-mode bypassPermissions` on by default. Built as a thin child image of `psyb0t/aicodebox`; every server-mode surface (API / OpenAI adapter / MCP / Telegram / Cron) is inherited from that base.\n\n## Agent execution\n\nUse `claudebox` when it is on `PATH`. Run it from the workspace the user\nnamed. Do not assemble a new `docker run` command for routine interactive or\none-shot work. The wrapper owns the workspace mount, `~/.claude`, SSH state,\nimage selection, and session lifecycle.\n\n```bash\nclaudebox                                      # interactive Claude Code\nclaudebox -p \"inspect this workspace\"          # one-shot work\nclaudebox -p \"emit events\" --output-format stream-json\nCLAUDEBOX_FULL=1 claudebox -p \"run the full suite\"\n```\n\nFor a wrapper-started server, prefix container variables with\n`CLAUDEBOX_ENV_`. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` passes\n`CLAUDEBOX_API_MODE=1` into the container. Bare `CLAUDEBOX_API_MODE` is not\nforwarded and does not start the server.\n\nStart a local API and MCP server only when the user asks for one. Authenticate\nClaude first, then use distinct bearer tokens for the two surfaces:\n\n```bash\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE_TOKEN=your-api-token \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token \\\nclaudebox\n```\n\nUse an HTTP or MCP endpoint only when the user asks for a service or provides\nan already-running remote URL. MCP plugins connect to a server. They do not\nreplace the local wrapper.\n\nIf `claudebox`, `codexbox`, and `pibox` were installed in the same command\ndirectory, a box can invoke a sibling command directly. The parent wrapper\npasses the real host paths and the sibling wrapper file. Do not set\n`AICODEBOX_HOST_*`, copy wrapper files, or manually mount another box's state\ndirectory. If the sibling command is absent, ask the user to install it or to\nchoose another approach.\n\n## Security & safety\n\n- **No auth when the per-mode token is unset.** `CLAUDEBOX_API_MODE_TOKEN` and `CLAUDEBOX_MCP_MODE_TOKEN` each default to no auth if unset — see [HTTP REST API mode](#http-rest-api-mode) and [MCP server mode](#mcp-server-mode) for details and the exact capability exposed unauthenticated in each case.\n- **File operations include removal.** Deleting a workspace file has no undo — only remove files the current task created, and only when the user asked.\n- **The standard wrapper mounts `/var/run/docker.sock`** so Claude can control the host Docker daemon. Server Compose examples omit it. See [Server modes (API / OpenAI / MCP / Telegram / Cron)](references/setup.md#server-modes-api--openai--mcp--telegram--cron), and do not use the wrapper for untrusted prompts.\n- **`--permission-mode bypassPermissions` is on by default** — Claude has full, unrestricted shell/file/docker access inside the container by design (see [When NOT To Use](#when-not-to-use)). Don't treat the container boundary as a sandbox for untrusted input unless you've isolated the container itself.\n- **Install script is piped from curl into bash by default** — a safer download-inspect-run alternative is documented alongside it; see [references/setup.md](references/setup.md#quick-install-cli-wrapper).\n\nThe image exposes interactive, command, HTTP, MCP, Telegram, and cron surfaces. The entrypoint selects one foreground mode, except that Telegram and cron run together. API mode takes precedence if it is set with another foreground mode:\n\n- **Interactive shell** — `claudebox` drops you into the native `claude` CLI, container-backed, with automatic session resumption.\n- **One-shot exec**: `claudebox -p \"prompt\" [flags]`, non-interactive, prompt in / structured output out, for scripts and CI.\n- **HTTP REST API** — `CLAUDEBOX_API_MODE=1`. `POST /run`, async runs polled via `GET /run/result?runId=`, `GET/PUT/DELETE /files/{path}`, workspace isolation.\n- **OpenAI-compatible endpoint** — same API-mode server, `/openai/v1/chat/completions` + `/openai/v1/models`. Streaming SSE, multi-turn, multimodal image input.\n- **MCP server** — `CLAUDEBOX_MCP_MODE=1`, 5 tools over streamable HTTP. Mounts at `/mcp/` on the API port when `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone as a sidecar process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), coexisting with Telegram/Cron/interactive mode.\n- **Telegram bot** — `CLAUDEBOX_TELEGRAM_MODE=1`, per-chat isolated workspaces, file/photo/video/voice ingestion, slash commands.\n- **Cron scheduler** — `CLAUDEBOX_CRON_MODE=1`, YAML-defined jobs on five or six field cron schedules with durable per-job artifacts.\n\nFor installation and configuration, see [references/setup.md](references/setup.md).\n\n## When To Use\n\n- Run Claude Code from a script, Makefile target, or CI pipeline without a TTY (`claudebox -p \"explain this diff\" --output-format json`).\n- Expose Claude Code as an HTTP backend other services can `POST /run` against, with workspace isolation for multi-tenant use.\n- Point an OpenAI SDK / LiteLLM at a self-hosted agentic backend instead of a plain model API — every completion runs the full Claude Code CLI (file I/O, shell, tools), not just text generation.\n- Let another MCP-aware agent, such as Claude Desktop, another Claude Code instance, or an agent framework, use this Claude Code instance as a tool over `/mcp/`.\n- Run Claude from Telegram to ask questions and share files from your phone.\n- Schedule recurring Claude jobs (nightly cleanup, hourly repo checks) with per-run history and optional Telegram result delivery.\n\n## When NOT To Use\n\n- Real-time token-by-token streaming for tool-calling or JSON-schema-constrained runs — the OpenAI adapter buffers those (computes the full answer, replays as one SSE burst). Only plain chat (no `tools`, no `response_format` schema) streams incrementally.\n- Multiple concurrent requests against the *same* workspace — API mode enforces one active Claude process per workspace and returns `409` on conflict. Use distinct `workspace` subpaths for parallel work.\n- Treating `--permission-mode bypassPermissions` as sandboxed-safe for untrusted input — Claude has full container access by design (shell, docker-in-docker, mounted SSH keys). Isolate the container itself if the input is untrusted.\n- Treating the MCP server as a sandbox. `run_prompt` has the same container authority as Claude, including mounted files and optional Docker access.\n\n## Interactive shell mode\n\nDrop-in replacement for the native `claude` command, container-backed:\n\n```bash\nclaudebox                  # interactive session, --continue applied automatically\nclaudebox --no-continue    # start a fresh session instead of resuming\nclaudebox --update         # opt in to a Claude Code CLI update this run\n```\n\nUtility commands pass through without entering interactive mode:\n\n```bash\nclaudebox --version         # claude CLI version\nclaudebox doctor            # health checks\nclaudebox auth              # manage authentication\nclaudebox mcp <args...>     # manage MCP servers, e.g. `claudebox mcp list`\nclaudebox setup-token       # interactive OAuth token setup\nclaudebox stop              # stop the running interactive container for this workspace\nclaudebox clear-session     # delete session history for this workspace\n```\n\nNo mode flag needed — this is the default when you run `claudebox` with no `CLAUDEBOX_*_MODE` env vars set. Auth: `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN` (see [Auth](#auth)).\n\n## One-shot exec mode\n\nNon-interactive prompt-in/response-out. Pass `-p` for scripts, CI, cron, or\nanywhere without a TTY:\n\n```bash\nclaudebox -p \"explain this codebase\"                                       # plain text (default)\nclaudebox -p \"explain this codebase\" --output-format json                  # structured JSON\nclaudebox -p \"list all TODOs\" --output-format stream-json | jq .           # complete native NDJSON\nclaudebox -p \"explain this codebase\" --model opus                          # pick a model\nclaudebox -p \"review this\" --system-prompt \"You are a security auditor\"    # replace system prompt\nclaudebox -p \"review this\" --append-system-prompt \"Focus on SQL injection\" # append to system prompt\nclaudebox -p \"debug this\" --effort max                                     # max reasoning effort\nclaudebox -p \"start over\" --no-continue                                    # fresh session\nclaudebox -p \"keep going\" --resume abc123-def456                           # resume a specific session\n\n# JSON-schema-constrained output\nclaudebox -p \"extract the author and title\" --output-format json \\\n  --json-schema '{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\"]}'\n```\n\n`--continue` is applied automatically so successive runs in the same workspace\nshare context. Use `--no-continue` for a clean slate or `--resume <session_id>`\nfor a specific one. Model aliases: `haiku`, `sonnet`, `opus`, `opusplan`,\n`sonnet[1m]`. The wrapper requires `-p` to select this mode.\n\n## HTTP REST API mode\n\n`CLAUDEBOX_API_MODE=1` starts a long-lived FastAPI server (default port `8080`, `CLAUDEBOX_API_MODE_PORT` to override). Bearer auth via `CLAUDEBOX_API_MODE_TOKEN` (unset = no auth).\n\nWith `CLAUDEBOX_API_MODE_TOKEN` unset the API surface is unauthenticated — anyone who can reach it gets full `/run` (arbitrary-prompt agentic execution) and `/files` (read/write anywhere under `/workspace`) access. Set the token and bind to loopback / behind an authenticating proxy before exposing it beyond localhost.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_API_MODE_TOKEN=your-secret-token\n  - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan  # optional — overrides the adapter's built-in default list\n```\n\n```bash\ncurl -X POST http://localhost:8080/run \\\n  -H \"Authorization: Bearer your-secret-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"what does this repo do\", \"workspace\": \"myproject\"}'\n```\n\nKey `/run` body fields: `prompt` (required), `workspace` (subpath under `/workspace`), `model`, `systemPrompt`, `appendSystemPrompt`, `jsonSchema`, `eventMode`, `outputFormat` (legacy), `noContinue`, `resume`, `fireAndForget`, `async`, `includeRaw` (raw stdout/stderr), `extraArgs`, `toolsAllowlist`, `noTools`, and `timeoutSeconds`. The Claude adapter always requests complete native records. Use `\"eventMode\": \"full\"` to return them in the stable `{sequence, attempt, backend, eventType, event}` envelope. `thinking` maps `low`, `medium`, `high`, `xhigh`, and `max` to Claude Code's `--effort` flag. `off` and `none` keep Claude Code's default. Every response carries a `runId`. Returns `409` if the target workspace is already busy.\n\n**Async runs** — `\"async\": true` returns immediately with a `runId`; poll it:\n\n```bash\ncurl -X POST http://localhost:8080/run -H \"Authorization: Bearer token\" -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"refactor this codebase\", \"workspace\": \"myproject\", \"async\": true}'\n# → {\"runId\": \"abc123\", \"workspace\": \"/workspace/myproject\", \"status\": \"running\"}\n\ncurl \"http://localhost:8080/run/result?runId=abc123\" -H \"Authorization: Bearer token\"\n# running → {\"runId\":..., \"status\": \"running\"}; completed → full result JSON (then purged from cache)\n```\n\nCompleted/failed/cancelled results are returned once then purged; unread results expire after 6 hours. `GET /run/result?runId=X` 404s on unknown/already-read/expired IDs.\n\n**File operations** — all paths relative to `/workspace`, path traversal blocked with `400`:\n\n```bash\ncurl \"http://localhost:8080/files\" -H \"Authorization: Bearer token\"                          # list root\ncurl \"http://localhost:8080/files/myproject/src\" -H \"Authorization: Bearer token\"            # list dir\ncurl \"http://localhost:8080/files/myproject/src/main.py\" -H \"Authorization: Bearer token\"    # download\ncurl -X PUT \"http://localhost:8080/files/myproject/src/main.py\" -H \"Authorization: Bearer token\" --data-binary @main.py\ncurl -X DELETE \"http://localhost:8080/files/myproject/src/old.py\" -H \"Authorization: Bearer token\"\n```\n\n`DELETE /files/{path}` removes a file under `/workspace` (no undo). Confirm the target path first, only remove files the current task created, and on a shared instance don't touch another caller's workspace — see [Security & safety](#security--safety).\n\n**Introspection and lifecycle:**\n\n```bash\ncurl http://localhost:8080/healthz                                                          # {\"ok\": true, \"adapter\": \"claude\"} — no auth\ncurl http://localhost:8080/status -H \"Authorization: Bearer token\"                           # {busyWorkspaces, runs}\ncurl -X DELETE \"http://localhost:8080/run/abc123\" -H \"Authorization: Bearer token\"            # cancel a run by id\n```\n\n## OpenAI-compatible endpoint mode\n\nSame API-mode server (`CLAUDEBOX_API_MODE=1`); no separate flag. `chat/completions`-shaped adapter for LiteLLM, OpenAI SDKs, or any client speaking that wire format. Every request runs the full agentic CLI, not just text generation — Claude can read/write files and run shell commands as part of answering.\n\n```bash\ncurl http://localhost:8080/openai/v1/models\n# {\"object\":\"list\",\"data\":[{\"id\":\"haiku\",...},{\"id\":\"sonnet\",...},{\"id\":\"opus\",...},{\"id\":\"opusplan\",...}]}\n\ncurl -X POST http://localhost:8080/openai/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"haiku\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}]}'\n\n# streaming\ncurl -X POST http://localhost:8080/openai/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"haiku\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}],\"stream\":true}'\n```\n\nModel aliases match the CLI (`haiku`/`sonnet`/`opus`/`opusplan`); provider prefixes are stripped (`claudebox/haiku` → `haiku`). `role: \"system\"` messages become `--system-prompt`. Single-user-message requests are the fast path (sent directly as the prompt); multi-turn conversations are serialized to a JSON file under `_oai_uploads/` in the workspace so Claude Code can read the full history. Multimodal `image_url` content (data URLs or `http(s)://`) is downloaded/decoded to the workspace and referenced by path.\n\nFor every native Claude record in an OpenAI stream, send\n`\"stream_options\": {\"include_aicodebox_events\": true}`. Claudebox emits a\nnamed `aicodebox.native` SSE event before normal OpenAI chunks. Its payload is\n`{sequence, attempt, backend, eventType, event}`. Standard chunks remain\nunchanged, so the extension stays opt-in for strict OpenAI SSE clients.\n\n`temperature` and `max_tokens` are accepted for OpenAI-client compatibility but have no effect on this adapter. `reasoning_effort` maps to the `claude --effort` flag: `low`, `medium`, `high`, `xhigh`, and `max` pass through, `minimal` maps to `low`, `none` or `off` keeps the default, and any other value is rejected. The `thinking` field on `/run` and MCP `run_prompt` works the same way.\n\n**Tool calling and structured output are supported, not ignored** — `tools`/`tool_choice` engage a client-executed function-calling bridge (Claude Code acts as a pure function-calling model, emits `tool_calls` for the *client* to run), and `response_format` (`json_object` or `json_schema`) constrains the final answer turn. Both can combine in one request. Because a tool call or schema-checked answer only exists once the full response is computed, `stream:true` combined with `tools` or a schema `response_format` returns a **buffered** single-shot SSE stream instead of token-incremental deltas — only plain chat (no tools, no schema) streams token-by-token.\n\nCustom headers for claudebox-specific behavior (canonical `x-aicodebox-*`, with legacy `X-Claude-*` aliases still accepted):\n\n| Header | Description |\n| --- | --- |\n| `x-aicodebox-workspace` (`X-Claude-Workspace`) | Workspace subpath under `/workspace` |\n| `x-aicodebox-continue` (`X-Claude-Continue`) | `1`/`true`/`yes` to continue the previous session |\n| `x-aicodebox-append-system-prompt` (`X-Claude-Append-System-Prompt`) | Text appended to the system prompt |\n| `x-aicodebox-json-schema` | JSON-schema string — fallback for clients that can't set `response_format` in the body (body field wins if both are set) |\n| `x-aicodebox-resume` | Resume a specific session id |\n| `x-aicodebox-tools-allowlist` | CSV or JSON array restricting Claude Code's own internal tools |\n| `x-aicodebox-no-tools` | Disable Claude Code's own internal tools (auto-defaulted on when in client tool-calling mode) |\n\nLiteLLM example:\n\n```python\nimport litellm\n\nresponse = litellm.completion(\n    model=\"claudebox/haiku\",\n    messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n    api_base=\"http://localhost:8080/openai/v1\",\n    api_key=\"your-secret-token\",  # any string if no API token is configured\n)\nprint(response.choices[0].message.content)\n```\n\n## MCP server mode\n\n`CLAUDEBOX_MCP_MODE=1` exposes a [Model Context Protocol](https://modelcontextprotocol.io/) server over streamable HTTP, using `CLAUDEBOX_MCP_MODE_TOKEN` as its bearer token (independent of the API token, no fallback; empty/unset = no auth). Where it listens depends on whether API mode is also on:\n\nWith `CLAUDEBOX_MCP_MODE_TOKEN` unset the MCP surface is unauthenticated — anyone who can reach it gets full tool access (run prompts, read/write/remove files under `/workspace`). Set the token and bind to loopback / behind an authenticating proxy before exposing it beyond localhost.\n\n- **`CLAUDEBOX_API_MODE=1` + `CLAUDEBOX_MCP_MODE=1`** (the setup the rest of the README documents) — MCP mounts at `/mcp/` on the API port, no extra process.\n- **`CLAUDEBOX_MCP_MODE=1` alone** (or combined with Telegram/Cron/interactive mode) — MCP runs as an independent background process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), serving at the port root, not under `/mcp`.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_MCP_MODE=1\n  - CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"claudebox\": {\n      \"url\": \"http://localhost:8080/mcp/\",\n      \"headers\": { \"Authorization\": \"Bearer your-mcp-token\" }\n    }\n  }\n}\n```\n\nClients that can't set headers can pass the token as a query param instead: `http://localhost:8080/mcp/?apiToken=your-mcp-token`. Wire it into Claude Code directly:\n\n```bash\nclaude mcp add --transport http claudebox http://localhost:8080/mcp/ \\\n  --header \"Authorization: Bearer your-mcp-token\"\n```\n\n**Available tools:**\n\n| Tool | Description |\n| --- | --- |\n| `run_prompt` | Run a prompt through Claude Code. Args: `prompt`, `workspace`, `model`, `system_prompt`, `append_system_prompt`, `no_continue` (default `true`), `resume`, `thinking` (`low`, `medium`, `high`, `xhigh`, and `max` map to Claude Code effort), `json_schema`. Returns the assistant's text. |\n| `list_files` | List files/dirs under a workspace path. |\n| `read_file` | Read a file's text content. |\n| `write_file` | Write content to a file (creates parent dirs). |\n| `delete_file` | Delete a file (refuses directories). |\n\n`delete_file` removes a file under `/workspace` (no undo). Confirm the target path first and only remove files the current task created — see [Security & safety](#security--safety).\n\nRaw JSON-RPC for debugging (streamable-HTTP handshake — `initialize` then reuse the returned `mcp-session-id`):\n\n```bash\ncurl -s -D - -X POST \"http://localhost:8080/mcp/\" \\\n  -H \"Authorization: Bearer your-mcp-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"debug\",\"version\":\"1\"}}}'\n# capture the mcp-session-id response header, then:\ncurl -s -X POST \"http://localhost:8080/mcp/\" \\\n  -H \"Authorization: Bearer your-mcp-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -H \"mcp-session-id: <session-id-from-above>\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}'\n```\n\n## Telegram bot mode\n\n`CLAUDEBOX_TELEGRAM_MODE=1` runs a conversational bot with per-chat isolated workspaces. Configure an explicit allowlist before exposing the bot. When `telegram.yml` is absent and `TELEGRAM_CHAT_ID` is unset, the compatibility fallback permits every chat.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_TELEGRAM_MODE=1\n  - CLAUDEBOX_TELEGRAM_MODE_TOKEN=123456:ABC-DEF   # from @BotFather\n```\n\n`$HOME/.aicodebox/telegram.yml` (mounted into the container):\n\n```yaml\nallowed_chats:\n  - 123456789    # your DM (positive = user id)\n  - -987654321   # a group chat (negative)\n\ndefault:\n  model: sonnet\n  effort: high\n  continue: true\n\nchats:\n  123456789:\n    workspace: my-project\n    model: opus\n    system_prompt: \"You are a senior engineer\"\n```\n\nPer-chat settings: `workspace`, `model`, `effort`, `continue`, `system_prompt`, `append_system_prompt`, and `allowed_users` for a group-chat allowlist.\n\nBot commands: any text message is a prompt; sending a file/photo/video/voice saves it to the workspace (caption becomes the prompt); `/model [name]`, `/effort [level]`, `/system_prompt [text]`, `/append_system_prompt [text]`, `/fetch <path>`, `/cancel`, `/status`, `/config`, `/reload`. Claude sends files back with `[SEND_FILE: relative/path]` in its response text.\n\n`effort` (config field and `/effort` command) is passed to the `claude` CLI as `--effort`. `off` keeps Claude Code's default effort.\n\n## Cron scheduler mode\n\n`CLAUDEBOX_CRON_MODE=1` runs YAML-defined Claude jobs on cron schedules. Five fields give minute resolution and six fields give second resolution. `docker logs` shows every tick.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_CRON_MODE=1\n  - CLAUDEBOX_CRON_MODE_FILE=/home/aicode/.aicodebox/cron.yaml\n  - CLAUDEBOX_WORKSPACE=/workspace\n```\n\n`cron.yaml`:\n\n```yaml\nmodel: haiku                       # default for all jobs; per-job \"model\" overrides\njobs:\n  - name: hourly_repo_check\n    schedule: \"0 * * * *\"          # 5-field standard cron\n    instruction: |\n      Look at the git log for the last hour. Summarize commits.\n  - name: every_30_seconds\n    schedule: \"*/30 * * * * *\"     # 6-field sub-minute\n    instruction: Write the current UTC timestamp to ./status.txt.\n```\n\nRoot defaults and per-job overrides support `model`, `effort`, `thinking`, `system_prompt`, `append_system_prompt`, and `telegram_chat_id`. A job also supports `workspace` and `no_continue`. `telegram_chat_id` requires `CLAUDEBOX_TELEGRAM_MODE_TOKEN`; set it to `0` in a job to disable a root default. `{system_datetime}` and `{job_name}` work in `instruction`, `system_prompt`, and `append_system_prompt`. Claude maps `effort` and `thinking` to its `--effort` flag.\n\nEach run writes `meta.json`, `stdout.log`, `stderr.log`, and `result.txt` under `$HOME/.aicodebox/cron/history/<workspace-slug>/<YYYYMMDD-HHMMSS>-<job-name>/`. The scheduler appends a summary to `$HOME/.aicodebox/cron/<job-name>.jsonl`. Set `CLAUDEBOX_CRON_MODE_HISTORY_DIR` to change the whole cron state root. Same-name overlaps are skipped. Combine with `CLAUDEBOX_TELEGRAM_MODE=1` to post results and reply to a finished run. See [references/setup.md](references/setup.md#cron--telegram-combined-mode).\n\n## Auth\n\nInteractive/exec/cron/CLI-driven modes need an Anthropic credential:\n\n```bash\nclaudebox setup-token                                        # interactive OAuth setup, one-time\nCLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN> claudebox -p \"do stuff\" # then reuse the token\n# or\nANTHROPIC_API_KEY=<YOUR_API_KEY> claudebox -p \"do stuff\"\n```\n\nServer modes gate their own HTTP surface independently, each with its own bearer token (unset = open):\n\n| Mode | Token var |\n| --- | --- |\n| API / OpenAI adapter | `CLAUDEBOX_API_MODE_TOKEN` |\n| MCP | `CLAUDEBOX_MCP_MODE_TOKEN` (separate from the API token, no fallback) |\n| Telegram | `CLAUDEBOX_TELEGRAM_MODE_TOKEN` (the bot token itself, not a bearer secret) |\n\nAll of these still need the underlying Anthropic credential (`CLAUDE_CODE_OAUTH_TOKEN` / `ANTHROPIC_API_KEY`) set in the container env to actually talk to the model.\n\n## Typical Workflows\n\n### Pipe a code review through CI\n\n```bash\nclaudebox -p \"review this diff for security issues\" --output-format json --model sonnet | jq -r .result\n```\n\n### Drive claudebox from another agent over MCP\n\n```bash\nclaude mcp add --transport http claudebox http://localhost:8080/mcp/ \\\n  --header \"Authorization: Bearer $CLAUDEBOX_MCP_MODE_TOKEN\"\n```\n\n### Fire-and-poll a long refactor over HTTP\n\n```bash\nRUN_ID=$(curl -s -X POST http://localhost:8080/run -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"refactor the auth module\", \"workspace\": \"myproject\", \"async\": true}' | jq -r .runId)\n\nuntil curl -s \"http://localhost:8080/run/result?runId=$RUN_ID\" -H \"Authorization: Bearer $TOKEN\" | jq -e '.status != \"running\"' >/dev/null; do\n  sleep 5\ndone\ncurl -s \"http://localhost:8080/run/result?runId=$RUN_ID\" -H \"Authorization: Bearer $TOKEN\" | jq\n```\n\n### Point LiteLLM at claudebox as an OpenAI-compatible backend\n\n```python\nimport litellm\nlitellm.completion(model=\"claudebox/sonnet\", messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n                    api_base=\"http://localhost:8080/openai/v1\", api_key=API_TOKEN)\n```\n\n### Nightly cleanup job with Telegram notification\n\n```yaml\ntelegram_chat_id: -1001234567890\njobs:\n  - name: nightly_cleanup\n    schedule: \"0 3 * * *\"\n    instruction: Find files older than 7 days under ./tmp and delete them. Report what you removed.\n```\n\nFor install steps, docker run/compose invocations, the full env-var reference, port list, and container management commands, see [references/setup.md](references/setup.md).\n\nFile v2.4.7:_meta.json\n\n{\n  \"ownerId\": \"kn79dhvmpjng4rp2jjk8k0v5xx80ccbk\",\n  \"slug\": \"claudebox\",\n  \"version\": \"2.4.7\",\n  \"publishedAt\": 1791380417890\n}\n\nFile v2.4.7:references/setup.md\n\n# claudebox setup\n\n## Requirements\n\n- Docker installed and running. That's it — the wrapper handles the rest.\n- An Anthropic credential: `CLAUDE_CODE_OAUTH_TOKEN` (via `claudebox setup-token`) or `ANTHROPIC_API_KEY`.\n\nFor ordinary agent work, use the installed `claudebox` command from the target\nworkspace. Do not replace it with a hand-written Docker invocation. The\nwrapper handles the workspace, state, SSH, image, and nested launch context.\n\n## Quick Install (CLI wrapper)\n\nSafer path — download, inspect, then run:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh -o install.sh\nless install.sh   # read it before running anything you downloaded\nbash install.sh\n\n# full image variant\nexport CLAUDEBOX_FULL=1 && bash install.sh\n\n# custom binary name\nbash install.sh claude\n```\n\nDownloading and reading the script before running it is the recommended flow, especially in an agent-driven or CI context — it runs with your privileges.\n\nThe installer pulls the image, generates an ed25519 SSH key at `~/.ssh/claudebox/id_ed25519` for git operations inside the container, creates `~/.claude`, and installs the wrapper to `/usr/local/bin/claudebox` (override with `CLAUDEBOX_INSTALL_DIR` / `CLAUDEBOX_BIN_NAME`). Add the generated public key to GitHub/GitLab for git push/pull to work from inside the container.\n\n```bash\nclaudebox                                  # interactive\nclaudebox -p \"inspect this workspace\"      # one-shot\nCLAUDEBOX_FULL=1 claudebox -p \"run tests\"  # temporary full image\n```\n\nFor a wrapper-started server, use `CLAUDEBOX_ENV_` before every variable that\nmust reach the container. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` starts API mode.\n\nInstall `claudebox`, `codexbox`, and `pibox` in the same command directory,\nnormally `/usr/local/bin`, when one box needs to launch another. The parent\nmounts only sibling wrapper files read-only. A sibling wrapper then runs through\nthe host Docker daemon and mounts its own host data directory.\n\nManual setup without piping to bash: `mkdir -p ~/.claude`, generate the SSH key yourself, `docker pull psyb0t/claudebox:latest` (or `:latest-full`), then fetch `wrapper.sh` and install it as your `claudebox` binary.\n\n## Image Variants\n\n| | `psyb0t/claudebox:latest` (minimal, default) | `psyb0t/claudebox:latest-full` |\n| --- | --- | --- |\n| Base | Ubuntu 24.04, git/curl/wget/jq, Node.js 24 LTS, Python 3.14 + uv, Docker CE | same, plus everything below |\n| Go | — | 1.26 toolchain (golangci-lint, gopls, delve, staticcheck, gofumpt, gotests, impl, gomodifytags) |\n| Python | — | 3.14 via pyenv (flake8, black, isort, pyright, mypy, vulture, pytest, poetry, pipenv) |\n| Node dev tools | — | eslint, prettier, typescript, yarn, pnpm, framework CLIs |\n| C/C++ | — | gcc, g++, make, cmake, clang-format, valgrind, gdb |\n| DevOps | — | terraform, kubectl, helm, gh |\n| DB clients | — | sqlite3, psql, mysql, redis-cli |\n| Shell utils | — | ripgrep, bat, exa, fd-find, ag, htop, tmux, shellcheck, shfmt |\n\nMinimal has passwordless sudo, so Claude installs whatever else it needs via `apt-get`/`pip`/`npm` on the fly — smaller pull, slower first task. Use `/aicodebox-init.d/*.sh` hooks to pre-install tooling on first container create instead of burning tokens on package management.\n\n`CLAUDEBOX_FULL=1` at install time bakes the full-variant choice into the wrapper permanently; at runtime it overrides per-invocation. Pre-v2 `CLAUDEBOX_MINIMAL=1` is a no-op (minimal is already the default).\n\n## docker run / docker-compose\n\n### Interactive / exec (via the wrapper — recommended)\n\nThe installed `claudebox` wrapper handles container naming, volume mounts, SSH key mounting, and auth forwarding automatically. Don't hand-roll `docker run` for interactive/exec use — install the wrapper instead (see Quick Install above).\n\n### Server modes (API / OpenAI / MCP / Telegram / Cron)\n\n```yaml\n# docker-compose.yml\nservices:\n  claudebox:\n    image: psyb0t/claudebox:latest\n    init: true\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:8080:8080\"\n    environment:\n      - CLAUDEBOX_API_MODE=1\n      - CLAUDEBOX_API_MODE_TOKEN=${CLAUDEBOX_API_MODE_TOKEN:?set this in .env}\n      - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan\n      - CLAUDE_CODE_OAUTH_TOKEN=${CLAUDE_CODE_OAUTH_TOKEN:?set this in .env}\n    volumes:\n      - ./claude-state:/home/aicode/.aicodebox\n      - /your/projects:/workspace\n    mem_limit: 2g\n    cpus: 2\n    pids_limit: 512\n    logging:\n      driver: local\n      options:\n        max-size: 10m\n        max-file: \"3\"\n```\n\nThis server example intentionally omits `/var/run/docker.sock`. That socket grants the container control over every host container. Add it only for a trusted workload that requires host Docker access.\n\nAdd `CLAUDEBOX_MCP_MODE=1` and `CLAUDEBOX_MCP_MODE_TOKEN` alongside `CLAUDEBOX_API_MODE=1` to mount MCP on the same port. API mode takes precedence over Telegram and cron if more than one foreground mode is set. Telegram and cron are the only foreground pair that run together.\n\n## Runtime boundaries\n\nSet Docker memory, CPU, PID, and log limits for long running containers. This image installs Claude Code during first start and changes identity during boot, so `read_only: true` and `cap_drop: [ALL]` are not safe copy-paste defaults. Test the exact image and startup path before adding them.\n\n## Environment Variable Reference\n\nAll wrapper/installer config uses the `CLAUDEBOX_*` prefix; the entrypoint aliases each to `AICODEBOX_*` (the base image's canonical names) when the target is unset — `AICODEBOX_*` wins if both are set. Legacy pre-v2 `CLAUDE_*` / `CLAUDE_MODE_*` names still work as fallbacks.\n\n### Wrapper / installer\n\n| Variable | Description | Default |\n| --- | --- | --- |\n| `CLAUDEBOX_GIT_NAME` / `CLAUDEBOX_GIT_EMAIL` | Git identity inside the container | _(none)_ |\n| `CLAUDEBOX_DATA_DIR` | Host path for the `.claude` data dir | `~/.claude` |\n| `CLAUDEBOX_SSH_DIR` | Host path for the SSH key directory | `~/.ssh/claudebox` |\n| `CLAUDEBOX_INSTALL_DIR` | Wrapper binary install location (install-time) | `/usr/local/bin` |\n| `CLAUDEBOX_BIN_NAME` | Wrapper binary name (install-time) | `claudebox` |\n| `CLAUDEBOX_IMAGE` | Override the Docker image | `psyb0t/claudebox:latest` |\n| `CLAUDEBOX_FULL` | Use the `latest-full` toolchain image instead of minimal | _(none)_ |\n| `CLAUDEBOX_CONTAINER_NAME` | Override the per-workspace container name | derived from `$PWD` |\n| `CLAUDEBOX_MAX_MEM` | Per-container memory limit | `10g` |\n| `CLAUDEBOX_ENV_*` | Forward arbitrary vars into the container (prefix stripped) | _(none)_ |\n| `CLAUDEBOX_MOUNT_*` | Mount extra host directories | _(none)_ |\n\nAuth/in-container settings route through `CLAUDEBOX_ENV_*`:\n\n```bash\nCLAUDEBOX_ENV_ANTHROPIC_API_KEY=your-api-key claudebox -p \"do stuff\"\nCLAUDEBOX_ENV_CLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN> claudebox -p \"do stuff\"\nCLAUDEBOX_ENV_DEBUG=true claudebox -p \"do stuff\"          # structured JSON debug logging\n```\n\nExtra mounts:\n\n```bash\nCLAUDEBOX_MOUNT_DATA=/data claudebox -p \"process the data\"                   # same path both sides\nCLAUDEBOX_MOUNT_1=/opt/configs CLAUDEBOX_MOUNT_2=/var/logs claudebox -p \"go\" # multiple mounts\nCLAUDEBOX_MOUNT_STUFF=/host/path:/container/path claudebox -p \"do stuff\"     # explicit src:dst\nCLAUDEBOX_MOUNT_RO=/data:/data:ro claudebox -p \"read the data\"               # read-only\n```\n\n### Server modes\n\n| Variable | Description | Default |\n| --- | --- | --- |\n| `CLAUDEBOX_API_MODE` | `1` to start the HTTP API server | _(none)_ |\n| `CLAUDEBOX_API_MODE_PORT` | API server port | `8080` |\n| `CLAUDEBOX_API_MODE_TOKEN` | Bearer token for `/run`, `/files`, `/status`, `/openai/*` | _(none — no auth)_ |\n| `CLAUDEBOX_AVAILABLE_MODELS` | CSV of model aliases surfaced at `/openai/v1/models`. Optional — claudebox's adapter has a built-in default (`haiku,sonnet,opus,opusplan`); set this to override it. The API server only refuses to boot if the resolved list ends up empty. | _(none — adapter default applies)_ |\n| `CLAUDEBOX_AVAILABLE_EFFORTS` | CSV of effort levels surfaced to Telegram `/effort` picker | adapter default |\n| `CLAUDEBOX_MCP_MODE` | `1` to expose MCP. Mounts at `/mcp/` on the API port if `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone on its own port | _(none)_ |\n| `CLAUDEBOX_MCP_MODE_PORT` | Port for the standalone MCP process (only used when API mode is off) | `8081` |\n| `CLAUDEBOX_MCP_MODE_TOKEN` | Bearer token for MCP (independent of the API token, no fallback) | _(none — no auth)_ |\n| `CLAUDEBOX_MCP_MODE_ALLOWED_HOSTS` | Comma-separated MCP `Host` allowlist. Add each reverse-proxy host name. | loopback hosts |\n| `CLAUDEBOX_MCP_MODE_ALLOWED_ORIGINS` | Comma-separated MCP browser Origin allowlist. Add each reverse-proxy origin. | loopback HTTP origins |\n| `CLAUDEBOX_TELEGRAM_MODE` | `1` to start the Telegram bot | _(none)_ |\n| `CLAUDEBOX_TELEGRAM_MODE_TOKEN` | Bot token from [@BotFather](https://t.me/BotFather) | _(none)_ |\n| `CLAUDEBOX_TELEGRAM_MODE_CONFIG` | Path to `telegram.yml` inside the container | `/home/aicode/.aicodebox/telegram.yml` |\n| `CLAUDEBOX_CRON_MODE` | `1` to start the cron scheduler | _(none)_ |\n| `CLAUDEBOX_CRON_MODE_FILE` | Path to the cron YAML inside the container | _(none)_ |\n| `CLAUDEBOX_CRON_MODE_HISTORY_DIR` | Cron state root for artifacts, summaries, and Telegram reply metadata | `/home/aicode/.aicodebox/cron` |\n| `CLAUDEBOX_WORKSPACE` | Absolute workspace path (cwd for every mode) | `/workspace` |\n| `CLAUDEBOX_ALWAYS_SKILLS_DIR` | Where `SKILL.md` files are scanned for always-active injection | `/home/aicode/.claude/.always-skills` |\n| `CLAUDEBOX_SYSTEM_HINT_FILE` | Text prepended to `--append-system-prompt` on every call | `/home/aicode/.claude/system-hint.txt` |\n| `DEBUG` | `1`/`true` for structured JSON debug logging | _(none)_ |\n\nLegacy fallbacks still accepted: `CLAUDE_MODE_API`/`CLAUDE_MODE_API_PORT`/`CLAUDE_MODE_API_TOKEN`, `CLAUDE_MODE_TELEGRAM`, `CLAUDE_MODE_CRON`/`CLAUDE_MODE_CRON_FILE`, `CLAUDE_WORKSPACE`, `CLAUDE_TELEGRAM_BOT_TOKEN`, `CLAUDE_TELEGRAM_CONFIG`.\n\n## Ports\n\n| Port | Service |\n| --- | --- |\n| 8080 (default, `CLAUDEBOX_API_MODE_PORT`) | HTTP API + OpenAI adapter, and MCP (`/mcp/`) if `CLAUDEBOX_MCP_MODE=1` is also set |\n| 8081 (default, `CLAUDEBOX_MCP_MODE_PORT`) | Standalone MCP at `/`, only when `CLAUDEBOX_MCP_MODE=1` is set without `CLAUDEBOX_API_MODE=1` |\n\nMCP either mounts onto the API port or runs on its own port — never both at once, depending on whether API mode is also enabled. Loopback hosts work by default. A proxy or public endpoint must set the exact `CLAUDEBOX_MCP_MODE_ALLOWED_HOSTS` and browser `CLAUDEBOX_MCP_MODE_ALLOWED_ORIGINS` values it sends.\n\n## Cron + Telegram Combined Mode\n\nSet both `CLAUDEBOX_CRON_MODE=1` and `CLAUDEBOX_TELEGRAM_MODE=1` in the same container: a single workspace shared between the cron scheduler (background) and the bot (foreground); when the bot exits, the scheduler is killed too.\n\n- Cron jobs post results to Telegram automatically when `telegram_chat_id` is set (root default and/or per-job override) in `cron.yaml`.\n- Reply to a cron notification message to interrogate that run — the bot detects the reply, looks up the original job (name, timestamp, instruction, result), and prepends that context to a fresh session.\n\nOnly a reply to a cron notification receives that recorded job context. Ordinary Telegram messages do not receive cron history.\n\nSent message IDs and job context are stored in `$HOME/.aicodebox/cron/telegram_messages.json` and are automatically pruned to the last 200 entries.\n\n## MCP Servers claudebox Itself Can Use\n\nIndependent of exposing claudebox *as* an MCP server (MCP mode above), Claude Code running inside claudebox can also *consume* MCP servers you configure — same mechanism as any Claude Code install:\n\n| Scope | Path | Notes |\n| --- | --- | --- |\n| Project | `<workspace>/.mcp.json` | Checked into git, shared by the team |\n| User | `~/.claude.json` under `mcpServers` | Global, every project on the host |\n| Local | `~/.claude.json` per-project section | Default scope of `claude mcp add` |\n\n```bash\nclaudebox mcp add --scope project my-server -- npx -y @some/mcp-server\nclaudebox mcp add --scope user my-server -- npx -y @some/mcp-server\n```\n\nRun `/mcp` inside an interactive session to inspect what's loaded. This is how cron and Telegram modes reach external systems (post to Discord/Slack/email/webhooks) — configure the server, reference it from the job instruction or chat.\n\n## Customization\n\n- **Custom scripts (`~/.claude/bin`)** — any executable placed here is on PATH in every mode.\n- **Init hooks (`~/.claude/init.d/*.sh`)** — run once as root on first container create, before the entrypoint drops to `aicode`. Good for pre-installing tools on the minimal image.\n- **Always-active skills (`~/.claude/.always-skills/`)** — every `SKILL.md` found (recursive, alphabetical) is appended to `--append-system-prompt` on every invocation, across all modes, prefixed with `[Skill file: <path>]`.\n\n## Gotchas\n\n- `--permission-mode bypassPermissions` is the default — Claude has full, unrestricted access to the container. Override per-request via `RunRequest.extra_args` at the API layer.\n- SSH keys are mounted from the host for git push/pull. Don't share your container or image with untrusted parties.\n- Host paths are preserved — a project at `/home/you/project` mounts at the same path inside the container, so Docker volume mounts Claude creates from within it resolve correctly against the host.\n- UID/GID of the `aicode` user auto-adjusts to match the host directory owner at startup.\n- Wrapper-started interactive and programmatic containers mount the Docker socket by design. The server Compose example above deliberately does not.\n- Two containers per workspace: `claude-<path>` for interactive (TTY), `claude-<path>_prog` for one-shot exec (no TTY). Both share mounted volumes and data.\n- API-mode workspace busy tracking: one active Claude process per workspace; concurrent requests to the same workspace get `409`.\n- If `telegram.yml` is absent, `TELEGRAM_CHAT_ID` becomes the only allowed chat. If both are absent, the compatibility fallback permits every chat. Use an explicit allowlist before exposing the bot.\n- Claude Code CLI auto-updates are disabled inside the container by default; opt in with `claudebox --update`.\n\n## Management\n\n```bash\ndocker logs -f <container>       # tail logs (structured JSON in server modes)\nclaudebox stop                   # stop the interactive container for this workspace\nclaudebox clear-session          # delete session history for this workspace\ndocker pull psyb0t/claudebox:latest       # update (minimal)\ndocker pull psyb0t/claudebox:latest-full  # update (full)\n```\n\nFile v2.4.7:skill-card.md\n\n## Description:\n\nInstall, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[psyb0t](https://clawhub.ai/user/psyb0t)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use claudebox to run Claude Code for coding tasks in a container, or connect other tools to its HTTP and MCP services and schedule recurring jobs.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The standard wrapper can give the coding agent host-level Docker control.\n\nMitigation: Use only with trusted prompts; do not rely on the container as a sandbox for untrusted input.\n\nRisk: Exposed API, MCP, or Telegram modes can permit unauthorized agent or file operations when configured without access controls.\n\nMitigation: Use separate service tokens and Telegram allowlists; bind services to loopback or place them behind an authenticated proxy.\n\nRisk: Remote installation scripts and unpinned dependencies can change unexpectedly.\n\nMitigation: Inspect the installer before running it and pin image and package versions for production.\n\n## Reference(s):\n\n- [ClawHub skill listing](https://clawhub.ai/psyb0t/skills/claudebox)\n- [Installation and setup guide](artifact/references/setup.md)\n- [Project homepage](https://github.com/psyb0t/docker-claudebox)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown with command and configuration snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Output depends on the requested Claude Code task and enabled service mode.]\n\n## Skill Version(s):\n\n2.4.7 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v2.4.6: 4 files, 17165 bytes\n\nFiles: references/setup.md (14461b), skill-card.md (2164b), SKILL.md (26044b), _meta.json (128b)\n\nFile v2.4.6:SKILL.md\n\n---\nname: claudebox\ndescription: \"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\"\nhomepage: https://github.com/psyb0t/docker-claudebox\nuser-invocable: true\nmetadata:\n  { \"openclaw\": { \"emoji\": \"📦\", \"primaryEnv\": \"CLAUDEBOX_URL\", \"requires\": { \"bins\": [\"docker\", \"curl\"] } } }\n---\n\n# claudebox\n\nClaude Code — the agentic coding CLI from Anthropic — running in an isolated Docker container with dev tools, passwordless sudo, docker-in-docker, and `--permission-mode bypassPermissions` on by default. Built as a thin child image of `psyb0t/aicodebox`; every server-mode surface (API / OpenAI adapter / MCP / Telegram / Cron) is inherited from that base.\n\n## Agent execution\n\nUse `claudebox` when it is on `PATH`. Run it from the workspace the user\nnamed. Do not assemble a new `docker run` command for routine interactive or\none-shot work. The wrapper owns the workspace mount, `~/.claude`, SSH state,\nimage selection, and session lifecycle.\n\n```bash\nclaudebox                                      # interactive Claude Code\nclaudebox -p \"inspect this workspace\"          # one-shot work\nclaudebox -p \"emit events\" --output-format stream-json\nCLAUDEBOX_FULL=1 claudebox -p \"run the full suite\"\n```\n\nFor a wrapper-started server, prefix container variables with\n`CLAUDEBOX_ENV_`. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` passes\n`CLAUDEBOX_API_MODE=1` into the container. Bare `CLAUDEBOX_API_MODE` is not\nforwarded and does not start the server.\n\nStart a local API and MCP server only when the user asks for one. Authenticate\nClaude first, then use distinct bearer tokens for the two surfaces:\n\n```bash\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE_TOKEN=your-api-token \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token \\\nclaudebox\n```\n\nUse an HTTP or MCP endpoint only when the user asks for a service or provides\nan already-running remote URL. MCP plugins connect to a server. They do not\nreplace the local wrapper.\n\nIf `claudebox`, `codexbox`, and `pibox` were installed in the same command\ndirectory, a box can invoke a sibling command directly. The parent wrapper\npasses the real host paths and the sibling wrapper file. Do not set\n`AICODEBOX_HOST_*`, copy wrapper files, or manually mount another box's state\ndirectory. If the sibling command is absent, ask the user to install it or to\nchoose another approach.\n\n## Security & safety\n\n- **No auth when the per-mode token is unset.** `CLAUDEBOX_API_MODE_TOKEN` and `CLAUDEBOX_MCP_MODE_TOKEN` each default to no auth if unset — see [HTTP REST API mode](#http-rest-api-mode) and [MCP server mode](#mcp-server-mode) for details and the exact capability exposed unauthenticated in each case.\n- **File operations include removal.** Deleting a workspace file has no undo — only remove files the current task created, and only when the user asked.\n- **Mounting `/var/run/docker.sock` grants host-level container control** — see [Server modes (API / OpenAI / MCP / Telegram / Cron)](references/setup.md#server-modes-api--openai--mcp--telegram--cron) in `references/setup.md`, only do this on a host you trust.\n- **`--permission-mode bypassPermissions` is on by default** — Claude has full, unrestricted shell/file/docker access inside the container by design (see [When NOT To Use](#when-not-to-use)). Don't treat the container boundary as a sandbox for untrusted input unless you've isolated the container itself.\n- **Install script is piped from curl into bash by default** — a safer download-inspect-run alternative is documented alongside it; see [references/setup.md](references/setup.md#quick-install-cli-wrapper).\n\nSeven programmatic surfaces, all reachable from the same container image, selected by which `CLAUDEBOX_*_MODE` env flags are set at boot:\n\n- **Interactive shell** — `claudebox` drops you into the native `claude` CLI, container-backed, with automatic session resumption.\n- **One-shot exec**: `claudebox -p \"prompt\" [flags]`, non-interactive, prompt in / structured output out, for scripts and CI.\n- **HTTP REST API** — `CLAUDEBOX_API_MODE=1`. `POST /run`, async runs polled via `GET /run/result?runId=`, `GET/PUT/DELETE /files/{path}`, workspace isolation.\n- **OpenAI-compatible endpoint** — same API-mode server, `/openai/v1/chat/completions` + `/openai/v1/models`. Streaming SSE, multi-turn, multimodal image input.\n- **MCP server** — `CLAUDEBOX_MCP_MODE=1`, 5 tools over streamable HTTP. Mounts at `/mcp` on the API port when `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone as a sidecar process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), coexisting with Telegram/Cron/interactive mode.\n- **Telegram bot** — `CLAUDEBOX_TELEGRAM_MODE=1`, per-chat isolated workspaces, file/photo/video/voice ingestion, slash commands.\n- **Cron scheduler** — `CLAUDEBOX_CRON_MODE=1`, YAML-defined jobs on 5- or 6-field cron schedules, per-job activity history.\n\nFor installation and configuration, see [references/setup.md](references/setup.md).\n\n## When To Use\n\n- Run Claude Code from a script, Makefile target, or CI pipeline without a TTY (`claudebox -p \"explain this diff\" --output-format json`).\n- Expose Claude Code as an HTTP backend other services can `POST /run` against, with workspace isolation for multi-tenant use.\n- Point an OpenAI SDK / LiteLLM at a self-hosted agentic backend instead of a plain model API — every completion runs the full Claude Code CLI (file I/O, shell, tools), not just text generation.\n- Let another MCP-aware agent (Claude Desktop, another Claude Code instance, an agent framework) use this Claude Code instance as a tool over `/mcp`.\n- Run Claude from Telegram — ask questions, share files, get shell access, from your phone.\n- Schedule recurring Claude jobs (nightly cleanup, hourly repo checks) with per-run history and optional Telegram result delivery.\n\n## When NOT To Use\n\n- Real-time token-by-token streaming for tool-calling or JSON-schema-constrained runs — the OpenAI adapter buffers those (computes the full answer, replays as one SSE burst). Only plain chat (no `tools`, no `response_format` schema) streams incrementally.\n- Multiple concurrent requests against the *same* workspace — API mode enforces one active Claude process per workspace and returns `409` on conflict. Use distinct `workspace` subpaths for parallel work.\n- Treating `--permission-mode bypassPermissions` as sandboxed-safe for untrusted input — Claude has full container access by design (shell, docker-in-docker, mounted SSH keys). Isolate the container itself if the input is untrusted.\n- Expecting one fixed MCP path — it's `/mcp` (mounted, requires `CLAUDEBOX_API_MODE=1` too) in the documented API-mode setup, but a different, unmounted standalone port (`CLAUDEBOX_MCP_MODE_PORT`) when MCP mode runs without API mode. Match your client config to which one you actually launched.\n\n## Interactive shell mode\n\nDrop-in replacement for the native `claude` command, container-backed:\n\n```bash\nclaudebox                  # interactive session, --continue applied automatically\nclaudebox --no-continue    # start a fresh session instead of resuming\nclaudebox --update         # opt in to a Claude Code CLI update this run\n```\n\nUtility commands pass through without entering interactive mode:\n\n```bash\nclaudebox --version         # claude CLI version\nclaudebox doctor            # health checks\nclaudebox auth              # manage authentication\nclaudebox mcp <args...>     # manage MCP servers, e.g. `claudebox mcp list`\nclaudebox setup-token       # interactive OAuth token setup\nclaudebox stop              # stop the running interactive container for this workspace\nclaudebox clear-session     # delete session history for this workspace\n```\n\nNo mode flag needed — this is the default when you run `claudebox` with no `CLAUDEBOX_*_MODE` env vars set. Auth: `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN` (see [Auth](#auth)).\n\n## One-shot exec mode\n\nNon-interactive prompt-in/response-out. Pass `-p` for scripts, CI, cron, or\nanywhere without a TTY:\n\n```bash\nclaudebox -p \"explain this codebase\"                                       # plain text (default)\nclaudebox -p \"explain this codebase\" --output-format json                  # structured JSON\nclaudebox -p \"list all TODOs\" --output-format stream-json | jq .           # complete native NDJSON\nclaudebox -p \"explain this codebase\" --model opus                          # pick a model\nclaudebox -p \"review this\" --system-prompt \"You are a security auditor\"    # replace system prompt\nclaudebox -p \"review this\" --append-system-prompt \"Focus on SQL injection\" # append to system prompt\nclaudebox -p \"debug this\" --effort max                                     # max reasoning effort\nclaudebox -p \"start over\" --no-continue                                    # fresh session\nclaudebox -p \"keep going\" --resume abc123-def456                           # resume a specific session\n\n# JSON-schema-constrained output\nclaudebox -p \"extract the author and title\" --output-format json \\\n  --json-schema '{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\"]}'\n```\n\n`--continue` is applied automatically so successive runs in the same workspace\nshare context. Use `--no-continue` for a clean slate or `--resume <session_id>`\nfor a specific one. Model aliases: `haiku`, `sonnet`, `opus`, `opusplan`,\n`sonnet[1m]`. The wrapper requires `-p` to select this mode.\n\n## HTTP REST API mode\n\n`CLAUDEBOX_API_MODE=1` starts a long-lived FastAPI server (default port `8080`, `CLAUDEBOX_API_MODE_PORT` to override). Bearer auth via `CLAUDEBOX_API_MODE_TOKEN` (unset = no auth).\n\nWith `CLAUDEBOX_API_MODE_TOKEN` unset the API surface is unauthenticated — anyone who can reach it gets full `/run` (arbitrary-prompt agentic execution) and `/files` (read/write anywhere under `/workspace`) access. Set the token and bind to loopback / behind an authenticating proxy before exposing it beyond localhost.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_API_MODE_TOKEN=your-secret-token\n  - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan  # optional — overrides the adapter's built-in default list\n```\n\n```bash\ncurl -X POST http://localhost:8080/run \\\n  -H \"Authorization: Bearer your-secret-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"what does this repo do\", \"workspace\": \"myproject\"}'\n```\n\nKey `/run` body fields: `prompt` (required), `workspace` (subpath under\n`/workspace`), `model`, `systemPrompt`, `appendSystemPrompt`, `jsonSchema`,\n`eventMode`, `outputFormat` (legacy), `noContinue`, `resume`,\n`fireAndForget`, `async`, `includeRaw` (raw stdout/stderr), `extraArgs`,\n`toolsAllowlist`, `noTools`, and `timeoutSeconds`. The Claude adapter always\nrequests complete native records. Use `\"eventMode\": \"full\"` to return them in\nthe stable `{sequence, attempt, backend, eventType, event}` envelope.\n`thinking` is accepted but has no effect on claudebox (see\n[OpenAI-compatible endpoint mode](#openai-compatible-endpoint-mode)). Every\nresponse carries a `runId`. Returns `409` if the target workspace is already\nbusy.\n\n**Async runs** — `\"async\": true` returns immediately with a `runId`; poll it:\n\n```bash\ncurl -X POST http://localhost:8080/run -H \"Authorization: Bearer token\" -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"refactor this codebase\", \"workspace\": \"myproject\", \"async\": true}'\n# → {\"runId\": \"abc123\", \"workspace\": \"/workspace/myproject\", \"status\": \"running\"}\n\ncurl \"http://localhost:8080/run/result?runId=abc123\" -H \"Authorization: Bearer token\"\n# running → {\"runId\":..., \"status\": \"running\"}; completed → full result JSON (then purged from cache)\n```\n\nCompleted/failed/cancelled results are returned once then purged; unread results expire after 6 hours. `GET /run/result?runId=X` 404s on unknown/already-read/expired IDs.\n\n**File operations** — all paths relative to `/workspace`, path traversal blocked with `400`:\n\n```bash\ncurl \"http://localhost:8080/files\" -H \"Authorization: Bearer token\"                          # list root\ncurl \"http://localhost:8080/files/myproject/src\" -H \"Authorization: Bearer token\"            # list dir\ncurl \"http://localhost:8080/files/myproject/src/main.py\" -H \"Authorization: Bearer token\"    # download\ncurl -X PUT \"http://localhost:8080/files/myproject/src/main.py\" -H \"Authorization: Bearer token\" --data-binary @main.py\ncurl -X DELETE \"http://localhost:8080/files/myproject/src/old.py\" -H \"Authorization: Bearer token\"\n```\n\n`DELETE /files/{path}` removes a file under `/workspace` (no undo). Confirm the target path first, only remove files the current task created, and on a shared instance don't touch another caller's workspace — see [Security & safety](#security--safety).\n\n**Introspection and lifecycle:**\n\n```bash\ncurl http://localhost:8080/healthz                                                          # {\"ok\": true, \"adapter\": \"claude\"} — no auth\ncurl http://localhost:8080/status -H \"Authorization: Bearer token\"                           # {busyWorkspaces, runs}\ncurl -X DELETE \"http://localhost:8080/run/abc123\" -H \"Authorization: Bearer token\"            # cancel a run by id\n```\n\n## OpenAI-compatible endpoint mode\n\nSame API-mode server (`CLAUDEBOX_API_MODE=1`); no separate flag. `chat/completions`-shaped adapter for LiteLLM, OpenAI SDKs, or any client speaking that wire format. Every request runs the full agentic CLI, not just text generation — Claude can read/write files and run shell commands as part of answering.\n\n```bash\ncurl http://localhost:8080/openai/v1/models\n# {\"object\":\"list\",\"data\":[{\"id\":\"haiku\",...},{\"id\":\"sonnet\",...},{\"id\":\"opus\",...},{\"id\":\"opusplan\",...}]}\n\ncurl -X POST http://localhost:8080/openai/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"haiku\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}]}'\n\n# streaming\ncurl -X POST http://localhost:8080/openai/v1/chat/completions \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"haiku\",\"messages\":[{\"role\":\"user\",\"content\":\"hello\"}],\"stream\":true}'\n```\n\nModel aliases match the CLI (`haiku`/`sonnet`/`opus`/`opusplan`); provider prefixes are stripped (`claudebox/haiku` → `haiku`). `role: \"system\"` messages become `--system-prompt`. Single-user-message requests are the fast path (sent directly as the prompt); multi-turn conversations are serialized to a JSON file under `_oai_uploads/` in the workspace so Claude Code can read the full history. Multimodal `image_url` content (data URLs or `http(s)://`) is downloaded/decoded to the workspace and referenced by path.\n\nFor every native Claude record in an OpenAI stream, send\n`\"stream_options\": {\"include_aicodebox_events\": true}`. Claudebox emits a\nnamed `aicodebox.native` SSE event before normal OpenAI chunks. Its payload is\n`{sequence, attempt, backend, eventType, event}`. Standard chunks remain\nunchanged, so the extension stays opt-in for strict OpenAI SSE clients.\n\n`temperature` and `max_tokens` are accepted for OpenAI-client compatibility but have no effect on this adapter. `reasoning_effort` maps to the `claude --effort` flag: `low`, `medium`, `high`, `xhigh`, and `max` pass through, `minimal` maps to `low`, `none` or `off` keeps the default, and any other value is rejected. The `thinking` field on `/run` and MCP `run_prompt` works the same way.\n\n**Tool calling and structured output are supported, not ignored** — `tools`/`tool_choice` engage a client-executed function-calling bridge (Claude Code acts as a pure function-calling model, emits `tool_calls` for the *client* to run), and `response_format` (`json_object` or `json_schema`) constrains the final answer turn. Both can combine in one request. Because a tool call or schema-checked answer only exists once the full response is computed, `stream:true` combined with `tools` or a schema `response_format` returns a **buffered** single-shot SSE stream instead of token-incremental deltas — only plain chat (no tools, no schema) streams token-by-token.\n\nCustom headers for claudebox-specific behavior (canonical `x-aicodebox-*`, with legacy `X-Claude-*` aliases still accepted):\n\n| Header | Description |\n| --- | --- |\n| `x-aicodebox-workspace` (`X-Claude-Workspace`) | Workspace subpath under `/workspace` |\n| `x-aicodebox-continue` (`X-Claude-Continue`) | `1`/`true`/`yes` to continue the previous session |\n| `x-aicodebox-append-system-prompt` (`X-Claude-Append-System-Prompt`) | Text appended to the system prompt |\n| `x-aicodebox-json-schema` | JSON-schema string — fallback for clients that can't set `response_format` in the body (body field wins if both are set) |\n| `x-aicodebox-resume` | Resume a specific session id |\n| `x-aicodebox-tools-allowlist` | CSV or JSON array restricting Claude Code's own internal tools |\n| `x-aicodebox-no-tools` | Disable Claude Code's own internal tools (auto-defaulted on when in client tool-calling mode) |\n\nLiteLLM example:\n\n```python\nimport litellm\n\nresponse = litellm.completion(\n    model=\"claudebox/haiku\",\n    messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n    api_base=\"http://localhost:8080/openai/v1\",\n    api_key=\"your-secret-token\",  # any string if no API token is configured\n)\nprint(response.choices[0].message.content)\n```\n\n## MCP server mode\n\n`CLAUDEBOX_MCP_MODE=1` exposes a [Model Context Protocol](https://modelcontextprotocol.io/) server over streamable HTTP, using `CLAUDEBOX_MCP_MODE_TOKEN` as its bearer token (independent of the API token, no fallback; empty/unset = no auth). Where it listens depends on whether API mode is also on:\n\nWith `CLAUDEBOX_MCP_MODE_TOKEN` unset the MCP surface is unauthenticated — anyone who can reach it gets full tool access (run prompts, read/write/remove files under `/workspace`). Set the token and bind to loopback / behind an authenticating proxy before exposing it beyond localhost.\n\n- **`CLAUDEBOX_API_MODE=1` + `CLAUDEBOX_MCP_MODE=1`** (the setup the rest of the README documents) — MCP mounts at `/mcp` on the API port, no extra process.\n- **`CLAUDEBOX_MCP_MODE=1` alone** (or combined with Telegram/Cron/interactive mode) — MCP runs as an independent background process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), serving at the port root, not under `/mcp`.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_MCP_MODE=1\n  - CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"claudebox\": {\n      \"url\": \"http://localhost:8080/mcp/\",\n      \"headers\": { \"Authorization\": \"Bearer your-mcp-token\" }\n    }\n  }\n}\n```\n\nClients that can't set headers can pass the token as a query param instead: `http://localhost:8080/mcp/?apiToken=your-mcp-token`. Wire it into Claude Code directly:\n\n```bash\nclaude mcp add --transport http claudebox http://localhost:8080/mcp/ \\\n  --header \"Authorization: Bearer your-mcp-token\"\n```\n\n**Available tools:**\n\n| Tool | Description |\n| --- | --- |\n| `run_prompt` | Run a prompt through Claude Code. Args: `prompt`, `workspace`, `model`, `system_prompt`, `append_system_prompt`, `no_continue` (default `true`), `resume`, `thinking` (accepted, no effect on claudebox — see [OpenAI-compatible endpoint mode](#openai-compatible-endpoint-mode)), `json_schema`. Returns the assistant's text. |\n| `list_files` | List files/dirs under a workspace path. |\n| `read_file` | Read a file's text content. |\n| `write_file` | Write content to a file (creates parent dirs). |\n| `delete_file` | Delete a file (refuses directories). |\n\n`delete_file` removes a file under `/workspace` (no undo). Confirm the target path first and only remove files the current task created — see [Security & safety](#security--safety).\n\nRaw JSON-RPC for debugging (streamable-HTTP handshake — `initialize` then reuse the returned `mcp-session-id`):\n\n```bash\ncurl -s -D - -X POST \"http://localhost:8080/mcp/\" \\\n  -H \"Authorization: Bearer your-mcp-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"debug\",\"version\":\"1\"}}}'\n# capture the mcp-session-id response header, then:\ncurl -s -X POST \"http://localhost:8080/mcp/\" \\\n  -H \"Authorization: Bearer your-mcp-token\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json, text/event-stream\" \\\n  -H \"mcp-session-id: <session-id-from-above>\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}'\n```\n\n## Telegram bot mode\n\n`CLAUDEBOX_TELEGRAM_MODE=1` runs a conversational bot with per-chat isolated workspaces. Requires a config file — the bot refuses to start without one, to prevent accidentally exposing Claude to the public.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_TELEGRAM_MODE=1\n  - CLAUDEBOX_TELEGRAM_MODE_TOKEN=123456:ABC-DEF   # from @BotFather\n```\n\n`~/.claude/telegram.yml` (mounted into the container):\n\n```yaml\nallowed_chats:\n  - 123456789    # your DM (positive = user id)\n  - -987654321   # a group chat (negative)\n\ndefault:\n  model: sonnet\n  effort: high\n  continue: true\n\nchats:\n  123456789:\n    workspace: my-project\n    model: opus\n    system_prompt: \"You are a senior engineer\"\n```\n\nPer-chat overrides: `workspace`, `model`, `effort`, `continue`, `system_prompt`, `append_system_prompt`, `max_budget_usd`, `allowed_users` (group-chat allowlist).\n\nBot commands: any text message is a prompt; sending a file/photo/video/voice saves it to the workspace (caption becomes the prompt); `/model [name]`, `/effort [level]`, `/system_prompt [text]`, `/append_system_prompt [text]`, `/fetch <path>`, `/cancel`, `/status`, `/config`, `/reload`. Claude sends files back with `[SEND_FILE: relative/path]` in its response text.\n\n`effort` (config field and `/effort` command) is passed to the `claude` CLI as `--effort`. `off` keeps Claude Code's default effort.\n\n## Cron scheduler mode\n\n`CLAUDEBOX_CRON_MODE=1` runs YAML-defined Claude jobs on cron schedules (5-field standard, 6-field for sub-minute resolution). Foreground process — `docker logs` shows every tick.\n\n```yaml\nenvironment:\n  - CLAUDEBOX_CRON_MODE=1\n  - CLAUDEBOX_CRON_MODE_FILE=/home/aicode/.claude/cron.yaml\n  - CLAUDEBOX_WORKSPACE=/workspace\n```\n\n`cron.yaml`:\n\n```yaml\nmodel: haiku                       # default for all jobs; per-job \"model\" overrides\njobs:\n  - name: hourly_repo_check\n    schedule: \"0 * * * *\"          # 5-field standard cron\n    instruction: |\n      Look at the git log for the last hour. Summarize commits.\n  - name: every_30_seconds\n    schedule: \"*/30 * * * * *\"     # 6-field sub-minute\n    instruction: Write the current UTC timestamp to ./status.txt.\n```\n\nPer-job/root fields: `model`, `effort`, `system_prompt`, `append_system_prompt`, `telegram_chat_id` (requires `CLAUDEBOX_TELEGRAM_MODE_TOKEN`). Template vars usable in `instruction`/`system_prompt`/`append_system_prompt`: `{system_datetime}`, `{job_name}`. `effort` has the same no-effect caveat as [Telegram bot mode](#telegram-bot-mode) — accepted, not currently wired into the CLI invocation.\n\nOutput streams to `~/.claude/cron/history/<workspace-slug>/<YYYYMMDD-HHMMSS>-<job-name>/` (`activity.jsonl` stream-json, `stderr.log`, `meta.json`). Overlapping ticks are skipped, not queued. Combine with `CLAUDEBOX_TELEGRAM_MODE=1` to get results posted to Telegram and reply-to-interrogate on finished runs — see [references/setup.md](references/setup.md#cron--telegram-combined-mode).\n\n## Auth\n\nInteractive/exec/cron/CLI-driven modes need an Anthropic credential:\n\n```bash\nclaudebox setup-token                                        # interactive OAuth setup, one-time\nCLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN> claudebox -p \"do stuff\" # then reuse the token\n# or\nANTHROPIC_API_KEY=<YOUR_API_KEY> claudebox -p \"do stuff\"\n```\n\nServer modes gate their own HTTP surface independently, each with its own bearer token (unset = open):\n\n| Mode | Token var |\n| --- | --- |\n| API / OpenAI adapter | `CLAUDEBOX_API_MODE_TOKEN` |\n| MCP | `CLAUDEBOX_MCP_MODE_TOKEN` (separate from the API token, no fallback) |\n| Telegram | `CLAUDEBOX_TELEGRAM_MODE_TOKEN` (the bot token itself, not a bearer secret) |\n\nAll of these still need the underlying Anthropic credential (`CLAUDE_CODE_OAUTH_TOKEN` / `ANTHROPIC_API_KEY`) set in the container env to actually talk to the model.\n\n## Typical Workflows\n\n### Pipe a code review through CI\n\n```bash\nclaudebox -p \"review this diff for security issues\" --output-format json --model sonnet | jq -r .result\n```\n\n### Drive claudebox from another agent over MCP\n\n```bash\nclaude mcp add --transport http claudebox http://localhost:8080/mcp/ \\\n  --header \"Authorization: Bearer $CLAUDEBOX_MCP_MODE_TOKEN\"\n```\n\n### Fire-and-poll a long refactor over HTTP\n\n```bash\nRUN_ID=$(curl -s -X POST http://localhost:8080/run -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" \\\n  -d '{\"prompt\": \"refactor the auth module\", \"workspace\": \"myproject\", \"async\": true}' | jq -r .runId)\n\nuntil curl -s \"http://localhost:8080/run/result?runId=$RUN_ID\" -H \"Authorization: Bearer $TOKEN\" | jq -e '.status != \"running\"' >/dev/null; do\n  sleep 5\ndone\ncurl -s \"http://localhost:8080/run/result?runId=$RUN_ID\" -H \"Authorization: Bearer $TOKEN\" | jq\n```\n\n### Point LiteLLM at claudebox as an OpenAI-compatible backend\n\n```python\nimport litellm\nlitellm.completion(model=\"claudebox/sonnet\", messages=[{\"role\": \"user\", \"content\": \"hello\"}],\n                    api_base=\"http://localhost:8080/openai/v1\", api_key=API_TOKEN)\n```\n\n### Nightly cleanup job with Telegram notification\n\n```yaml\ntelegram_chat_id: -1001234567890\njobs:\n  - name: nightly_cleanup\n    schedule: \"0 3 * * *\"\n    instruction: Find files older than 7 days under ./tmp and delete them. Report what you removed.\n```\n\nFor install steps, docker run/compose invocations, the full env-var reference, port list, and container management commands, see [references/setup.md](references/setup.md).\n\nFile v2.4.6:_meta.json\n\n{\n  \"ownerId\": \"kn79dhvmpjng4rp2jjk8k0v5xx80ccbk\",\n  \"slug\": \"claudebox\",\n  \"version\": \"2.4.6\",\n  \"publishedAt\": 1790385971718\n}\n\nFile v2.4.6:references/setup.md\n\n# claudebox setup\n\n## Requirements\n\n- Docker installed and running. That's it — the wrapper handles the rest.\n- An Anthropic credential: `CLAUDE_CODE_OAUTH_TOKEN` (via `claudebox setup-token`) or `ANTHROPIC_API_KEY`.\n\nFor ordinary agent work, use the installed `claudebox` command from the target\nworkspace. Do not replace it with a hand-written Docker invocation. The\nwrapper handles the workspace, state, SSH, image, and nested launch context.\n\n## Quick Install (CLI wrapper)\n\nSafer path — download, inspect, then run:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh -o install.sh\nless install.sh   # read it before running anything you downloaded\nbash install.sh\n\n# full image variant\nexport CLAUDEBOX_FULL=1 && bash install.sh\n\n# custom binary name\nbash install.sh claude\n```\n\nDownloading and reading the script before running it is the recommended flow, especially in an agent-driven or CI context — it runs with your privileges.\n\nThe installer pulls the image, generates an ed25519 SSH key at `~/.ssh/claudebox/id_ed25519` for git operations inside the container, creates `~/.claude`, and installs the wrapper to `/usr/local/bin/claudebox` (override with `CLAUDEBOX_INSTALL_DIR` / `CLAUDEBOX_BIN_NAME`). Add the generated public key to GitHub/GitLab for git push/pull to work from inside the container.\n\n```bash\nclaudebox                                  # interactive\nclaudebox -p \"inspect this workspace\"      # one-shot\nCLAUDEBOX_FULL=1 claudebox -p \"run tests\"  # temporary full image\n```\n\nFor a wrapper-started server, use `CLAUDEBOX_ENV_` before every variable that\nmust reach the container. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` starts API mode.\n\nInstall `claudebox`, `codexbox`, and `pibox` in the same command directory,\nnormally `/usr/local/bin`, when one box needs to launch another. The parent\nmounts only sibling wrapper files read-only. A sibling wrapper then runs through\nthe host Docker daemon and mounts its own host data directory.\n\nManual setup without piping to bash: `mkdir -p ~/.claude`, generate the SSH key yourself, `docker pull psyb0t/claudebox:latest` (or `:latest-full`), then fetch `wrapper.sh` and install it as your `claudebox` binary.\n\n## Image Variants\n\n| | `psyb0t/claudebox:latest` (minimal, default) | `psyb0t/claudebox:latest-full` |\n| --- | --- | --- |\n| Base | Ubuntu 24.04, git/curl/wget/jq, Node.js 24 LTS, Python 3.14 + uv, Docker CE | same, plus everything below |\n| Go | — | 1.26 toolchain (golangci-lint, gopls, delve, staticcheck, gofumpt, gotests, impl, gomodifytags) |\n| Python | — | 3.14 via pyenv (flake8, black, isort, pyright, mypy, vulture, pytest, poetry, pipenv) |\n| Node dev tools | — | eslint, prettier, typescript, yarn, pnpm, framework CLIs |\n| C/C++ | — | gcc, g++, make, cmake, clang-format, valgrind, gdb |\n| DevOps | — | terraform, kubectl, helm, gh |\n| DB clients | — | sqlite3, psql, mysql, redis-cli |\n| Shell utils | — | ripgrep, bat, exa, fd-find, ag, htop, tmux, shellcheck, shfmt |\n\nMinimal has passwordless sudo, so Claude installs whatever else it needs via `apt-get`/`pip`/`npm` on the fly — smaller pull, slower first task. Use `/aicodebox-init.d/*.sh` hooks to pre-install tooling on first container create instead of burning tokens on package management.\n\n`CLAUDEBOX_FULL=1` at install time bakes the full-variant choice into the wrapper permanently; at runtime it overrides per-invocation. Pre-v2 `CLAUDEBOX_MINIMAL=1` is a no-op (minimal is already the default).\n\n## docker run / docker-compose\n\n### Interactive / exec (via the wrapper — recommended)\n\nThe installed `claudebox` wrapper handles container naming, volume mounts, SSH key mounting, and auth forwarding automatically. Don't hand-roll `docker run` for interactive/exec use — install the wrapper instead (see Quick Install above).\n\n### Server modes (API / OpenAI / MCP / Telegram / Cron)\n\n```yaml\n# docker-compose.yml\nservices:\n  claudebox:\n    image: psyb0t/claudebox:latest\n    ports:\n      - \"8080:8080\"\n    environment:\n      - CLAUDEBOX_API_MODE=1\n      - CLAUDEBOX_API_MODE_TOKEN=your-secret-token\n      - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan\n      - CLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN>\n    volumes:\n      - ~/.claude:/home/aicode/.claude\n      - /your/projects:/workspace\n      - /var/run/docker.sock:/var/run/docker.sock\n```\n\nMounting `/var/run/docker.sock` grants host-level container control — anything that can reach the socket (including Claude itself, by design, or an attacker who compromises the API/MCP surface above) can create, inspect, or destroy any container on the host, not just this one. Only mount it on a host you trust, and only if you need docker-in-docker for this workload.\n\nAdd `CLAUDEBOX_MCP_MODE=1` + `CLAUDEBOX_MCP_MODE_TOKEN` alongside `CLAUDEBOX_API_MODE=1` to mount MCP on the same port. Set `CLAUDEBOX_TELEGRAM_MODE=1` + `CLAUDEBOX_TELEGRAM_MODE_TOKEN` for the bot, or `CLAUDEBOX_CRON_MODE=1` + `CLAUDEBOX_CRON_MODE_FILE` for the scheduler — any combination can run in the same container (e.g. cron + Telegram share one workspace).\n\n## Runtime Hardening (recommended `docker run` flags)\n\n- `--cap-drop=ALL --cap-add=NET_BIND_SERVICE` — drop every Linux capability, add back only bind-below-1024 if needed.\n- `--security-opt no-new-privileges:true` — block setuid privilege escalation inside the container.\n- `--memory=2g --cpus=2 --pids-limit=512` — cap resource use so a runaway process can't starve the host.\n- `--read-only --tmpfs /tmp:rw,noexec,nosuid` — only if you don't need `/workspace` writes, otherwise skip.\n\nThe container drops from root to `aicode` (UID 1000) at boot via `setpriv`, so the process running your code is never root even without `--user`.\n\n## Environment Variable Reference\n\nAll wrapper/installer config uses the `CLAUDEBOX_*` prefix; the entrypoint aliases each to `AICODEBOX_*` (the base image's canonical names) when the target is unset — `AICODEBOX_*` wins if both are set. Legacy pre-v2 `CLAUDE_*` / `CLAUDE_MODE_*` names still work as fallbacks.\n\n### Wrapper / installer\n\n| Variable | Description | Default |\n| --- | --- | --- |\n| `CLAUDEBOX_GIT_NAME` / `CLAUDEBOX_GIT_EMAIL` | Git identity inside the container | _(none)_ |\n| `CLAUDEBOX_DATA_DIR` | Host path for the `.claude` data dir | `~/.claude` |\n| `CLAUDEBOX_SSH_DIR` | Host path for the SSH key directory | `~/.ssh/claudebox` |\n| `CLAUDEBOX_INSTALL_DIR` | Wrapper binary install location (install-time) | `/usr/local/bin` |\n| `CLAUDEBOX_BIN_NAME` | Wrapper binary name (install-time) | `claudebox` |\n| `CLAUDEBOX_IMAGE` | Override the Docker image | `psyb0t/claudebox:latest` |\n| `CLAUDEBOX_FULL` | Use the `latest-full` toolchain image instead of minimal | _(none)_ |\n| `CLAUDEBOX_CONTAINER_NAME` | Override the per-workspace container name | derived from `$PWD` |\n| `CLAUDEBOX_MAX_MEM` | Per-container memory limit | `10g` |\n| `CLAUDEBOX_ENV_*` | Forward arbitrary vars into the container (prefix stripped) | _(none)_ |\n| `CLAUDEBOX_MOUNT_*` | Mount extra host directories | _(none)_ |\n\nAuth/in-container settings route through `CLAUDEBOX_ENV_*`:\n\n```bash\nCLAUDEBOX_ENV_ANTHROPIC_API_KEY=your-api-key claudebox -p \"do stuff\"\nCLAUDEBOX_ENV_CLAUDE_CODE_OAUTH_TOKEN=<YOUR_OAUTH_TOKEN> claudebox -p \"do stuff\"\nCLAUDEBOX_ENV_DEBUG=true claudebox -p \"do stuff\"          # structured JSON debug logging\n```\n\nExtra mounts:\n\n```bash\nCLAUDEBOX_MOUNT_DATA=/data claudebox -p \"process the data\"                   # same path both sides\nCLAUDEBOX_MOUNT_1=/opt/configs CLAUDEBOX_MOUNT_2=/var/logs claudebox -p \"go\" # multiple mounts\nCLAUDEBOX_MOUNT_STUFF=/host/path:/container/path claudebox -p \"do stuff\"     # explicit src:dst\nCLAUDEBOX_MOUNT_RO=/data:/data:ro claudebox -p \"read the data\"               # read-only\n```\n\n### Server modes\n\n| Variable | Description | Default |\n| --- | --- | --- |\n| `CLAUDEBOX_API_MODE` | `1` to start the HTTP API server | _(none)_ |\n| `CLAUDEBOX_API_MODE_PORT` | API server port | `8080` |\n| `CLAUDEBOX_API_MODE_TOKEN` | Bearer token for `/run`, `/files`, `/status`, `/openai/*` | _(none — no auth)_ |\n| `CLAUDEBOX_AVAILABLE_MODELS` | CSV of model aliases surfaced at `/openai/v1/models`. Optional — claudebox's adapter has a built-in default (`haiku,sonnet,opus,opusplan`); set this to override it. The API server only refuses to boot if the resolved list ends up empty. | _(none — adapter default applies)_ |\n| `CLAUDEBOX_AVAILABLE_EFFORTS` | CSV of effort levels surfaced to Telegram `/effort` picker | adapter default |\n| `CLAUDEBOX_MCP_MODE` | `1` to expose MCP. Mounts at `/mcp` on the API port if `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone on its own port | _(none)_ |\n| `CLAUDEBOX_MCP_MODE_PORT` | Port for the standalone MCP process (only used when API mode is off) | `8081` |\n| `CLAUDEBOX_MCP_MODE_TOKEN` | Bearer token for MCP (independent of the API token, no fallback) | _(none — no auth)_ |\n| `CLAUDEBOX_TELEGRAM_MODE` | `1` to start the Telegram bot | _(none)_ |\n| `CLAUDEBOX_TELEGRAM_MODE_TOKEN` | Bot token from [@BotFather](https://t.me/BotFather) | _(none)_ |\n| `CLAUDEBOX_TELEGRAM_MODE_CONFIG` | Path to `telegram.yml` inside the container | `/home/aicode/.claude/telegram.yml` |\n| `CLAUDEBOX_CRON_MODE` | `1` to start the cron scheduler | _(none)_ |\n| `CLAUDEBOX_CRON_MODE_FILE` | Path to the cron YAML inside the container | _(none)_ |\n| `CLAUDEBOX_WORKSPACE` | Absolute workspace path (cwd for every mode) | `/workspace` |\n| `CLAUDEBOX_ALWAYS_SKILLS_DIR` | Where `SKILL.md` files are scanned for always-active injection | `/home/aicode/.claude/.always-skills` |\n| `CLAUDEBOX_SYSTEM_HINT_FILE` | Text prepended to `--append-system-prompt` on every call | `/home/aicode/.claude/system-hint.txt` |\n| `DEBUG` | `1`/`true` for structured JSON debug logging | _(none)_ |\n\nLegacy fallbacks still accepted: `CLAUDE_MODE_API`/`CLAUDE_MODE_API_PORT`/`CLAUDE_MODE_API_TOKEN`, `CLAUDE_MODE_TELEGRAM`, `CLAUDE_MODE_CRON`/`CLAUDE_MODE_CRON_FILE`, `CLAUDE_WORKSPACE`, `CLAUDE_TELEGRAM_BOT_TOKEN`, `CLAUDE_TELEGRAM_CONFIG`.\n\n## Ports\n\n| Port | Service |\n| --- | --- |\n| 8080 (default, `CLAUDEBOX_API_MODE_PORT`) | HTTP API + OpenAI adapter, and MCP (`/mcp`) if `CLAUDEBOX_MCP_MODE=1` is also set |\n| 8081 (default, `CLAUDEBOX_MCP_MODE_PORT`) | Standalone MCP, only when `CLAUDEBOX_MCP_MODE=1` is set without `CLAUDEBOX_API_MODE=1` |\n\nMCP either mounts onto the API port or runs on its own port — never both at once, depending on whether API mode is also enabled.\n\n## Cron + Telegram Combined Mode\n\nSet both `CLAUDEBOX_CRON_MODE=1` and `CLAUDEBOX_TELEGRAM_MODE=1` in the same container: a single workspace shared between the cron scheduler (background) and the bot (foreground); when the bot exits, the scheduler is killed too.\n\n- Cron jobs post results to Telegram automatically when `telegram_chat_id` is set (root default and/or per-job override) in `cron.yaml`.\n- Reply to a cron notification message to interrogate that run — the bot detects the reply, looks up the original job (name, timestamp, instruction, result), and prepends that context to a fresh session.\n- The whole chat gets the last ~10 cron runs injected via `--append-system-prompt`, so Claude can answer cron questions anywhere in the conversation.\n\nSent message IDs and job context are stored in `~/.claude/cron/telegram_messages.json` (auto-pruned to the last 200 entries).\n\n## MCP Servers claudebox Itself Can Use\n\nIndependent of exposing claudebox *as* an MCP server (MCP mode above), Claude Code running inside claudebox can also *consume* MCP servers you configure — same mechanism as any Claude Code install:\n\n| Scope | Path | Notes |\n| --- | --- | --- |\n| Project | `<workspace>/.mcp.json` | Checked into git, shared by the team |\n| User | `~/.claude.json` under `mcpServers` | Global, every project on the host |\n| Local | `~/.claude.json` per-project section | Default scope of `claude mcp add` |\n\n```bash\nclaudebox mcp add --scope project my-server -- npx -y @some/mcp-server\nclaudebox mcp add --scope user my-server -- npx -y @some/mcp-server\n```\n\nRun `/mcp` inside an interactive session to inspect what's loaded. This is how cron and Telegram modes reach external systems (post to Discord/Slack/email/webhooks) — configure the server, reference it from the job instruction or chat.\n\n## Customization\n\n- **Custom scripts (`~/.claude/bin`)** — any executable placed here is on PATH in every mode.\n- **Init hooks (`~/.claude/init.d/*.sh`)** — run once as root on first container create, before the entrypoint drops to `aicode`. Good for pre-installing tools on the minimal image.\n- **Always-active skills (`~/.claude/.always-skills/`)** — every `SKILL.md` found (recursive, alphabetical) is appended to `--append-system-prompt` on every invocation, across all modes, prefixed with `[Skill file: <path>]`.\n\n## Gotchas\n\n- `--permission-mode bypassPermissions` is the default — Claude has full, unrestricted access to the container. Override per-request via `RunRequest.extra_args` at the API layer.\n- SSH keys are mounted from the host for git push/pull. Don't share your container or image with untrusted parties.\n- Host paths are preserved — a project at `/home/you/project` mounts at the same path inside the container, so Docker volume mounts Claude creates from within it resolve correctly against the host.\n- UID/GID of the `aicode` user auto-adjusts to match the host directory owner at startup.\n- The Docker socket is mounted in — Claude can build images and run containers from within its own container, by design.\n- Two containers per workspace: `claude-<path>` for interactive (TTY), `claude-<path>_prog` for one-shot exec (no TTY). Both share mounted volumes and data.\n- API-mode workspace busy tracking: one active Claude process per workspace; concurrent requests to the same workspace get `409`.\n- Telegram mode requires `telegram.yml` to exist — refuses to boot silently exposed.\n- Claude Code CLI auto-updates are disabled inside the container by default; opt in with `claudebox --update`.\n\n## Management\n\n```bash\ndocker logs -f <container>       # tail logs (structured JSON in server modes)\nclaudebox stop                   # stop the interactive container for this workspace\nclaudebox clear-session          # delete session history for this workspace\ndocker pull psyb0t/claudebox:latest       # update (minimal)\ndocker pull psyb0t/claudebox:latest-full  # update (full)\n```\n\nFile v2.4.6:skill-card.md\n\n## Description:\n\nInstall, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[psyb0t](https://clawhub.ai/user/psyb0t)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers use claudebox to run Claude Code in a Docker container for coding tasks, or connect other tools to its HTTP, MCP, Telegram, and scheduled-job interfaces.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Claude Code runs with broad shell and file permissions inside the container.\n\nMitigation: Use only with trusted prompts and workspaces; isolate the container before handling untrusted input.\n\nRisk: HTTP and MCP modes can expose agent execution and workspace files without authentication if tokens are unset.\n\nMitigation: Set distinct API and MCP bearer tokens and bind services to localhost or a trusted network.\n\nRisk: Mounting the Docker socket can grant host-level container control.\n\nMitigation: Avoid mounting /var/run/docker.sock unless necessary, and restrict access to trusted users.\n\nRisk: Remote install scripts and changing images or packages can introduce unexpected behavior.\n\nMitigation: Review downloaded installers before execution and consider pinning images and packages for production use.\n\n## Reference(s):\n\n- [claudebox on ClawHub](https://clawhub.ai/psyb0t/skills/claudebox)\n- [claudebox project homepage](https://github.com/psyb0t/docker-claudebox)\n- [claudebox setup guide](artifact/references/setup.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Shell commands, Configuration instructions, Code]\n\n**Output Format:** [Markdown with shell commands and configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [None]\n\n## Skill Version(s):\n\n2.4.6 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v2.4.5: 4 files, 17475 bytes\n\nFiles: references/setup.md (14461b), skill-card.md (2804b), SKILL.md (26199b), _meta.json (128b)\n\nFile v2.4.5:SKILL.md\n\n---\nname: claudebox\ndescription: \"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\"\nhomepage: https://github.com/psyb0t/docker-claudebox\nuser-invocable: true\nmetadata:\n  { \"openclaw\": { \"emoji\": \"📦\", \"primaryEnv\": \"CLAUDEBOX_URL\", \"requires\": { \"bins\": [\"docker\", \"curl\"] } } }\n---\n\n# claudebox\n\nClaude Code — the agentic coding CLI from Anthropic — running in an isolated Docker container with dev tools, passwordless sudo, docker-in-docker, and `--permission-mode bypassPermissions` on by default. Built as a thin child image of `psyb0t/aicodebox`; every server-mode surface (API / OpenAI adapter / MCP / Telegram / Cron) is inherited from that base.\n\n## Agent execution\n\nUse `claudebox` when it is on `PATH`. Run it from the workspace the user\nnamed. Do not assemble a new `docker run` command for routine interactive or\none-shot work. The wrapper owns the workspace mount, `~/.claude`, SSH state,\nimage selection, and session lifecycle.\n\n```bash\nclaudebox                                      # interactive Claude Code\nclaudebox -p \"inspect this workspace\"          # one-shot work\nclaudebox -p \"emit events\" --output-format stream-json\nCLAUDEBOX_FULL=1 claudebox -p \"run the full suite\"\n```\n\nFor a wrapper-started server, prefix container variables with\n`CLAUDEBOX_ENV_`. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` passes\n`CLAUDEBOX_API_MODE=1` into the container. Bare `CLAUDEBOX_API_MODE` is not\nforwarded and does not start the server.\n\nStart a local API and MCP server only when the user asks for one. Authenticate\nClaude first, then use distinct bearer tokens for the two surfaces:\n\n```bash\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE_TOKEN=your-api-token \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token \\\nclaudebox\n```\n\nUse an HTTP or MCP endpoint only when the user asks for a service or provides\nan already-running remote URL. MCP plugins connect to a server. They do not\nreplace the local wrapper.\n\nIf `claudebox`, `codexbox`, and `pibox` were installed in the same command\ndirectory, a box can invoke a sibling command directly. The parent wrapper\npasses the real host paths and the sibling wrapper file. Do not set\n`AICODEBOX_HOST_*`, copy wrapper files, or manually mount another box's state\ndirectory. If the sibling command is absent, ask the user to install it or to\nchoose another approach.\n\n## Security & safety\n\n- **No auth when the per-mode token is unset.** `CLAUDEBOX_API_MODE_TOKEN` and `CLAUDEBOX_MCP_MODE_TOKEN` each default to no auth if unset — see [HTTP REST API mode](#http-rest-api-mode) and [MCP server mode](#mcp-server-mode) for details and the exact capability exposed unauthenticated in each case.\n- **File operations include removal.** Deleting a workspace file has no undo — only remove files the current task created, and only when the user asked.\n- **Mounting `/var/run/docker.sock` grants host-level container control** — see [Server modes (API / OpenAI / MCP / Telegram / Cron)](references/setup.md#server-modes-api--openai--mcp--telegram--cron) in `references/setup.md`, only do this on a host you trust.\n- **`--permission-mode bypassPermissions` is on by default** — Claude has full, unrestricted shell/file/docker access inside the container by design (see [When NOT To Use](#when-not-to-use)). Don't treat the container boundary as a sandbox for untrusted input unless you've isolated the container itself.\n- **Install script is piped from curl into bash by default** — a safer download-inspect-run alternative is documented alongside it; see [references/setup.md](references/setup.md#quick-install-cli-wrapper).\n\nSeven programmatic surfaces, all reachable from the same container image, selected by which `CLAUDEBOX_*_MODE` env flags are set at boot:\n\n- **Interactive shell** — `claudebox` drops you into the native `claude` CLI, container-backed, with automatic session resumption.\n- **One-shot exec**: `claudebox -p \"prompt\" [flags]`, non-interactive, prompt in / structured output out, for scripts and CI.\n- **HTTP REST API** — `CLAUDEBOX_API_MODE=1`. `POST /run`, async runs polled via `GET /run/result?runId=`, `GET/PUT/DELETE /files/{path}`, workspace isolation.\n- **OpenAI-compatible endpoint** — same API-mode server, `/openai/v1/chat/completions` + `/openai/v1/models`. Streaming SSE, multi-turn, multimodal image input.\n- **MCP server** — `CLAUDEBOX_MCP_MODE=1`, 5 tools over streamable HTTP. Mounts at `/mcp` on the API port when `CLAUDEBOX_API_MODE=1` is also set; otherwise runs standalone as a sidecar process on its own port (`CLAUDEBOX_MCP_MODE_PORT`, default `8081`), coexisting with Telegram/Cron/interactive mode.\n- **Telegram bot** — `CLAUDEBOX_TELEGRAM_MODE=1`, per-chat isolated workspaces, file/photo/video/voice ingestion, slash commands.\n- **Cron scheduler** — `CLAUDEBOX_CRON_MODE=1`, YAML-defined jobs on 5- or 6-field cron schedules, per-job activity history.\n\nFor installation and configuration, see [references/setup.md](references/setup.md).\n\n## When To Use\n\n- Run Claude Code from a script, Makefile target, or CI pipeline without a TTY (`claudebox -p \"explain this diff\" --output-format json`).\n- Expose Claude Code as an HTTP backend other services can `POST /run` against, with workspace isolation for multi-tenant use.\n- Point an OpenAI SDK / LiteLLM at a self-hosted agentic backend instead of a plain model API — every completion runs the full Claude Code CLI (file I/O, shell, tools), not just text generation.\n- Let another MCP-aware agent (Claude Desktop, another Claude Code instance, an agent framework) use this Claude Code instance as a tool over `/mcp`.\n- Run Claude from Telegram — ask questions, share files, get shell access, from your phone.\n- Schedule recurring Claude jobs (nightly cleanup, hourly repo checks) with per-run history and optional Telegram result delivery.\n\n## When NOT To Use\n\n- Real-time token-by-token streaming for tool-calling or JSON-schema-constrained runs — the OpenAI adapter buffers those (computes the full answer, replays as one SSE burst). Only plain chat (no `tools`, no `response_format` schema) streams incrementally.\n- Multiple concurrent requests against the *same* workspace — API mode enforces one active Claude process per workspace and returns `409` on conflict. Use distinct `workspace` subpaths for parallel work.\n- Treating `--permission-mode bypassPermissions` as sandboxed-safe for untrusted input — Claude has full container access by design (shell, docker-in-docker, mounted SSH keys). Isolate the container itself if the input is untrusted.\n- Expecting one fixed MCP path — it's `/mcp` (mounted, requires `CLAUDEBOX_API_MODE=1` too) in the documented API-mode setup, but a different, unmounted standalone port (`CLAUDEBOX_MCP_MODE_PORT`) when MCP mode runs without API mode. Match your client config to which one you actually launched.\n\n## Interactive shell mode\n\nDrop-in replacement for the native `claude` command, container-backed:\n\n```bash\nclaudebox                  # interactive session, --continue applied automatically\nclaudebox --no-continue    # start a fresh session instead of resuming\nclaudebox --update         # opt in to a Claude Code CLI update this run\n```\n\nUtility commands pass through without entering interactive mode:\n\n```bash\nclaudebox --version         # claude CLI version\nclaudebox doctor            # health checks\nclaudebox auth              # manage authentication\nclaudebox mcp <args...>     # manage MCP servers, e.g. `claudebox mcp list`\nclaudebox setup-token       # interactive OAuth token setup\nclaudebox stop              # stop the running interactive container for this workspace\nclaudebox clear-session     # delete session history for this workspace\n```\n\nNo mode flag needed — this is the default when you run `claudebox` with no `CLAUDEBOX_*_MODE` env vars set. Auth: `ANTHROPIC_API_KEY` or `CLAUDE_CODE_OAUTH_TOKEN` (see [Auth](#auth)).\n\n## One-shot exec mode\n\nNon-interactive prompt-in/response-out. Pass `-p` for scripts, CI, cron, or\nanywhere without a TTY:\n\n```bash\nclaudebox -p \"explain this codebase\"                                       # plain text (default)\nclaudebox -p \"explain this codebase\" --output-format json                  # structured JSON\nclaudebox -p \"list all TODOs\" --output-format stream-json | jq .           # complete native NDJSON\nclaudebox -p \"explain this codebase\" --model opus                          # pick a model\nclaudebox -p \"review this\" --system-prompt \"You are a security auditor\"    # replace system prompt\nclaudebox -p \"review this\" --append-system-prompt \"Focus on SQL injection\" # append to system prompt\nclaudebox -p \"debug this\" --effort max                                     # max reasoning effort\nclaudebox -p \"start over\" --no-continue                                    # fresh session\nclaudebox -p \"keep going\" --resume abc123-def456                           # resume a specific session\n\n# JSON-schema-constrained output\nclaudebox -p \"extract the author and title\" --output-format json \\\n  --json-schema '{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\"]}'\n```\n\n`--continue` is applied automatically so successive runs in the same workspace\nshare context. Use `--no-continue` for a clean slate or `--resume <session_id>`\nfor a specific one. Model aliases: `haiku`, `sonnet`, `opus`, `opusplan`,\n`sonnet[1m]`. The wrapper requires `-p` to select this mode.\n\n## HTTP REST API mode\n\n`CLAUDEBOX_API_MODE=1` starts a long-lived FastAPI server (default port `8080`, `CLAUDEBOX_API_MODE_PORT` to override). Bearer auth via `CLAUDEBOX_API_MODE_TOKEN` (unset = no auth).\n\nWith `CLAUDEBOX_API_MODE_TOKEN` unset the API surface is unauthenticated — anyone who can reach it gets full `/run` (arbitrary-prompt agentic execution) and `/files` (read/write anywhere under `/workspace`) access. Set the token and bind to loopback / behind an authenticating proxy before exposing i\n\nArchive v2.4.4: 4 files, 17260 bytes\n\nFiles: references/setup.md (14461b), skill-card.md (2265b), SKILL.md (26199b), _meta.json (128b)\n\nArchive v2.4.3: 4 files, 17420 bytes\n\nFiles: references/setup.md (14461b), skill-card.md (2719b), SKILL.md (26199b), _meta.json (128b)\n\nArchive v2.4.2: 4 files, 16805 bytes\n\nFiles: references/setup.md (13860b), skill-card.md (2580b), SKILL.md (25201b), _meta.json (128b)\n\nArchive v2.4.1: 4 files, 16740 bytes\n\nFiles: references/setup.md (13833b), skill-card.md (2694b), SKILL.md (25047b), _meta.json (128b)\n\nArchive v2.4.0: 4 files, 16540 bytes\n\nFiles: references/setup.md (13536b), skill-card.md (2514b), SKILL.md (25047b), _meta.json (128b)\n\nArchive v2.3.12: 4 files, 16605 bytes\n\nFiles: references/setup.md (13536b), skill-card.md (2586b), SKILL.md (25047b), _meta.json (129b)","readmeExcerpt":"Skill: claudebox Owner: psyb0t Summary: Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces. Tags: latest:2.5.0 Version history: v2.5.0 | 2026-10-07T17:20:21.602Z | auto cluedebox v2.5.0 changelog: - Updated reference documentation in references/setup.md. - Removed skill-card.md file. - No changes to command-line interface or functionality—docu","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"claudebox                                      # interactive Claude Code\nclaudebox -p \"inspect this workspace\"          # one-shot work\nclaudebox -p \"emit events\" --output-format stream-json\nCLAUDEBOX_FULL=1 claudebox -p \"run the full suite\""},{"language":"bash","snippet":"CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE_TOKEN=your-api-token \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token \\\nclaudebox"},{"language":"bash","snippet":"claudebox                  # interactive session, --continue applied automatically\nclaudebox --no-continue    # start a fresh session instead of resuming\nclaudebox --update         # opt in to a Claude Code CLI update this run"},{"language":"bash","snippet":"claudebox --version         # claude CLI version\nclaudebox doctor            # health checks\nclaudebox auth              # manage authentication\nclaudebox mcp <args...>     # manage MCP servers, e.g. `claudebox mcp list`\nclaudebox setup-token       # interactive OAuth token setup\nclaudebox stop              # stop the running interactive container for this workspace\nclaudebox clear-session     # delete session history for this workspace"},{"language":"bash","snippet":"claudebox -p \"explain this codebase\"                                       # plain text (default)\nclaudebox -p \"explain this codebase\" --output-format json                  # structured JSON\nclaudebox -p \"list all TODOs\" --output-format stream-json | jq .           # complete native NDJSON\nclaudebox -p \"explain this codebase\" --model opus                          # pick a model\nclaudebox -p \"review this\" --system-prompt \"You are a security auditor\"    # replace system prompt\nclaudebox -p \"review this\" --append-system-prompt \"Focus on SQL injection\" # append to system prompt\nclaudebox -p \"debug this\" --effort max                                     # max reasoning effort\nclaudebox -p \"start over\" --no-continue                                    # fresh session\nclaudebox -p \"keep going\" --resume abc123-def456                           # resume a specific session\n\n# JSON-schema-constrained output\nclaudebox -p \"extract the author and title\" --output-format json \\\n  --json-schema '{\"type\":\"object\",\"properties\":{\"author\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}},\"required\":[\"author\",\"title\"]}'"},{"language":"yaml","snippet":"environment:\n  - CLAUDEBOX_API_MODE=1\n  - CLAUDEBOX_API_MODE_TOKEN=your-secret-token\n  - CLAUDEBOX_AVAILABLE_MODELS=haiku,sonnet,opus,opusplan  # optional — overrides the adapter's built-in default list"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: claudebox\ndescription: \"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces.\"\nhomepage: https://github.com/psyb0t/docker-claudebox\nuser-invocable: true\nmetadata:\n  { \"openclaw\": { \"emoji\": \"📦\", \"primaryEnv\": \"CLAUDEBOX_URL\", \"requires\": { \"bins\": [\"docker\", \"curl\"] } } }\n---\n\n# claudebox\n\nClaude Code — the agentic coding CLI from Anthropic — running in an isolated Docker container with dev tools, passwordless sudo, docker-in-docker, and `--permission-mode bypassPermissions` on by default. Built as a thin child image of `psyb0t/aicodebox`; every server-mode surface (API / OpenAI adapter / MCP / Telegram / Cron) is inherited from that base.\n\n## Agent execution\n\nUse `claudebox` when it is on `PATH`. Run it from the workspace the user\nnamed. Do not assemble a new `docker run` command for routine interactive or\none-shot work. The wrapper owns the workspace mount, `~/.claude`, SSH state,\nimage selection, and session lifecycle.\n\n```bash\nclaudebox                                      # interactive Claude Code\nclaudebox -p \"inspect this workspace\"          # one-shot work\nclaudebox -p \"emit events\" --output-format stream-json\nCLAUDEBOX_FULL=1 claudebox -p \"run the full suite\"\n```\n\nFor a wrapper-started server, prefix container variables with\n`CLAUDEBOX_ENV_`. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` passes\n`CLAUDEBOX_API_MODE=1` into the container. Bare `CLAUDEBOX_API_MODE` is not\nforwarded and does not start the server.\n\nStart a local API and MCP server only when the user asks for one. Authenticate\nClaude first, then use distinct bearer tokens for the two surfaces:\n\n```bash\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE=1 \\\nCLAUDEBOX_ENV_CLAUDEBOX_API_MODE_TOKEN=your-api-token \\\nCLAUDEBOX_ENV_CLAUDEBOX_MCP_MODE_TOKEN=your-mcp-token \\\nclaudebox\n```\n\nUse an HTTP or MCP endpoint only when the user asks for a service or provides\nan already-running remote URL. MCP plugins connect to a server. They do not\nreplace the local wrapper.\n\nIf `claudebox`, `codexbox`, and `pibox` were installed in the same command\ndirectory, a box can invoke a sibling command directly. The parent wrapper\npasses the real host paths and the sibling wrapper file. Do not set\n`AICODEBOX_HOST_*`, copy wrapper files, or manually mount another box's state\ndirectory. If the sibling command is absent, ask the user to install it or to\nchoose another approach.\n\n## Security & safety\n\n- **No auth when the per-mode token is unset.** `CLAUDEBOX_API_MODE_TOKEN` and `CLAUDEBOX_MCP_MODE_TOKEN` each default to no auth if unset — see [HTTP REST API mode](#http-rest-api-mode) and [MCP server mode](#mcp-server-mode) for details and the exact capability exposed unauthenticated in each case.\n- **File operations include removal.** Deleting a workspace file has no undo — only remove files the current task created, and only when the user asked.\n- **The standard wrapper mounts `/var/run/d"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn79dhvmpjng4rp2jjk8k0v5xx80ccbk\",\n  \"slug\": \"claudebox\",\n  \"version\": \"2.5.0\",\n  \"publishedAt\": 1791393621602\n}"},{"path":"references/setup.md","content":"# claudebox setup\n\n## Requirements\n\n- Docker installed and running. That's it — the wrapper handles the rest.\n- An Anthropic credential: `CLAUDE_CODE_OAUTH_TOKEN` (via `claudebox setup-token`) or `ANTHROPIC_API_KEY`.\n\nFor ordinary agent work, use the installed `claudebox` command from the target\nworkspace. Do not replace it with a hand-written Docker invocation. The\nwrapper handles the workspace, state, SSH, image, and nested launch context.\n\n## Quick Install (CLI wrapper)\n\nSafer path — download, inspect, then run:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/psyb0t/docker-claudebox/master/install.sh -o install.sh\nless install.sh   # read it before running anything you downloaded\nbash install.sh\n\n# full image variant\nexport CLAUDEBOX_FULL=1 && bash install.sh\n\n# custom binary name\nbash install.sh claude\n```\n\nDownloading and reading the script before running it is the recommended flow, especially in an agent-driven or CI context — it runs with your privileges.\n\nThe installer pulls the image, generates an ed25519 SSH key at `~/.ssh/claudebox/id_ed25519` for git operations inside the container, creates `~/.claude`, and installs the wrapper to `/usr/local/bin/claudebox` (override with `CLAUDEBOX_INSTALL_DIR` / `CLAUDEBOX_BIN_NAME`). Add the generated public key to GitHub/GitLab for git push/pull to work from inside the container.\n\n```bash\nclaudebox                                  # interactive\nclaudebox -p \"inspect this workspace\"      # one-shot\nCLAUDEBOX_FULL=1 claudebox -p \"run tests\"  # temporary full image\n```\n\nFor a wrapper-started server, use `CLAUDEBOX_ENV_` before every variable that\nmust reach the container. For example,\n`CLAUDEBOX_ENV_CLAUDEBOX_API_MODE=1 claudebox` starts API mode.\n\nInstall `claudebox`, `codexbox`, and `pibox` in the same command directory,\nnormally `/usr/local/bin`, when one box needs to launch another. The parent\nmounts only sibling wrapper files read-only. A sibling wrapper then runs through\nthe host Docker daemon and mounts its own host data directory.\n\nManual setup without piping to bash: `mkdir -p ~/.claude`, generate the SSH key yourself, `docker pull psyb0t/claudebox:latest` (or `:latest-full`), then fetch `wrapper.sh` and install it as your `claudebox` binary.\n\n## Image Variants\n\n| | `psyb0t/claudebox:latest` (minimal, default) | `psyb0t/claudebox:latest-full` |\n| --- | --- | --- |\n| Base | Ubuntu 24.04, git/curl/wget/jq, Node.js 24 LTS, Python 3.14 + uv, Docker CE | same, plus everything below |\n| Go | — | 1.26 toolchain (golangci-lint, gopls, delve, staticcheck, gofumpt, gotests, impl, gomodifytags) |\n| Python | — | 3.14 via pyenv (flake8, black, isort, pyright, mypy, vulture, pytest, poetry, pipenv) |\n| Node dev tools | — | eslint, prettier, typescript, yarn, pnpm, framework CLIs |\n| C/C++ | — | gcc, g++, make, cmake, clang-format, valgrind, gdb |\n| DevOps | — | terraform, kubectl, helm, gh |\n| DB clients | — | sqlite3, psql, mysql, redis-cli |\n| Shell utils | — | ripgrep, bat, exa, fd-find, ag, htop"},{"path":"skill-card.md","content":"## Description:\n\nInstall and run Claude Code in a Docker-backed workspace, or connect to its HTTP, MCP, Telegram, and scheduled-job interfaces.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[psyb0t](https://clawhub.ai/user/psyb0t)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use Claudebox to run Claude Code locally or from automation, and to configure authenticated services for remote or scheduled agent tasks.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Unauthenticated HTTP or MCP endpoints can expose agent execution and workspace file control.\n\nMitigation: Set separate API and MCP tokens; bind services to loopback or protect them with an authenticated proxy.\n\nRisk: Agent tasks can access host Docker or mounted credentials when run through the standard wrapper.\n\nMitigation: Keep untrusted prompts out of privileged runtimes; isolate workspaces and omit the Docker socket when it is unnecessary.\n\nRisk: Installing remote scripts or using mutable images can run unreviewed code.\n\nMitigation: Inspect the installer and image provenance before use, and prefer pinned images and packages.\n\nRisk: File-control operations can delete workspace files without an undo path.\n\nMitigation: Confirm target paths and only delete files the current task created when removal was requested.\n\n## Reference(s):\n\n- [Claudebox setup guide](references/setup.md)\n- [Claudebox project homepage](https://github.com/psyb0t/docker-claudebox)\n- [Claudebox release on ClawHub](https://clawhub.ai/psyb0t/skills/claudebox)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration]\n\n**Output Format:** [Markdown with shell commands and configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Agent responses may include text, code, and structured results from the configured runtime.]\n\n## Skill Version(s):\n\n2.5.0 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces. Skill: claudebox Owner: psyb0t Summary: Install, configure, or run Claude Code through the claudebox wrapper, or connect to its HTTP, MCP, Telegram, or cron surfaces. Tags: latest:2.5.0 Version history: v2.5.0 | 2026-10-07T17:20:21.602Z | auto cluedebox v2.5.0 changelog: - Updated reference documentation in references/setup.md. - Removed skill-card.md file. - No changes to command-line interface or functionality—docu","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1715,"uniquenessScore":45,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T04:35:01.162Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T04:35:01.162Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T07:53:42.762Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}