Run agent CLIs locally on macOS, with optional Ollama integration
This repository packages a practical local setup for running agent CLIs on Apple
Silicon Macs with Apple’s container tool.
Run agentctl --version to inspect the checked-out release. Published versions
and the release process are documented in docs/releases.md.
The main entry point is agentctl, which manages:
- curated images such as
agent-plain,agent-python, andagent-swift - runtime selection (
codex,claude, and more over time) - local vs online launch modes
- runtime auth sync through the in-container
agent.shcontract - feature packs and bootstrap flows
You need:
- an Apple Silicon Mac running macOS 26
- Apple’s
containerCLI 1.1 or newer - the system Bash and Apple-provided
jq(jq 1.6 or newer; macOS 26 providesjq 1.7.1-apple)
This baseline is Homebrew-free and does not require host-side Python, Node.js, or another package manager. Ollama is only required for local-model workflows; online runtime workflows do not require it.
Recommended memory:
- for local-model workflows, plan for at least 32 GB RAM
- online-only workflows may work with less memory, but that is not yet verified in the current docs/test matrix
Official releases:
container: https://github.com/apple/container/releases- Ollama: https://ollama.com/download
After installing container (and Ollama if you plan to use local models), clone
this repository and open a Terminal in the repository root.
Then make agentctl available on your PATH. The easiest option on macOS is
usually a symlink into /usr/local/bin:
sudo ln -sf "$PWD/agentctl" /usr/local/bin/agentctlIf you prefer a user-local install instead:
mkdir -p "$HOME/bin"
ln -sf "$PWD/agentctl" "$HOME/bin/agentctl"
export PATH="$HOME/bin:$PATH"After that, run:
# Pull the default local model used by current Codex and Claude local flows
ollama pull gpt-oss:20b
# Optional Codex profile models
ollama pull gemma4:26b-a4b-it-q4_K_M
ollama pull qwen3.5:35b-a3b-coding-nvfp4
# Optional smaller model for direct `--model` testing
ollama pull qwen3.5:9b-nvfp4
# Start the Apple container API service
container system startBefore your first local run, make sure containers can reach Ollama. The short version is:
- agentctl maps
host.container.internalto the current Apple container gateway - default Ollama only listens on
localhost - you may need to expose or proxy Ollama onto the container-visible host address
Details and options are in docs/networking.md.
For isolated Ollama listeners or non-default ports, pass the container-reachable base URL explicitly:
OLLAMA_HOST=http://host.container.internal:11439 agentctl run ...
# or
agentctl run -c ollama_host=http://host.container.internal:11439 ...agentctl run starts an agent inside a container, but it mounts a host
directory into that container at /workdir.
In the normal case:
- the directory you run
agentctl runfrom becomes the mounted work directory - everything under that directory is visible to the agent
- the agent can read and write files in that mounted directory tree
- the agent does not get unrestricted access to the rest of your host
filesystem through
agentctl
So the normal workflow is:
cdinto the project or document folder you want the agent to work on- run
agentctl run - let the agent work inside that mounted directory tree
If you want a different directory than the current one, use:
agentctl run --workdir /path/to/projectBuild the curated images once:
agentctl buildThen start the agent against the current directory, which will be mounted into
the container as /workdir:
agentctl runCommon first-run workflows:
# Run Codex with a specific local profile
agentctl run -c profile=gemma
# Test a specific model directly
agentctl run --model qwen3.5:9b-nvfp4
# Pass a runtime-specific Claude launch flag
agentctl run --runtime claude -c dangerously-skip-permissions=true
# Use the runtime's online/provider-backed mode after logging in once
agentctl auth --runtime codex
agentctl run --runtime codex --online
# Start a shell instead of the runtime
agentctl run --shell
# Launch with Claude when the image includes it, or install explicitly before launch
agentctl run --runtime claude
agentctl run --runtime claude --install-runtime
# Override the launch model for the selected runtime
agentctl run --runtime claude --model qwen3:14b
# Refresh an existing container in place after pulling a newer agentctl checkout
agentctl refreshChoose a toolchain image when needed:
agentctl run --image agent-python
agentctl run --image agent-swiftInspect or manage runtimes:
agentctl runtime list
agentctl runtime info codex
agentctl runtime install claude
agentctl runtime use claudeRun stdio-based protocol servers inside a container:
# ACP agent runtime with container lifecycle and online auth sync
agentctl run --stdio --name my-agent --image agent-swift --workdir /path/to/project \
--runtime codex --online --cmd \
sh -lc 'cd /workdir && npx -y @agentclientprotocol/codex-acp'
# ACP agent runtime in an already-running container
agentctl exec --stdio --name my-agent -- sh -lc 'cd /workdir && npx -y @agentclientprotocol/codex-acp'
# MCP stdio server
agentctl exec --stdio --name my-agent -- sh -lc 'cd /workdir && node ./my-mcp-server.js'Use the office feature on an agent-python container:
agentctl run --image agent-python --cmd true
agentctl feature info office
agentctl feature install officeBootstrap onto a compatible non-agentctl container:
agentctl bootstrap --name existing-devbox
agentctl bootstrap --name my-alpine-devbox --image docker.io/library/alpine:latestUse these curated images for most workflows:
agent-plain: general shell, Git, and runtime workagent-python: Python-heavy tasks and librariesagent-swift: Swift toolchain and SwiftPM workflows
agent-office remains only as a legacy compatibility image. For new work, use
agent-python plus the office feature pack.
If you started with one curated image and later need another one for the same
container, recreate it with agentctl upgrade --image .... For example:
agentctl upgrade --name <container> --image agent-pythonUpgrades create backup images by default. To inspect a backup image without
refreshing it or mounting the current workdir, use rescue:
agentctl rescue --image <container>-backup-<timestamp>For upgrade recovery workflows, backup state inventory, and restore examples, see docs/rescue.md.
If you already have a compatible base container and want to bring the managed
control surface onto it, use agentctl bootstrap instead of starting from a
curated image. More on that in docs/bootstrap.md.
Host integration and shell unit tests are documented in TESTING.md.
Fast checks (the host runner defaults to its smoke tier):
bash tests/run-unit-tests.sh
bash tests/run-tests.shUse bash tests/run-tests.sh --tier full for release and runtime-upgrade
validation.
Deeper documentation now lives under docs/: