outrig image
outrig image groups commands for the container images that host an agent’s tools.
outrig image add scaffolds a repo-local image-config (a named Dockerfile + MCP-server
bundle); outrig image init scaffolds a standalone image project whose build output is a
reusable image, outrig image build builds and validates that project, and
outrig image inspect reads an image’s declared labels locally by default, or from a
registry with --remote. The rest of the group (image ls, image rm) is reserved for
later.
outrig image add
outrig image add scaffolds a new image-config. It writes a Dockerfile under
.agents/outrig/images/<name>/Dockerfile and appends matching [images.<name>] and
[images.<name>.mcp] blocks to your repo’s config.toml.
Run it any time you want to add an image-config – e.g., a planning config alongside
the <repo>-standard one outrig init creates by default. init calls
image add in a loop for the first (and any further) image-configs you create during
initial setup.
Bootstrapping a fresh repo
If you run outrig image add in a directory without an .agents/outrig/config.toml
(neither here nor in any parent), outrig prompts before scaffolding:
[outrig] no .agents/outrig/config.toml found in /path/to/repo or any parent.
? Configure outrig in this directory now? [Y/n]:
Answering y walks the same repo-config prompts that outrig init uses
(workspace, default agent, preamble), then continues with the image add flow.
Answering n exits with the same error a strict find would have produced – run
outrig init later when you’re ready.
Synopsis
outrig image add [<name>] [--force]
| Argument / flag | Default | Description |
|---|---|---|
<name> | prompted | Image-config name (becomes [images.<name>]). |
--force | off | Overwrite existing Dockerfile/config entries for this name. |
Run it
Every prompt shows the default in [default: ...]; press Enter to accept it. Type ? and
Enter at any prompt for an explanation of what’s being asked plus the available options.
The default image-config name is <repo-folder>-standard (kebab-cased), so the example
below assumes a hello-outrig repo.
$ cd hello-outrig
$ outrig image add
? Image-config name [default: hello-outrig-standard]:
? Base image [default: debian:bookworm-slim]:
? Language toolchains [default: ]: rust, node
? MCP servers [default: fs]:
[outrig] wrote .agents/outrig/images/hello-outrig-standard/Dockerfile
[outrig] added [images.hello-outrig-standard] block to .agents/outrig/config.toml
[outrig] added [images.hello-outrig-standard.mcp] entries: fs
Next: try `outrig build` to verify the image builds, then `outrig run`.
The prompts are intentionally limited – the goal is a known-good starting point you can edit by hand, not an exhaustive Dockerfile generator.
Help at any prompt
? Language toolchains [default: ]: ?
Pick zero or more language toolchains to install in the image. The Dockerfile
template adds the corresponding install steps; you can edit the file afterwards.
rust rustup + stable toolchain (cargo, rustfmt, clippy).
node Node 20 LTS via NodeSource.
python CPython 3.12 with pip and venv.
go Go 1.22.
none Just the base image -- nothing extra installed.
See: https://tgockel.github.io/outrig/usage/image.html#known-toolchains
? Language toolchains [default: ]:
Known toolchains
The toolchain prompt offers curated options that cover the common cases:
| Choice | What gets installed |
|---|---|
rust | rustup + the stable toolchain, cargo, rustfmt, clippy. |
node | Node 20 LTS via the base image’s package manager (or NodeSource). |
python | CPython 3.12 with pip and venv. |
go | Go 1.22. |
none | Just the base image. |
You can pick more than one. The Dockerfile is a starting point – edit it freely afterwards.
Known MCP servers
fs– installs@modelcontextprotocol/server-filesystemfrom npm; default[mcp]entry:{ command = ["mcp-server-filesystem", "/workspace"] }.git– installsmcp-server-gitfrom PyPI; default[mcp]entry:{ command = ["mcp-server-git", "--repository", "/workspace"] }.
fs is the default. Add git for repo-aware tools, or wire up additional servers by
editing the [images.<name>.mcp] block directly – see
Concepts -> MCP Servers.
A shell MCP server is the usual next tool for coding image-configs; choose a package, install it
in the Dockerfile, and declare its command in [images.<name>.mcp].
TODO: Incomplete – the list of “known MCP servers” will grow as the ecosystem does. Anything not listed here you install in the Dockerfile by hand.
When templates do not fit
The prompt flow is intentionally small. If you need an image with a database, internal SDK,
unlisted MCP server, or other custom package set, use
outrig mcp self. It gives an MCP-capable AI tool the OutRig docs,
config schema, suggested tools, and advisory validators so it can propose a Dockerfile and
matching [images.<name>] block without being limited to the built-in template menu.
What gets written
.agents/outrig/images/hello-outrig-standard/Dockerfile (excerpt):
FROM docker.io/library/debian:bookworm-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates curl git build-essential passwd \
&& rm -rf /var/lib/apt/lists/*
# rust toolchain
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain stable --profile default
ENV PATH=/root/.cargo/bin:$PATH
# node toolchain
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
# MCP servers
RUN npm install -g @modelcontextprotocol/server-filesystem
WORKDIR /workspace
CMD ["sleep", "infinity"]
The Dockerfile is generic – no USER directive, no hard-coded UID. outrig sets up a user
matching your host UID/GID at run time (see
Concepts -> Workspace). The
passwd package keeps useradd/groupadd available for that bootstrap step.
Appended to .agents/outrig/config.toml:
[images.hello-outrig-standard]
dockerfile = ".agents/outrig/images/hello-outrig-standard/Dockerfile"
context = ".agents/outrig/images/hello-outrig-standard"
[images.hello-outrig-standard.mcp]
fs = { command = ["mcp-server-filesystem", "/workspace"] }
Re-running
Without --force, outrig refuses if either the Dockerfile path or the config block already
exists for that name:
$ outrig image add hello-outrig-standard
error: .agents/outrig/images/hello-outrig-standard/Dockerfile
already exists; pass --force to overwrite.
With --force, the Dockerfile is replaced and the [images.<name>] block is rewritten in
place (preserving surrounding TOML).
outrig image init
outrig image init scaffolds a standalone image project: a self-contained directory whose
build output is a reusable container image. Unlike image add, it writes no repo config –
it creates three files and nothing else:
Dockerfile– a Debian-slim image with the filesystem MCP server, ending in the standardCMD ["sleep", "infinity"]. It installs the tool binaries; it does not copy OutRig config.image.toml– the standalone image authoring config:[image].refplus a[mcp]table.outrig image buildvalidates this file and stamps the[mcp]table into the image’s OCI labels, which outrig reads back at session startup and merges with any repo[images.<name>.mcp].README.md– how to build the image and reference it from a repo.
The command is noninteractive – there are no prompts. The project name (used as [image].ref)
defaults to the target directory’s name.
Synopsis
outrig image init [<dir>] [--force]
| Argument / flag | Default | Description |
|---|---|---|
<dir> | current dir | Project directory; its name becomes the image ref. |
--force | off | Overwrite the generated files if they already exist. |
The directory name must match ^[a-zA-Z][a-zA-Z0-9_-]*$ (e.g. rust-dev). A target that
resolves to no usable name is rejected; . and the no-argument form use the current
directory’s name.
What gets written
$ outrig image init rust-dev
[outrig] wrote rust-dev/Dockerfile
[outrig] wrote rust-dev/image.toml
[outrig] wrote rust-dev/README.md
[outrig] next: build this image with `outrig image build`
rust-dev/image.toml:
[image]
ref = "rust-dev"
[mcp]
fs = { command = ["mcp-server-filesystem", "/workspace"] }
[build] is omitted, so the build defaults to the sibling Dockerfile with context ..
Consuming the image from a repo
Once built, reference the image from a repo’s config.toml with image-name. Because the
MCP server declarations are stamped into image labels, the consuming block needs no
[images.<name>.mcp]:
[images.rust-dev]
image-name = "rust-dev"
That authoring split is the key difference from image add: repo-local blocks keep their
[images.<name>.mcp] entries in config.toml and stamp them into cache image labels when built;
standalone projects carry the declarations in image.toml so the image can be consumed elsewhere
without repo-local MCP config. See
Concepts -> Containers for the
image-name shape.
Re-running
Without --force, init refuses if any of the three files already exists, naming the
conflicts:
$ outrig image init rust-dev
error: rust-dev/Dockerfile, rust-dev/image.toml, rust-dev/README.md
already present; pass --force to overwrite.
--force regenerates the three files and leaves anything else in the directory untouched.
outrig image build
outrig image build builds a standalone image project (the output of outrig image init) and
validates that the result is a working OutRig toolset image. It is the standalone-project
counterpart to outrig build, which builds repo-local image-configs.
It reads the project’s image.toml, serializes it into OCI labels, builds the declared
Dockerfile with buildah, and tags the result with the [image].ref from image.toml –
stamping those labels onto the image. Then it always validates the built image, and – unless
--no-test – live-tests every MCP server the image declares.
Synopsis
outrig image build [<dir>] [--tag <ref>] [--no-test] [--no-cache]
| Argument / flag | Default | Description |
|---|---|---|
<dir> | current dir | Project directory holding image.toml. |
--tag <ref> | [image].ref | Build tag override; does not edit image.toml. |
--no-test | off | Skip the live MCP test; still validates image.toml. |
--no-cache | off | Force a clean build; passed through to buildah. |
What it does
$ outrig image build rust-dev
[outrig] building image rust-dev
[outrig] dockerfile: Dockerfile
[outrig] context: .
... buildah build output ...
[outrig] image ready
[outrig] image config validated (1 mcp server)
[outrig] mcp fs: initialized (12 tools)
[outrig] image ok
After the build, outrig reads the stamped org.outrig.mcp label back off the built image and
validates it (every server name well-formed, every command non-empty). By default it then starts
the image, and for each declared MCP server initializes it and calls tools/list, reporting the
tool count per server. The image is built locally; nothing is pushed.
Failure modes
The command exits nonzero – printing error: ... – in these cases:
image.tomlmissing, malformed, or missing required fields (no[image].ref, an empty or invalid[mcp]table, a partial[build]): caught before the build runs.- The stamped
org.outrig.mcplabel is missing or malformed: read back off the built image and validated after the build, even with--no-test. - A declared MCP server cannot initialize or return
tools/list: caught during the live test.--no-testskips this check (the per-server stderr is captured in the error message).
--no-test
--no-test skips only the live MCP server test. The stamped org.outrig.mcp label is still
read back from the built image and validated, so a missing or malformed config still fails. Use
it to verify a build quickly, or in environments where starting the servers is not wanted.
--tag and --no-cache
--tag <ref> tags the build output as <ref> for that invocation instead of the [image].ref
in image.toml; the file is never rewritten. Short refs are passed to buildah verbatim, so both
rust-dev and rust-dev:0.1.0 work.
Unlike repo-local outrig build – which tags <image-config-name>:<content-hash> and skips
the build on a cache hit – a standalone build tags a stable, caller-named ref with no content
hash, so there is no project-level cache to skip: --no-cache only forwards --no-cache to
buildah to force a clean build.
outrig image inspect
outrig image inspect prints the OutRig config labels declared by an image. It is read-only:
local mode checks the local image store and reads labels with podman image inspect; remote mode
uses skopeo inspect against a registry. Neither mode pulls image layers, creates a container, or
starts an MCP server. Live initialization and tools/list checks belong to
outrig image build.
Synopsis
outrig image inspect [--remote] <ref>
| Argument | Description |
|---|---|
<ref> | Image ref to inspect. Never pulled. |
--remote | Read registry metadata with skopeo inspect. |
Output
The command writes only the inspect result to stdout. Diagnostics and errors go to stderr.
$ outrig image inspect rust-dev
image: rust-dev
description: Rust tooling
version: 0.1.0
tags: ["rust","build"]
mcp:
fs:
command: ["mcp-server-filesystem","/workspace"]
db:
command: ["db-mcp"]
env:
TOKEN: "${DB_TOKEN}"
description, version, and tags appear only when the image carries those labels. If the
image has no org.outrig.mcp label, inspect still prints the image ref and any metadata labels it
finds, then omits the mcp: section.
Repo-local images built by outrig build, outrig run, or outrig mcp are stamped with an
org.outrig.mcp label on cache misses. For those <image-config-name>:<hash> refs, inspect shows
the merged MCP declarations from inherited/Dockerfile labels plus [images.<name>.mcp], without
starting a container. Standalone images may additionally show description, version, and
tags.
Use --remote when the ref is in a registry and you want the labels without pulling it:
outrig image inspect --remote ghcr.io/acme/rust-dev:latest
Remote inspection requires skopeo on PATH. Authentication uses the normal container
credentials that skopeo reads, such as credentials created by skopeo login, podman login,
buildah login, or docker login.
Failure modes
The command exits nonzero – printing error: ... – in these cases:
- The image is not present locally: inspect reports a local-only not-found error and does not attempt a pull.
--remoteis used butskopeois not installed: inspect reports the missing runtime dependency.- The registry request fails:
skopeoerrors, including missing credentials or denied access, are reported with the command and stderr tail. - The remote ref uses an unsupported transport: use a plain registry ref or
docker://<ref>. - A declared OutRig label is malformed: invalid
org.outrig.tagsororg.outrig.mcpvalues fail before anything is started.
See also
- outrig init – runs
image addin a loop as the last step of initial setup. - Concepts -> Containers – Dockerfile conventions and named image-configs.
- Concepts -> MCP Servers – the MCP servers
image addscaffolds. - AI-assisted design – design a custom image-config with
outrig mcp self. - Reference -> Config – the
[images.<name>]schema.