outrig run
outrig run is the main subcommand. It walks up from the current directory to find
.agents/outrig/config.toml, builds (or cache-hits) the container image, starts the container,
attaches every MCP server defined for the selected container-config, and drops you into a
stdin/stdout REPL with the agent.
Synopsis
outrig run [--agent <name>]
[--container <name>]
[--config <path>]
[--device <cpu|cuda|cuda:N|metal>]
[--max-tool-calls <n>]
[--max-tool-result-bytes <n>]
[--network <default|audit|filter>]
[--session-dir <path>]
[--session-root <path>]
[--verbose]
--agent <name>(default:default-agent): selects an[agents.<name>]block.--container <name>(default: agent’scontainer, elsedefault-container): pick a container.--config <path>(default: walks up from cwd): use from outside the repo or non-standard locations.--device <cpu|cuda|cuda:N|metal>(default: mistralrs modeldevice, elsecpu): override the in-process mistralrs model device for this run.--max-tool-calls <n>(default: resolvedtool-call-cap, else50): override the per-turn tool-call cap for this run.--max-tool-result-bytes <n>(default: resolvedtool-result-cap, else262144): override the per-tool-result byte cap for this run.--network <default|audit|filter>(default: config[network].mode, elsedefault): choose Podman’s default networking, network audit logging, or global network filtering for this run.--session-dir <path>(default:<session-root>/<sid>): this run’s specific session directory; symlinked from the root.--session-root <path>(default:session-rootconfig, else XDG): root directory containing all sessions.--verbose(default: off): adds buildah/podman command transcripts to stderr andcontainer.log.
Repeat --verbose (-vv) to also enable trace-level logs from outrig’s own modules for that
invocation.
Normal startup progress is always printed to stderr so slow container or MCP startup is visible.
--verbose adds the underlying buildah/podman command transcript; it is not required for the
progress lines. Tracing filters come from OUTRIG_LOG first, then RUST_LOG if OUTRIG_LOG
is unset.
When --session-dir is given, outrig writes this run’s session.json and logs/ directly into
<path> and creates a symlink at <session-root>/<sid> -> <path> so outrig ls/logs/discard
keep working. This lets you launch with a known path and read session.json immediately without
looking up an auto-generated id:
$ outrig run --session-dir /tmp/my-debug-run < prompts.txt
$ cat /tmp/my-debug-run/session.json # known location, no id lookup needed
--session-dir refuses if the path already contains a session.json.
What happens, in order
- Locate config. Walks up from the current directory until
.agents/outrig/config.tomlis found, or fails. - Resolve container-config. Uses
--containerif given, otherwisedefault-container. The selected block must exist. - Build (or cache-hit) the image. Runs
buildah build. If the cache hash matches an existing tag, no rebuild. - Start the container.
podman run -d --rm --name outrig-<sid> -v <repo>:/workspace:rw --userns=keep-id ... <image> sleep infinity. - Bootstrap the user. As in-container root, ensure a group with
$(id -g)and a user with$(id -u)exist (creating them viagroupadd/useraddif not), and that/home/<user>exists and is owned by them. See Concepts -> Workspace for the full logic. - Start network interception, if enabled.
--network audit,--network filter, or matching[network].modeconfig installs the per-session interceptor and opens<session_dir>/logs/network.jsonl. Filter mode also enforces global[network]policy. The default mode skips this step entirely. - Connect MCP servers. For each entry in
[containers.<name>.mcp],podman exec -i --user=$(id -u):$(id -g)the configured command, run the MCPinitializehandshake, and discover tools viatools/list. - Resolve agent -> model -> provider. From
--agent(ordefault-agent), look up[agents.<a>].model– if unset, fall back to top-leveldefault-model. Then[models.<m>].provider, then[providers.<p>]. Resolve the per-turn tool-call cap fromtool-call-capand the per-result byte cap fromtool-result-cap. For in-process mistralrs models,--deviceoverrides the model’s configureddevicefor this run. For OpenAI-style models,--deviceis rejected. Then read the API key from the env var named in the provider’sapi-key. Build the Rig provider client. - Build the Rig agent. Dynamic tools from every MCP server’s tool list (each prefixed
<server>__<tool>), the agent’spreambleand sampling params, assembled withAgentBuilder. - Open the REPL. Banner on stderr,
>prompt, ready for input.
If anything before step 10 fails, outrig run reports the error on stderr and exits non-zero
without starting the REPL.
REPL banner
A typical startup looks like:
[outrig] loading config
[outrig] config loaded (1ms)
[outrig] resolving agent and container
[outrig] agent/container resolved: agent coding, container coding (0ms)
[outrig] computing image tag
[outrig] image tag computed: outrig-cache:8c2a4f7e91d6b5a3 (32ms)
[outrig] ensuring image outrig-cache:8c2a4f7e91d6b5a3
[outrig] image ready: outrig-cache:8c2a4f7e91d6b5a3 (cache hit) (18ms)
[outrig] starting container outrig-20260502T103412-3f2a
[outrig] container ready: outrig-20260502T103412-3f2a (620ms)
[outrig] bootstrapping container user
[outrig] container user ready (141ms)
[outrig] reading and merging MCP configuration
[outrig] MCP configuration ready: 2 servers (74ms)
[outrig] MCP fs: initializing
[outrig] MCP fs: initialized (188ms)
[outrig] MCP fs: listing tools
[outrig] MCP fs: tools ready: 3 tools (11ms)
[outrig] building agent
[outrig] agent ready (0ms)
[outrig] agent: coding (model: fast / provider: openai / gpt-4o-mini)
[outrig] tool-call cap: 50
[outrig] tool-result cap: 262144 bytes
[outrig] container-config: coding
[outrig] image: outrig-cache:8c2a4f7e91d6b5a3
[outrig] container started: outrig-20260502T103412-3f2a
[outrig] mcp fs: initialized (3 tools)
[outrig] mcp shell: initialized (1 tool)
[outrig] tools available: fs__read_file, fs__list_directory, fs__write_file, shell__exec
[outrig] session id: 20260502T103412-3f2a (Ctrl-D to exit, /help for slash commands)
[outrig] entering REPL
>
All startup progress and the banner are on stderr. The only thing that ever goes to stdout is
the assistant’s natural-language reply. For in-process mistralrs models, that reply is flushed
as chunks while the model decodes; OpenAI-compatible providers print the reply when the turn
finishes. The stream separation makes it easy to capture just the model output:
$ echo "summarise this repo" | outrig run > summary.txt
summary.txt ends up with only the model’s text, nothing else.
REPL behavior
Each line you type at > is one user turn:
> add a doc comment to the public function `parse_config` and run cargo check.
[outrig] tool call: fs__read_file({"path": "/workspace/src/config.rs"})
[outrig] tool call: fs__write_file({"path": "/workspace/src/config.rs", ...})
[outrig] tool call: shell__exec({"cmd": "cargo check"})
Done. I added a `///` doc comment describing the function's inputs and the
TOML keys it expects. `cargo check` passed with no warnings. Diff:
[diff snippet]
>
Behind the scenes the agent may make many tool calls per turn – Rig drives the model-tool-model loop until the model emits a normal text reply with no tool calls. Tool-call traces appear on stderr; assistant text is printed on stdout.
Each turn has a tool-call cap. The compiled-in default is 50; a top-level
tool-call-cap in config changes the default, [agents.<name>].tool-call-cap overrides it for
one agent, and outrig run --max-tool-calls <n> overrides both for the current run. The cap is
per turn, so a follow-up prompt starts a fresh count.
Each individual tool result also has a byte cap before it is appended to the LLM-visible
conversation history. The compiled-in default is 262144 bytes (256 KiB); a top-level
tool-result-cap in config changes the default, [agents.<name>].tool-result-cap overrides it
for one agent, and outrig run --max-tool-result-bytes <n> overrides both for the current run.
If a tool returns more than the cap, outrig keeps the head of the result and appends a marker
that includes the original size, the cap, and a hint to narrow the next query.
When the tool-call cap fires, outrig ends the current turn and keeps protocol-valid partial conversation history. If the model had already asked for the next tool call, outrig records a tool result saying that call was not executed because the cap was reached:
[outrig] tool-call iteration cap (50) reached; ending turn
[outrig] partial history retained -- send another prompt (e.g. "continue")
to keep going, or "/reset" to drop it.
Type continue, or any more specific instruction, to let the next turn pick up from the retained
tool calls with a fresh cap. If the skipped tool call is still needed, the model can ask for it
again. Use /reset first when you want to drop that history.
The REPL is line-buffered. Multi-line input is not supported in v0.
TODO: Incomplete – multi-line / paste-mode input is deferred.
Slash commands
Anything starting with / is a REPL command, not a model prompt:
| Command | Effect |
|---|---|
/help | Print the slash-command list to stderr. |
/tools | List every tool currently registered with the agent, with descriptions. |
/reset | Clear conversation history; container and MCP servers stay up. |
/quit | Exit cleanly (same as EOF/Ctrl-D). |
> /tools
[outrig] tools available (4):
fs__list_directory List the contents of a directory.
fs__read_file Read a file's contents.
fs__write_file Write a file (overwrites existing).
shell__exec Run a shell command and return stdout/stderr.
> /reset
[outrig] history cleared
>
Interrupting and exiting
- Ctrl-C during a turn cancels the in-flight LLM/tool call. The REPL prints
[outrig] interruptedto stderr and returns to a>prompt with conversation history intact, so you can redirect the agent. - Ctrl-D at an empty prompt ends the session: closes MCP server stdios, stops the container, finalizes the session record, exits.
- A second Ctrl-C without an intervening prompt also exits.
> please refactor everything ^C
[outrig] interrupted
> never mind, just summarise the file types in this repo.
...
When something goes wrong
Common failures and what they look like:
$ outrig run
error: no .agents/outrig/config.toml found in current directory or any parent
help: run `outrig init` to initialize
You’re not inside an outrig-configured repo. Either cd into one or pass --config <path>.
$ outrig run
[outrig] container-config: coding
error: container-config "coding" is missing required key: dockerfile
The selected [containers.<name>] block is incomplete. See
Reference -> Config.
$ outrig run
[outrig] container-config: coding
[outrig] image: outrig-cache:8c2a4f7e91d6b5a3 (cache hit)
[outrig] container started: outrig-20260501T134412-3f2a
[outrig] mcp fs: error: failed to spawn `mcp-server-filesystem` in container
[outrig] caused by: exec: "mcp-server-filesystem": executable file not found in $PATH
The MCP server binary isn’t in the image. Install it in the Dockerfile.
$ outrig run
[outrig] container-config: coding
[outrig] image: outrig-cache:8c2a4f7e91d6b5a3 (cache hit)
[outrig] container started: outrig-20260501T134412-3f2a
[outrig] mcp fs: initialized
[outrig] mcp shell: initialized
[outrig] model: gpt-4o-mini
[outrig] session id: 20260501T134412-3f2a
> hi
error: LLM call failed: 401 Unauthorized
caused by: provider returned: invalid_api_key
OPENAI_API_KEY is unset, expired, or pointing at the wrong endpoint.
See also
- outrig build – pre-warming the image cache.
- Sessions – what
--session-dirwrites and how to inspect it. - Reference -> CLI – all flags.