AI agent development container with Claude Code, Codex, RTK, mise, APM, entire, and git-wt pre-installed.
- macOS + Colima running as the Docker backend. The shell launcher calls
colima ssh/colima statusto resolve the SSH agent socket and to check readiness, so Docker Desktop or other backends are not supported out of the box.
Source the plugin in your ~/.zshrc:
source /path/to/agent-stack/agent-stack.plugin.zshThen start a container from the current directory:
agent- Docker socket: allows the container to control host Docker (
docker build,docker run,docker exec, etc.). Remove if not needed. - Bind mount (
~/.agent-stack): persists container-only agent settings on the host.Codexuses~/.agent-stack/.codex,Claudeuses~/.agent-stack/.claude, so they stay separated from host-side~/.codexand~/.claude. - Named volume (
agent-mise-data): persists mise-installed runtimes across container recreations. - gitconfig: mounts host git config (read-only) so
git commitandgit pushwork inside the container. - SSH agent: the shell launcher resolves the forwarded agent socket from the Colima VM and mounts it into the container. Set
ssh.forwardAgent: truein Colima so the forwarded agent is available.
With preinstalled sheldon, optional shell plugins can be added in ~/.agent-stack/.sheldon/plugins.toml. For example:
shell = "zsh"
[plugins.entire-fzf]
github = "Syati/entire-fzf"On first use, the plugin automatically creates ~/.agent-stack/.env, ~/.agent-stack/.claude, ~/.agent-stack/.codex, ~/.agent-stack/.chrome-agent, and ~/.agent-stack/.sheldon/plugins.toml.
By default, agent does not mount the host Docker socket. Use agent --docker only when the container needs to run host Docker commands such as docker build, docker run, or docker compose.
agent reads SSH_AUTH_SOCK from inside the Colima VM by calling colima ssh, then mounts that forwarded socket into the container. If you need SSH credentials inside the container, enable ssh.forwardAgent: true in Colima and restart Colima after changing the config.
You can pass a container command directly, for example agent claude, agent codex, or agent zsh -lc 'uname -a'.
Multiple instances can run in parallel. Each agent call creates a separate container, so git-wt worktrees are still the safest way to avoid file conflicts when several agents work on the same repo.
Runs as non-root user agent (home: /home/agent, shell: zsh). Working directory is /workspace.
| Tool | Description |
|---|---|
| Claude Code | Anthropic's AI coding CLI |
| Codex | OpenAI's AI coding CLI |
| RTK | Token-optimized CLI proxy (60-90% token savings) |
| mise | Dev tool version manager |
| APM | Agent Package Manager for MCP/skills |
| entire | AI session capture for git |
| git-wt | Simplified git worktree management |
| sheldon | Plugin manager for user-managed shell extensions |
| gh | GitHub CLI |
| ripgrep | Fast grep (auto-used by RTK) |
| agent-browser | Browser automation for AI agents |
| build-essential | C/C++ compiler toolchain |
~/.agent-stack/.env is optional. Use it only when you want to pass extra environment variables through the shell launcher, for example:
GH_TOKEN=op://Private/github-pat/credential
CHROME_REMOTE_PORT=9222
AGENT_TCP_BRIDGES=127.0.0.1:64342->host.docker.internal:64342
When 1Password CLI (op) is available, op:// references are resolved via op inject automatically. Without op, the file is passed as-is.
AGENT_TCP_BRIDGES is optional. It starts one or more TCP bridges inside the container before your command runs. Use a comma-separated list of listen_host:listen_port->target_host:target_port entries when a host-side service only accepts requests that preserve localhost on the client side.
For example, this lets container-side Codex keep using http://127.0.0.1:64342/stream for RubyMine MCP while forwarding the traffic to the host:
AGENT_TCP_BRIDGES=127.0.0.1:64342->host.docker.internal:64342Multiple bridges can be defined with commas:
AGENT_TCP_BRIDGES=127.0.0.1:64342->host.docker.internal:64342,127.0.0.1:9223->host.docker.internal:9223agent sets these paths explicitly inside the container:
CODEX_HOME=/home/agent/.agent-stack/.codex
CLAUDE_CONFIG_DIR=/home/agent/.agent-stack/.claudeThis keeps container auth and settings separate from host-side ~/.codex and ~/.claude. On first launch, authenticate inside the container once to populate those directories. For Codex, use codex login --device-auth. For Claude Code, run claude and complete the normal interactive login flow.
git clone https://github.com/Syati/agent-stack.git
cd agent-stack
docker build -t agent-stack:local -f docker/Dockerfile .
AGENT_STACK_IMAGE=agent-stack:local agentagent-browser is pre-installed in the container. Start Chrome on the host with remote debugging, then connect from the container.
Host side (agent chrome or manually):
agent chromeContainer side (run chrome-connect to resolve WebSocket URL and connect):
chrome-connectagent chrome reads CHROME_REMOTE_PORT from ~/.agent-stack/.env and defaults to 9222. Its Chrome profile is stored in ~/.agent-stack/.chrome-agent, so the browser state also stays scoped to agent-stack. The plugin launcher is currently macOS-only because it uses the standard /Applications/Google Chrome.app/... path.
MIT