# Add Agent

> Add a new AI coding agent to Agent Sandbox. Creates all required files (Dockerfile, templates, CI, docs) and wires the agent into the CLI, proxy, and build system.

- Skill: `mattolson/add-agent` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mattolson/add-agent`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mattolson/add-agent/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: mattolson (https://skillmd.com/u/mattolson)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/mattolson/add-agent

---


# Scaffold Agent Support

This skill generates all the files needed to add a new AI coding agent to Agent Sandbox. It follows the established patterns from Claude, Copilot, and Codex implementations.

## Arguments

The skill takes a single argument: the agent name (lowercase, no spaces). Example: `gemini`, `opencode`, `factory`.

## Process

### Step 1: Gather Information

Ask the user for the following (skip any already provided):

1. **Agent name** (from argument)
2. **Display name** - human-readable name for comments and labels (e.g., "Google Gemini CLI")
3. **Project URL** - link to the agent's GitHub repo or website (for README table)
4. **Installation method** - how to install the agent binary/CLI
   - npm package (like Claude and Copilot)
   - direct binary download from GitHub releases (like Codex)
   - curl installer script
   - pip package
   - go install
5. **Package identifier** - npm package name, GitHub releases URL pattern, pip package, go module, or download URL
6. **Version detection source** - how CI detects new releases
   - npm registry (Claude, Copilot): `npm view {package} version`
   - GitHub releases API (Codex): `gh api repos/{owner}/{repo}/releases/latest --jq .tag_name`
   - Note any tag prefix that needs stripping (e.g., Codex uses `rust-v` prefix)
7. **Version variable name** - env var for build.sh (e.g., `GEMINI_VERSION`)
8. **Config directory** - where the agent stores its config in the container (e.g., `/home/dev/.gemini`)
9. **Default config files** - any config files to bake into the image (e.g., Codex bakes `config.toml` to disable its internal sandbox)
10. **Internal sandbox** - does the agent have its own sandboxing (Landlock, seccomp, etc.) that should be disabled inside our container? If so, how to disable it.
11. **Required API domains** - domains the agent needs to reach (API, auth/OAuth, CDN)
12. **Authentication method** - how users authenticate (API key env var, OAuth flow, device code, etc.)
13. **Auto-approve flag** - the CLI flag for unattended/yolo mode (e.g., `--dangerously-skip-permissions`, `--yolo`, `--full-auto`)
14. **VS Code extension ID** - if one exists (e.g., `github.copilot-chat`), or "none" for CLI-only agents
15. **JetBrains plugin ID** - if one exists (e.g., `com.anthropic.code.plugin`), or "none"
16. **Agent-specific environment variables** - any env vars the agent needs at runtime
17. **Does the agent need Node.js?** - whether to install Node.js in the Dockerfile (only if the base image doesn't include it and the agent needs it)

### Step 2: Create Files

Generate all files listed below. Read the reference files first to match the exact format and structure.

#### 2.1: Dockerfile

Create `images/agents/{agent}/Dockerfile`.

Pattern:
- `ARG BASE_IMAGE=agent-sandbox-base:local` + `FROM ${BASE_IMAGE}`
- Optional extra packages block (same pattern as existing agents)
- Install Node.js if needed (copy pattern from Copilot Dockerfile)
- As root: create config directory and `~/.local/bin` if installing a binary there
- Copy any default config files (e.g., `COPY config.toml /home/dev/.{agent}/config.toml`)
- `USER dev`
- Set `ENV PATH="/home/dev/.local/bin:$PATH"` if installing to `~/.local/bin`
- Install the agent (method depends on installation type)
- For direct binary downloads: use `ARG TARGETARCH` for multi-arch, prefer musl (statically linked) over gnu variants
- Add labels: `org.opencontainers.image.description` and version label

If the agent needs default config files, create them alongside the Dockerfile (e.g., `images/agents/{agent}/config.toml`).

#### 2.2: Agent Compose Layer

Create `internal/embeddata/templates/{agent}/cli/agent.yml`.

This is a compose overlay that layers on top of the shared `internal/embeddata/templates/compose/base.yml`. It contains only agent-specific configuration. Read an existing agent.yml for the exact format.

Contents:
- Managed-by comment header
- `services.proxy.volumes: []` (required placeholder for compose merge)
- `services.agent.image` - the GHCR image reference
- `services.agent.volumes` - agent-specific state and history volumes
- `services.agent.environment` - agent-specific env vars (if any)
- Named volume declarations at the bottom

Do NOT include proxy config, HTTP_PROXY, HTTPS_PROXY, capabilities, or other shared settings. Those live in `base.yml`.

#### 2.3: devcontainer.json

Create `internal/embeddata/templates/{agent}/devcontainer/devcontainer.json`.

This file references a layered array of compose files. Read an existing devcontainer.json for the exact format.

Key points:
- `dockerComposeFile` is an array of 5 paths pointing into `.agent-sandbox/compose/`:
  `base.yml`, `agent.{name}.yml`, `mode.devcontainer.yml`, `user.override.yml`, `user.agent.{name}.override.yml`
- `service: "agent"`
- `workspaceFolder: "/workspace"`
- VS Code settings section with port forwarding disabled and security settings
- VS Code extensions array if applicable, or omit for CLI-only agents
- JetBrains settings section with proxy configuration
- JetBrains plugins array if applicable
- `remoteUser: "dev"`
- `overrideCommand: false`

#### 2.4: Update Agent Registry

Edit `cli/lib/agent.bash`:
- Add the new agent to `supported_agents_display()` (space-separated string)
- Add the new agent to `supported_agents()` (printf list)
- Add the new agent to `select_agent()` (option list)
- Add the new agent to the `validate_agent()` case statement

#### 2.5: Update CLI Compose Scaffolding

Edit `cli/lib/cli-compose.bash`:
- If the agent has host-side config that users might want to mount (like Claude's `CLAUDE.md` and `settings.json`), add a conditional block in `scaffold_cli_agent_override_if_missing()` following the Claude pattern. This adds commented-out volume entries to `user.agent.{name}.override.yml`.
- Skip this for agents without meaningful host-side config.

#### 2.6: Update BATS Tests

Two test files reference the agent list string:

1. Edit `cli/test/init/init.bats`: update the "rejects invalid --agent value" assertion to include the new agent name.
2. Edit `cli/test/switch/switch.bats`:
   - Update the "switch rejects invalid --agent value" assertion(s) to include the new agent name.
   - Update the `stub select_option` call in "switch prompts for agent when --agent is omitted" to include the new agent in the argument list.

Both assertions and the stub match the output of `supported_agents_display()` / `select_agent()`.

#### 2.7: Update Proxy Service Domains and Known Agents

Two files in the proxy image need updating:

**`images/proxy/service_catalog.py`**: add a new entry to the `SIMPLE_SERVICE_HOSTS` dict.

Guidelines:
- Place alphabetically among existing entries
- Prefer wildcards over listing subdomains individually (e.g., `*.openai.com` covers `api.openai.com`, `auth.openai.com`, regional endpoints)
- Only use separate entries for different TLDs (e.g., `chatgpt.com` is separate from `openai.com`)
- Include both API domains and auth/OAuth domains so authentication works through the proxy

If the service needs rule-level semantics (repo scoping, method narrowing beyond the generic `readonly` mapping), add a dedicated expander function following the GitHub pattern instead of using `SIMPLE_SERVICE_HOSTS`.

**`images/proxy/render-policy`**: add the new agent name to the `KNOWN_AGENTS` set. This script renders the effective proxy policy at startup and validates the `AGENTBOX_ACTIVE_AGENT` env var against this set. If the agent is missing, the proxy will refuse to start with an "Unknown agent" error.

#### 2.8: Update build.sh

Edit `images/build.sh` to add:
- Default env var at top (e.g., `: "${GEMINI_VERSION:=latest}"`)
- Extra packages env var (e.g., `: "${GEMINI_EXTRA_PACKAGES:=}"`)
- `build_{agent}()` function following the pattern of existing agent build functions
- Add to the case statement (both specific target and `all` target)
- Update usage text (first line and examples)

#### 2.9: Agent Documentation

Create `docs/agents/{agent}.md` following this structure (see `docs/agents/codex.md` for exact format):

1. **Header**: `# {Display Name} Sandbox Template`
2. **One-liner**: "Run {display name} in a network-locked container..."
3. **Link**: "See the [main README](../../README.md) for installation, architecture overview, and configuration options."
4. **Setup section**: Auth instructions covering all supported auth methods. Note any gotchas (e.g., account-level settings that must be enabled).
5. **Usage section**: How to start the agent, including the auto-approve flag. Include `agentbox compose down` for stopping.
6. **Required Network Policy section**: Show the `services:` YAML snippet with the agent's service name.

#### 2.10: Update Project README

Edit `README.md`:
- Add row to the "Supported agents" table with the agent name, project URL, and status columns (CLI, VS Code, JetBrains). New agents are typically `:large_blue_circle: Preview` for CLI and devcontainer modes.
- Add link to `docs/{agent}/README.md` in the "Agent-specific setup" section

### Step 3: CI/CD Workflows

Create the CI files directly in `.github/workflows/`. They follow a clear pattern and can be written without drafting.

#### 3.1: Build Job

Edit `.github/workflows/build-images.yml`:
- Add `{AGENT}_IMAGE_NAME` env var (e.g., `GEMINI_IMAGE_NAME`)
- Add `build-{agent}` job following the pattern of `build-codex` (for GitHub releases) or `build-copilot` (for npm)
- Version detection depends on the source:
  - npm: `npm view {package} version`
  - GitHub releases: `gh api repos/{owner}/{repo}/releases/latest --jq .tag_name` with any tag prefix stripping via `sed`
- Add to summary job `needs` array
- Add agent version and digest to summary output table

#### 3.2: Version Check Workflow

Create `.github/workflows/check-{agent}-version.yml` following the pattern of existing version check workflows.

- Pick the next available daily cron slot (current: Claude 6am UTC, Copilot 7am, Codex 8am)
- Match the version source to the build job (npm or GitHub releases)
- Tag prefix: `{agent}-` for the GHCR tag check
- Trigger `build-images.yml` if the version tag doesn't exist in GHCR

### Step 4: Verify

After creating all files:

1. List all files created/modified
2. Note any manual steps needed
3. Remind user to:
   - Build and test locally: `./images/build.sh {agent}`
   - Verify the binary works: `docker run --rm agent-sandbox-{agent}:local {agent} --version`
   - Test init flow: `agentbox init --agent {agent} --mode cli --path /tmp/test-project`
   - Run CLI tests: `go test ./...`
   - Test proxy enforcement after starting containers:
     - Allowed domain returns 200: `curl -x http://proxy:8080 https://{api-domain}`
     - Blocked domain returns 403: `curl -x http://proxy:8080 https://example.com`
   - Test auth flow inside the container

## Reference Files

When generating files, read these for the exact patterns:
- `images/agents/claude/Dockerfile` (npm install pattern)
- `images/agents/copilot/Dockerfile` (npm install with Node.js pattern)
- `images/agents/codex/Dockerfile` (direct binary download pattern, multi-arch, config file baking)
- `images/agents/codex/config.toml` (baked config file example)
- `internal/embeddata/templates/compose/base.yml` (shared compose base layer with proxy and agent skeleton)
- `internal/embeddata/templates/compose/mode.devcontainer.yml` (devcontainer mode overlay)
- `internal/embeddata/templates/claude/cli/agent.yml` (agent compose layer with env vars)
- `internal/embeddata/templates/copilot/cli/agent.yml` (simplest agent compose layer)
- `internal/embeddata/templates/claude/devcontainer/devcontainer.json` (devcontainer with extensions and JetBrains plugins)
- `internal/embeddata/templates/codex/devcontainer/devcontainer.json` (CLI-only agent, no extensions)
- `internal/runtime/agents.go` (agent registry: supported list and validation)
- `internal/scaffold/init.go` (CLI and devcontainer init flow entrypoints)
- `internal/scaffold/devcontainer.go` (devcontainer JSON rendering and merge behavior)
- `internal/cli/init_test.go` (init command assertions and prompting expectations)
- `internal/cli/switch_test.go` (switch command assertions and agent validation coverage)
- `images/proxy/addons/enforcer.py` (service domains, alphabetical ordering)
- `images/proxy/render-policy` (KNOWN_AGENTS set, policy rendering validation)
- `images/build.sh` (build functions and case statement)
- `docs/agents/codex.md` (simplest agent doc, CLI-only)
- `docs/agents/copilot.md` (agent doc with IDE notes)
- `README.md` (supported agents table and setup links)
- `.github/workflows/build-images.yml` (build jobs)
- `.github/workflows/check-codex-version.yml` (GitHub releases version check)
- `.github/workflows/check-copilot-version.yml` (npm version check)

