{"id":51025457,"url":"https://github.com/deployment-io/agentbox","last_synced_at":"2026-06-21T19:30:32.870Z","repository":{"id":353046645,"uuid":"1217749743","full_name":"deployment-io/agentbox","owner":"deployment-io","description":"Run AI coding agents headlessly in Docker with a predictable contract. Pluggable runtime.","archived":false,"fork":false,"pushed_at":"2026-06-11T03:43:33.000Z","size":853,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-11T04:13:45.795Z","etag":null,"topics":["agent-runtime","ai-agents","anthropic","automation","claude-code","coding-agent","docker","go","headless","llm","open-source","orchestrator","self-hosted"],"latest_commit_sha":null,"homepage":"https://deployment.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deployment-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-22T07:20:07.000Z","updated_at":"2026-06-11T03:42:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/deployment-io/agentbox","commit_stats":null,"previous_names":["deployment-io/agentbox"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/deployment-io/agentbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deployment-io%2Fagentbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deployment-io%2Fagentbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deployment-io%2Fagentbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deployment-io%2Fagentbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deployment-io","download_url":"https://codeload.github.com/deployment-io/agentbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deployment-io%2Fagentbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34623906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-21T02:00:05.568Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-runtime","ai-agents","anthropic","automation","claude-code","coding-agent","docker","go","headless","llm","open-source","orchestrator","self-hosted"],"created_at":"2026-06-21T19:30:31.505Z","updated_at":"2026-06-21T19:30:32.862Z","avatar_url":"https://github.com/deployment-io.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentbox\n\n[![Build \u0026 Test](https://github.com/deployment-io/agentbox/actions/workflows/build.yml/badge.svg)](https://github.com/deployment-io/agentbox/actions/workflows/build.yml)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n\n**Run AI coding agents in a Docker container with a predictable contract.**\n\n![agentbox demo: the docker run command, agentbox's streaming event log, and the structured result.json written on exit](docs/images/agentbox-demo.png)\n\nGive agentbox a prompt and credentials via environment variables; it\ninstalls the agent, runs it against a bind-mounted working directory,\nstreams output to stdout, and writes a structured result to\n`/result.json`. You don't have to think about stream-json parsing,\nsubprocess lifecycle, signal handling, or version pinning — agentbox\nhandles it so the same invocation shape works across CI, a managed\nplatform, or a local terminal.\n\nBuilt by [deployment.io](https://deployment.io) but designed to stand\nalone — useful to anyone running agents headlessly on their own\ninfrastructure.\n\n## Quick Start\n\nYou'll need:\n- Docker\n- A working directory (any git repo or folder for the agent to work on)\n- An Anthropic API key (see [Credentials](#credentials))\n\n```bash\n# Pull the image\ndocker pull deploymenthq/agentbox:latest\n\n# Create a scratch output dir (agentbox writes result.json there)\nmkdir -p /tmp/agentbox-out\nchmod 777 /tmp/agentbox-out\n\n# Run the agent on a local directory\ndocker run --rm \\\n  -e ANTHROPIC_API_KEY=\"sk-ant-...\" \\\n  -e STEP_PROMPT=\"Add a README.md if missing, summarizing the project.\" \\\n  -e RESULT_PATH=\"/scratch/result.json\" \\\n  -v \"$(pwd):/work\" \\\n  -v /tmp/agentbox-out:/scratch \\\n  deploymenthq/agentbox:latest\n\n# Inspect the outcome\ncat /tmp/agentbox-out/result.json\n```\n\nOn exit:\n- Files the agent created or modified are in your working directory\n- `/tmp/agentbox-out/result.json` has the structured outcome (`status`,\n  `changes_summary`, `files_changed`, `token_usage`, `turns`, etc.)\n- The container's exit code indicates what happened (see [Contract](#contract))\n\n## Permissions\n\nagentbox runs as UID 1000 (the `agent` user) inside the container, so\nany host directory you bind-mount must be writable by that UID. On\nmost single-user Linux desktops your account is already UID 1000 and\nthis just works — but if Docker auto-created the bind-mount source,\nor you're on a multi-user box, the agent will hit `permission denied`\nthe first time it tries to write a file.\n\nFix it before running, either with `chown` (preferred):\n\n```bash\nsudo chown 1000:1000 /path/to/your/dir\n```\n\n…or with `chmod` (works, but less hygienic):\n\n```bash\nchmod 777 /path/to/your/dir\n```\n\nThis applies to both the working directory you bind-mount at `/work`\nand any scratch directory you bind-mount at `/scratch` for the result\nfile.\n\n## Contract\n\nFull spec: [docs/CONTRACT.md](docs/CONTRACT.md). Summary:\n\n### Required environment variables\n\n| Variable | Description |\n|---|---|\n| `STEP_PROMPT` | The prompt for the agent. Free-form text. |\n| `ANTHROPIC_API_KEY` | Anthropic API key. See [Credentials](#credentials). |\n\n### Optional environment variables\n\n| Variable | Default | Description |\n|---|---|---|\n| `WORK_DIR` | `/work` | Path where the repo is bind-mounted. |\n| `RESULT_PATH` | `/tmp/result.json` | Where to write the structured result. |\n| `AGENT_TYPE` | `claude-code` | Which agent to install and run. |\n| `CLAUDE_CODE_VERSION` | Pinned in image | Overridable Claude Code version. |\n| `MODEL` | Agent default | e.g., `opus`, `haiku`, or a pinned version. |\n| `MAX_TURNS` | Uncapped | Hard cap on agent turns. |\n| `NO_ACTIVITY_TIMEOUT` | `10m` | Kill the subprocess if stdout is silent this long. `0` disables. |\n| `PREVIOUS_STEPS_SUMMARY` | — | Free-form context of prior steps for multi-step workflows. |\n\n### Exit codes\n\n| Code | Meaning |\n|---|---|\n| `0` | Success |\n| `1` | Execution failure |\n| `2` | Auth / rate-limit / model-access failure |\n| `3` | Cancelled (SIGTERM received) |\n| `4` | No-activity timeout |\n\n### `/result.json` schema (abbreviated)\n\n```json\n{\n  \"schema_version\": 1,\n  \"agent_type\": \"claude-code\",\n  \"agent_version\": \"2.1.117\",\n  \"status\": \"success\",\n  \"changes_summary\": \"Added README.md summarizing the project.\",\n  \"files_changed\": [\"/work/README.md\"],\n  \"token_usage\": {\n    \"input_tokens\": 4,\n    \"output_tokens\": 125,\n    \"cache_read_tokens\": 28143,\n    \"cache_creation_tokens\": 0\n  },\n  \"turns\": 2\n}\n```\n\n## Credentials\n\nPass your Anthropic API key as an environment variable:\n\n```bash\n-e ANTHROPIC_API_KEY=\"sk-ant-...\"\n```\n\nGet a key at [platform.claude.com](https://platform.claude.com).\n\n## Supported Agents\n\n**v1:** Claude Code and Codex (OpenAI). Select via `AGENT_TYPE`\n(`claude-code` | `codex`).\n\n**Planned:** other agent runtimes (Aider, …) register through the same\n`Driver` interface and dispatch on `AGENT_TYPE`. See\n[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).\n\n## How It Works\n\n```\nDocker container\n  └── agentbox (Go binary — ENTRYPOINT, PID 1)\n       └── agent subprocess (claude in v1)\n            └── agent's own subprocesses (bash, git, npm, ...)\n```\n\n- Pre-built language runtimes (Node.js 22, Python 3) live in the image\n  at build time.\n- At startup, the Go orchestrator installs the selected agent package\n  (`npm install -g` / `pip install --user`) as a non-root user. This\n  takes ~15-30s on a cold cache.\n- The agent runs against the bind-mounted working directory. Its\n  output is teed two ways: a per-event human-readable summary line\n  goes to the container's stdout (for log streaming), and the raw\n  stream goes to an internal parser that builds the structured\n  result. The unfiltered raw stream is also written to\n  `/scratch/agent.log` for deep debugging when the summarized view\n  isn't enough.\n- On SIGTERM, agentbox forwards it to the agent with a 10s grace\n  period before SIGKILL.\n- On exit, `/result.json` is written and the container exits with the\n  appropriate code.\n\nSee [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for details.\n\n## Production Hardening\n\nThe [Quick Start](#quick-start) command is the minimum to get a run\ngoing. agentbox ships with a non-root user, a hostname allowlist\nproxy, and a private-IP deny list baked into the image — those apply\nwithout any extra flags. Everything below is host-side hardening that\nagentbox itself can't enforce; it's how we launch the container in\nproduction.\n\n```bash\ndocker run --rm \\\n  --user 1000:1000 \\\n  --cap-drop=ALL \\\n  --read-only \\\n  --tmpfs /tmp:exec,size=512m,uid=1000,gid=1000,mode=755 \\\n  --tmpfs /home/agent:exec,size=1g,uid=1000,gid=1000,mode=755 \\\n  --memory=2g \\\n  --cpus=2 \\\n  --add-host metadata.google.internal:127.0.0.1 \\\n  --add-host metadata.goog:127.0.0.1 \\\n  --add-host 169.254.169.254:127.0.0.1 \\\n  -e AGENT_TYPE=claude-code \\\n  -e ANTHROPIC_API_KEY=\"sk-ant-...\" \\\n  -e STEP_PROMPT=\"...\" \\\n  -e MAX_TURNS=30 \\\n  -e ADDITIONAL_ALLOWED_HOSTS=\"github.com,api.github.com\" \\\n  -v \"$(pwd):/work\" \\\n  deploymenthq/agentbox:latest\n```\n\n| Flag | Why |\n|---|---|\n| `--user 1000:1000` | Pin to the non-root `agent` user even if the orchestrator scheduling the container forgets. |\n| `--cap-drop=ALL` | Strip every Linux capability. The agent and its subprocesses don't need any of them. |\n| `--read-only` | Root filesystem becomes immutable. Anything that needs to write must go through the bind mount or a tmpfs. |\n| `--tmpfs /tmp:exec,...` | Scratch space for the agent. `exec` is required — npm and pip extract executables here. |\n| `--tmpfs /home/agent:exec,...` | Holds the agent's per-run install (e.g. `npm install -g`). Sized at 1G to fit Claude Code's footprint. |\n| `--memory=2g --cpus=2` | Cap blast radius from a runaway agent. Tune per workload. |\n| `--add-host ...metadata...:127.0.0.1` | Pin AWS/GCP cloud-metadata endpoints to localhost so a bypassed proxy still can't reach IMDS. |\n| `MAX_TURNS` | Hard cap on agent turns; second line of defense against an agent that won't stop. |\n| `ADDITIONAL_ALLOWED_HOSTS` | Extends the proxy allowlist for hosts your task legitimately needs (your git host, internal registries, etc.). |\n\n## Building From Source\n\n```bash\ngit clone https://github.com/deployment-io/agentbox.git\ncd agentbox\ndocker build -t agentbox:dev .\n```\n\nThe multi-stage Dockerfile compiles the Go binary inside a\n`golang:1.24-bookworm` stage and copies it into a\n`debian:bookworm-slim` runtime. No local Go install required.\n\nTo pin a different Claude Code version at build time:\n\n```bash\ndocker build --build-arg CLAUDE_CODE_VERSION=X.Y.Z -t agentbox:dev .\n```\n\n## Platform Support\n\nv1 publishes `linux/amd64` images only. Multi-arch support is\nplanned but not yet in scope.\n\n## License\n\nApache 2.0 — see [LICENSE](LICENSE).\n\n## Related\n\n- [docs/CONTRACT.md](docs/CONTRACT.md) — full input/output contract\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — internals\n- [deployment.io](https://deployment.io) — the platform agentbox was\n  built to power (and one of many possible consumers)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeployment-io%2Fagentbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeployment-io%2Fagentbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeployment-io%2Fagentbox/lists"}