Agents

Each agent is a tool: add it to a template's tools: list, and every branch of the template has it, set up for unattended work. The agent's credentials stay on the host, where isx init configures them, and the proxy adds them to the agent's requests as they leave the instance. The sections below cover one agent each.

An agent that uses a model server on your host, such as Ollama, reaches it once you expose its port and point the agent at host.isx.internal.

Claude Code

Claude Code is Anthropic's official CLI for Claude, and works with all three Claude auth modes: API key, Claude Pro/Max OAuth and Vertex AI. Add it to any template with tools: [claude]:

name: tpl-claude-dev
description: Isolated dev environment with Claude Code
parent: tpl-minimal
repos:
  - url: https://github.com/myorg/myproject.git
    path: ~/myproject
workdir: ~/myproject
tools:
  - claude
default-action: claude

The claude tool downloads the latest Claude Code binary, configures permissions for unattended agent use, and sets up authentication. The key or token stays on the host, and the proxy adds it to Claude Code's requests as they leave the instance.

Parameters

Parameter Default What it does
model Claude Code's own default The model Claude Code uses
advisor-model Claude Code's own default The model Claude Code consults as its advisor, such as opus
theme Claude Code's own default Colour theme: dark, light, dark-daltonized or light-daltonized
editor-mode Claude Code's own default Input editor mode: normal or vim
output-style Claude Code's own default Response style: Default, Proactive, Explanatory or Learning
attribution-commit Claude Code's own default The trailer Claude Code adds to its commits, such as Assisted-By: Claude Code <noreply@anthropic.com>
attribution-pr Claude Code's own default The text Claude Code adds to its pull requests; an empty string omits it

Model IDs follow the claude-* naming convention: claude-opus-5-5, claude-sonnet-5-5, claude-haiku-5-5. advisor-model also takes the aliases opus, sonnet and haiku, which model does not. A child template can set any of these parameters again without reinstalling Claude Code.

tools:
  - claude:
      model: claude-sonnet-5-5

What the build sets up

The build gives Claude Code bypass-permissions mode with every tool allowed, and turns off auto-update, error reporting, the feedback survey and its own sandbox. It leaves Claude Code's telemetry on, because turning it off also turns off the advisor.

It accepts the onboarding and the trust prompt for the home directory, so the first session starts without questions.

The footer shows Running unconstrained in isx [version] [container name]. The default action (default-action: claude above) resumes your most recent session, in that session's directory.

Codex CLI

Codex CLI is OpenAI's coding agent, and signs in with an OpenAI API key. Add it to any template with tools: [codex]:

name: tpl-codex-dev
description: Isolated dev environment with Codex CLI
parent: tpl-minimal
repos:
  - url: https://github.com/myorg/myproject.git
    path: ~/myproject
workdir: ~/myproject
tools:
  - codex
default-action: codex

Codex needs an OpenAI API key (create one here). API usage needs billing credits, even on free accounts. Run isx init to configure the key: it stays on the host, and the proxy adds it to Codex's requests as they leave the instance.

Parameters

By default Codex picks both the model and the reasoning effort.

Parameter Default What it does
model Codex picks Any model your OpenAI account can use (model list)
effort Codex picks Reasoning effort: minimal, low, medium, high or xhigh
tools:
  - codex:
      model: gpt-5.3-codex
      effort: high

What the build sets up

The build configures Codex for unattended use, turns off its update check and marks the home directory as trusted. The build also gives Codex the environment primer, a short text that tells an agent about its instance, and does not write ~/.codex/AGENTS.md. The default action resumes your most recent session.

The footer shows the model, the current directory and Running unconstrained in isx [version] [container name]. That message is the name of a permission profile with full filesystem and network access. The build also turns on live web search.

The version and instance name refresh at login, including in a new branch of a template. Use /statusline to customize the footer; the permissions item displays the isx message.

Pi Coding Agent

Pi is a provider-agnostic CLI coding agent. Its default provider is anthropic, so it uses your Claude account: an API key, Claude Pro/Max OAuth or Vertex AI. A template with Pi alone needs a Claude account unless it sets Pi's provider parameter, described below. Add it to any template with tools: [pi]:

name: tpl-pi-dev
description: Isolated dev environment with Pi coding agent
parent: tpl-minimal
repos:
  - url: https://github.com/myorg/myproject.git
    path: ~/myproject
workdir: ~/myproject
tools:
  - pi
shell-command: pi

The credential stays on the host, and the proxy adds it to Pi's requests as they leave the instance. To use Pi without making it the default shell, omit shell-command and launch it manually after isx shell. With default-action: pi instead, the instance opens Pi resuming your most recent session, in that session's directory.

Every template build puts the environment primer at /AGENTS.md, which Pi loads in every directory. Pi gets this file whether or not the template also installs Claude Code. Your own ~/.pi/agent/AGENTS.md and project AGENTS.md files load as usual; isx never writes them.

Pi's footer adds Running unconstrained in isx [version] [container name] below the model and directory. It comes from an extension at /etc/isx/pi/isx-status.ts, loaded by the extensions entry isx writes in ~/.pi/agent/settings.json. The version and instance name are read when Pi starts, so a branch shows its own name. Your own extensions in ~/.pi/agent/extensions/ load as usual.

Parameters

Parameter Default What it does
provider anthropic The API Pi talks to; also accepts openai, google, google-vertex or vertex
model claude-sonnet-5-5 for anthropic, otherwise Pi's own The model Pi uses

The openai provider uses your OpenAI key, as shown below. A provider isx does not manage needs no credential from isx: Pi signs in to it itself.

The google provider is the Gemini API, and uses your Gemini key, as Gemini CLI does. The google-vertex provider runs Gemini models on Vertex AI, and needs a Vertex AI Claude account. isx also accepts vertex as a name for this provider, and writes google-vertex, the name Pi knows, in Pi's settings.

On Vertex AI, Pi sends its calls with an API key that is a proof: a token isx gives the instance in place of the credential. The proxy checks the proof and moves each call into your account's project and region.

The proxy signs the call with the host's GCP credentials, which never enter the instance. It uses those credentials only for Gemini model calls, and refuses any other Vertex AI call that carries the proof.

Pi can also run against OpenAI, using the same key as Codex CLI:

tools:
  - pi:
      provider: openai
      model: gpt-4.1

opencode

opencode is a provider-agnostic CLI coding agent. Like Pi, its default provider is anthropic, so it uses your Claude account: an API key, Claude Pro/Max OAuth or Vertex AI. Anthropic bills a Claude Pro or Max subscription used from opencode as extra usage, since opencode is not Claude Code. Add it to any template with tools: [opencode]:

name: tpl-opencode-dev
parent: tpl-minimal
tools:
  - opencode
default-action: opencode

The default action opens opencode in the directory of your most recent session, and continues that session. The credential stays on the host, and the proxy adds it to opencode's requests as they leave the instance. opencode reads a proof from OPENCODE_ANTHROPIC_API_KEY, which its settings name, so Claude Code's own sign-in is left alone.

What the build sets up

isx writes ~/.config/opencode/opencode.json, which pins the model and turns off update checks and session sharing. It also allows what opencode would otherwise ask about: reading .env files, directories outside the project, and repeating a tool call. opencode's plan agent still cannot edit files. The settings load the environment primer from /AGENTS.md, the file Pi reads.

Skills isx installs in ~/.agents/skills load in opencode as they do in Claude Code. Your own ~/.config/opencode/AGENTS.md and project AGENTS.md files load as usual. Each build writes opencode.json again, so keep your own settings in a project opencode.json. opencode shows no isx footer: it has no place for one.

Parameters

Parameter Default What it does
provider anthropic The API opencode talks to; also accepts openai and google
model claude-sonnet-5-5 for anthropic, otherwise opencode's own The model opencode uses
small-model opencode's own The model for small tasks such as session titles; setting model does not change it

The openai provider uses your OpenAI key, as Codex CLI does. The google provider is the Gemini API, and uses your Gemini key, as Gemini CLI does. A provider isx does not manage needs no credential from isx: opencode signs in to it itself.

tools:
  - opencode:
      provider: openai
      model: gpt-4.1

Gemini CLI

Google's Gemini CLI signs in with a Gemini API key. Add it to a template with tools: [gemini-cli]:

name: tpl-gemini-dev
parent: tpl-minimal
tools:
  - gemini-cli
default-action: gemini-cli

Run isx init on the host and select Gemini CLI to configure the key. isx stores keys in host-side gemini.accounts.<name>.apiKey, with gemini.default selecting the default account. Use accounts: { gemini: work } in a template or isx branch --from tpl-gemini-dev --account gemini=work my-gemini to select a named account.

The instance receives a GEMINI_API_KEY proof placeholder. The proxy verifies it and adds the selected key to requests to generativelanguage.googleapis.com as they leave the instance. Gemini CLI reads the placeholder when launched, so no API key or proof is saved in its settings.

This integration supports Gemini API keys; Google OAuth is not supported. Gemini models on Vertex AI are served through Pi instead.

After upgrading both isx and isx-proxy, rebuild existing Gemini templates and branch new instances. An instance from an older template keeps a login notice until its template is rebuilt. The build removes that notice, including when a child template inherits Gemini, and adds the proof environment.

Parameters

Parameter Default What it does
model Gemini CLI's own default The model, as a native Gemini model ID

A child template can set model again without reinstalling the CLI.

tools:
  - gemini-cli:
      model: gemini-4-argon

What the build sets up

The tool installs @google/gemini-cli and writes ~/.gemini/settings.json, which disables:

The tool also writes ~/.gemini/policies/isx-auto-approve.toml, which auto-approves tool calls in normal, auto-edit and YOLO modes. The policy applies to direct gemini launches, headless invocations and the default action, without extra flags. Plan mode retains its normal policy behavior.

Gemini's shell checks can still require approval for commands outside the workspace or commands it cannot parse; --yolo remains available for full YOLO behavior.

The policy uses priority zero, so higher-priority user rules can override it. Remove the file to restore upstream approval defaults.

When gemini-cli is installed, every template build writes the environment primer to ~/.gemini/extensions/isx/GEMINI.md, including inherited template notes, installed tools and cloned repositories. That file belongs to an extension named isx, which Gemini CLI loads beside your own ~/.gemini/GEMINI.md. The build never writes your file, and project GEMINI.md files remain separate.

The extension file is owned by agentuser and regenerated on rebuild. A rebuild also removes the copy an older build left in ~/.gemini/GEMINI.md, unless you changed its first line. Launching with --extensions naming other extensions leaves the primer out. The tool leaves context.fileName unset.

Bob Shell

Bob Shell is IBM's AI-powered coding assistant, and signs in with an IBM API key (create one here). Add it to any template with tools: [bob]:

name: tpl-bob-dev
description: Isolated dev environment with Bob Shell
parent: tpl-minimal
repos:
  - url: https://github.com/myorg/myproject.git
    path: ~/myproject
workdir: ~/myproject
tools:
  - bob
default-action: bob

Run isx init to configure the key: it stays on the host, and the proxy adds it to Bob's requests as they leave the instance. An instance holds only a placeholder value.

During isx init you are asked to accept the IBM license agreement. When you accept, isx configures the acceptance in every instance, so Bob Shell does not prompt again.

The default action resumes your most recent task with --auto-approve, which auto-approves all tool calls; running bob manually in a shell uses normal approval mode. The build trusts the home directory and turns off auto-update and the update reminder.

Parameters

Parameter Default What it does
max-session-turns Bob's own default The most turns a session may take; -1 for unlimited
compression-threshold Bob's own default The share of the context window, 0.0 to 1.0, at which Bob compresses the conversation
checkpointing Bob's own default true or false: whether Bob keeps safety checkpoints

A child template can set any of them again without reinstalling Bob.

GitHub Copilot CLI

GitHub Copilot CLI signs in with the same GitHub personal access token as the gh tool; no separate credential is needed. Add it to a template with tools: [copilot]:

name: tpl-copilot-dev
description: Isolated dev environment with GitHub Copilot CLI
parent: tpl-minimal
repos:
  - url: https://github.com/myorg/myproject.git
    path: ~/myproject
workdir: ~/myproject
tools:
  - copilot
shell-command: copilot

Run isx init to configure your GitHub token if you have not already. The build auto-approves every tool call, in interactive and headless runs alike, the same as --yolo.

Parameters

By default Copilot picks the model, the reasoning effort and the context window tier.

Parameter Default What it does
model Copilot picks Any model your Copilot plan offers, such as claude-opus-5.5, or auto
effort Copilot picks Reasoning effort: none, minimal, low, medium, high, xhigh or max; the levels a model supports vary
context Copilot picks Context window tier: default or long_context, for models that offer one
tools:
  - copilot:
      model: claude-opus-5.5
      effort: medium
      context: long_context

The build writes these parameters to Copilot's ~/.copilot/settings.json as model, effortLevel and contextTier, and a child template can set any of them again without reinstalling Copilot. The same file always holds defaultPermissionMode: allow-all, so interactive sessions start in Allow All.

Agent Skills

A template can declare agent skills for the build to install. Skills are installed once into the template, at ~/.agents/skills, the shared location any agent can read, and inherited by every instance branched from it. Claude Code finds them through ~/.claude/skills.

name: tpl-skills
description: Agent with security skills
parent: tpl-minimal
skills:
  repo: myorg/claude-skills      # default catalog for bare skill names
  list:
    - security-review            # short name → myorg/claude-skills@security-review
    - code-review                # short name → myorg/claude-skills@code-review
    - xixu-me/skills@xget        # explicit owner/repo@skill-name
    - myorg/catalog              # all skills from a repo

There is no implicit default catalog: repo is only needed to resolve bare skill names, such as security-review above. When all entries use the fully qualified owner/repo@skill or owner/repo form, you can omit repo and use the list shorthand:

skills:
  - xixu-me/skills@xget
  - myorg/catalog

Skill source formats:

Form What it selects
owner/repo@skill-name One skill from a GitHub repo
owner/repo All skills from a GitHub repo
https://github.com/owner/repo The same as owner/repo, with @skill-name accepted too
./local-path A local directory, relative to where isx build runs
/absolute/path A local directory, by absolute path
skill-name A bare name, resolved against the skills.repo field, which bare names require

A local directory that holds a SKILL.md is one skill, named after the directory; otherwise each subdirectory with a SKILL.md is one. From a GitHub repo, every top-level <name>/SKILL.md on main or master is a skill. Only the SKILL.md is installed; isx caches the GitHub ones on the host at ~/.cache/incus-spawn/skills/.

To find available skills, browse skills.sh.

Agent Environment Context

Every build writes a short primer for the agents the template installs, so each starts its sessions knowing where it is. The primer says that the instance is disposable, sudo needs no password, the proxy handles credentials, isx-trust fixes a runtime's own CA bundle, and outward-facing actions such as opening a PR wait until asked.

It also lists the tools and repositories the template provides.

The build stores it once, in /etc/isx/agent-instructions.md. With Claude Code it appears at /etc/claude-code/CLAUDE.md, and with Pi or opencode at /AGENTS.md, both links to that one file. With Gemini CLI, the isx extension's ~/.gemini/extensions/isx/GEMINI.md gets a copy you own.

Editing one of the links changes the stored file, so both agents read the edit, and the next build replaces every copy of the primer.

With Codex CLI, /etc/codex/requirements.toml holds the primer as managed developer instructions, which Codex adds to your own. A template that ships its own requirements.toml keeps it, so Codex does not get the primer, and the build warns you of that.

Your own ~/.claude/CLAUDE.md and project CLAUDE.md files load as usual.

Templates and tools can add their own lines to the primer with agent_note:

name: tpl-openjdk
parent: tpl-minimal
agent_note: |
  The build needs a boot JDK of 26/27/28. This box ships 26 at $JAVA_HOME and
  deliberately omits 25.

A tool's note, and any skills it ships, are added to every template that installs the tool. Bare skill names in a tool resolve against the tool's own skills.repo:

name: mvnd
description: Apache Maven Daemon 1.x
agent_note: |
  `mvnd` is Maven running as a resident daemon: prefer it over `mvn` for repeated
  builds in the same repo. It takes the same goals and flags as `mvn`.
skills:
  repo: myorg/catalog
  list:
    - mvnd-builds

When to write a note

The agent reads its notes in every session, so write a note only for things the agent would otherwise get wrong: a required flag, a version to avoid, a fix that looks obvious and is wrong. Be specific:

agent_note: |
  Run configure with CC=/usr/bin/gcc CXX=/usr/bin/g++. Without them it aborts on
  /usr/lib64/ccache/gcc being a symlink; dropping --enable-ccache "fixes" it and
  silently costs every later rebuild.

Some content is better placed elsewhere:

Instead of Use
agent_note: Maven 3.9 build tool description, which is what template and tool listings show
agent_note: maven, podman and jtreg are installed Nothing: the primer already lists installed tools and cloned repos
agent_note: Build with 'make images', test with 'make test TEST=tier1' A skill, which loads on demand rather than in every session
agent_note: Be careful when editing the parser A specific constraint, or nothing at all
agent_note: Follow the Quarkus code style The repository's own CLAUDE.md, which applies only to work in that repo

Changing a note marks the templates that use it as out of sync (△ in the TUI); rebuild them with isx build --out-of-sync.