Skip to content

Run the agents in a container

The tutorial container has everything you need for the session: Claude Code, Codex CLI and OpenCode, plus uv, git, the GitHub CLI (gh), Python 3, the terminal editors vim, emacs and nano, and VS Code in the browser (code-server).

What the container isolates

The run scripts mount your project and named volumes for agent settings and logins. Your host home directory, SSH keys, and other projects are not mounted. The agent can change the mounted project, use supplied credentials, and access the network. Files in the project and named volumes survive container removal; changes elsewhere in the container are discarded. Commit your work with git as usual. Inside a container it is reasonable to allow more autonomy (fewer approval prompts) than on your laptop or on a shared allocation.

Image: ghcr.io/autonomous-scientific-agents/agentic-coding:latest (Linux amd64 and arm64, so it runs on Intel and Apple-silicon machines).

1. Install Podman

We recommend Podman: it is open source, free for everyone, and does not need a background service running as root. Docker works too.

Download and run the installer from podman.io (or brew install podman if you use Homebrew). Podman runs containers in a small Linux virtual machine; create and start it once:

podman machine init
podman machine start

After a restart, run podman machine start again before using the container.

Podman uses WSL 2. In PowerShell:

winget install -e --id RedHat.Podman

Open a new terminal, then create and start the Podman machine (if WSL is not installed yet, init offers to install it; restart and run init again):

podman machine init
podman machine start

After a restart, run podman machine start again before using the container.

sudo apt update && sudo apt install -y podman     # Ubuntu / Debian
# sudo dnf install -y podman                       # Fedora / RHEL

No virtual machine is needed on Linux, and containers run as your own user.

Check that it works:

podman run --rm quay.io/podman/hello

Prefer a graphical app? Podman Desktop installs Podman and sets up the machine for you.

Docker Desktop instead

Docker Desktop (macOS, Windows) or Docker Engine (Linux) also works. Docker Desktop is free for personal use, education and small businesses, but larger organizations need a paid subscription, so check with your institution. With Docker, write docker wherever this page says podman.

The run script uses whichever of podman and docker is running, trying podman first. If both are running, choose with CONTAINER_ENGINE=docker (PowerShell: $env:CONTAINER_ENGINE = "docker").

2. Get the image and the run script

podman pull ghcr.io/autonomous-scientific-agents/agentic-coding:latest
curl -fsSLO https://raw.githubusercontent.com/Autonomous-Scientific-Agents/AgenticCodingTutorial/main/run.sh
chmod +x run.sh

In PowerShell, with the Podman machine running:

podman pull ghcr.io/autonomous-scientific-agents/agentic-coding:latest
irm https://raw.githubusercontent.com/Autonomous-Scientific-Agents/AgenticCodingTutorial/main/run.ps1 -OutFile run.ps1

run.ps1 is the PowerShell version of run.sh and takes the same arguments: wherever this page says /path/to/run.sh, use C:\path\to\run.ps1. If PowerShell answers running scripts is disabled on this system, allow scripts for your user once with Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.

Working in WSL instead? Open your Ubuntu terminal and follow the macOS / Linux tab.

Prefer to build it yourself? Clone this repository and run ./run.sh build (Windows: .\run.ps1 build).

3. Start it in your project

Run the script from the project folder you want the agent to work on. That folder appears as /workspace inside the container. Agent settings and logins are kept in separate named volumes.

cd my-project
/path/to/run.sh            # a bash shell inside the container
claude                     # or: codex, opencode
cd my-project
C:\path\to\run.ps1         # a bash shell inside the container
claude                     # or: codex, opencode

You can also start one tool directly: /path/to/run.sh claude.

For scripts and pipelines, pass a command that can run without an interactive prompt. Both launchers keep standard input open and allocate a terminal only when input and output are connected to a terminal:

printf 'hello\n' | /path/to/run.sh cat
/path/to/run.sh python3 --version > python-version.txt
'hello' | C:\path\to\run.ps1 cat
C:\path\to\run.ps1 python3 --version | Set-Content python-version.txt

Set the required model token in the environment before running an agent without a terminal.

Editors

Editor How
vim, emacs, nano run them in the container shell: vim src/pgmol/api.py, emacs -nw …
VS Code in the browser /path/to/run.sh code, then open http://localhost:8080
VS Code on your desktop copy .devcontainer/ into your project, install the Dev Containers extension, and run Dev Containers: Reopen in Container

Files are shared, so you can also keep editing on your host with any editor while the agent runs in the container.

4. Model access and logins

The *-amsc and *-alcf commands below also work without the container; see Shortcut commands for MAG and ALCF.

Set keys and tokens as environment variables on the host; the run scripts pass them into the container without writing their values into the image or a configuration file. Tools can also save credentials in their named volumes when you log in, as described below. The script passes these variables when they are set:

  • any variable whose name starts with AMSC_ (MAG) or ALCF_ (ALCF)
  • ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, ANTHROPIC_CUSTOM_HEADERS, ANTHROPIC_MODEL and the ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL variables
  • the Claude Code settings CLAUDE_CODE_MAX_OUTPUT_TOKENS, CLAUDE_CODE_AUTO_COMPACT_WINDOW, CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS, CLAUDE_CODE_NO_FLICKER, CLAUDE_CODE_SUBAGENT_MODEL, DISABLE_TELEMETRY and DISABLE_NON_ESSENTIAL_MODEL_CALLS
  • OPENAI_API_KEY, OPENAI_BASE_URL, OPENROUTER_API_KEY

When a shell starts in the container, one line shows what is ready, for example MAG ready (claude-amsc) · ALCF: not logged in (claude-alcf walks you through it) · GitHub ready. Run agent-status to show it again. To list what arrived without printing the values: env | cut -d= -f1 | grep -E 'AMSC|ALCF|ANTHROPIC|OPENAI'.

  • Subscription login: run claude or codex and follow the login prompt. Logins and settings are stored in named volumes, so you sign in once. That covers ~/.claude (including .claude.json: sign-in, trusted folders and MCP servers), ~/.codex, and OpenCode's ~/.config/opencode and ~/.local/share/opencode.
  • GitHub: see GitHub and git below.

AmSC Model Access Gateway (MAG)

For Genesis Mission teams. Follow Get started with MAG to get a personal access token (PAT).

1. Store the PAT on your host under the name AMSC_TOKEN, as MAG's guide describes.

Add this line to ~/.zshrc (macOS) or ~/.bashrc (Linux), then open a new terminal:

export AMSC_TOKEN='<your PAT>'

Set it once as a user variable, then open a new terminal:

[Environment]::SetEnvironmentVariable('AMSC_TOKEN', '<your PAT>', 'User')

No AMSC_TOKEN yet, or it expired? Run claude-amsc anyway: it explains where to get a PAT, asks you to paste it (hidden), checks it with MAG, and uses it for that agent run only. Later launches, including in the same container, ask again. Set it on the host as above to reuse it across launches until it expires.

When the PAT expires. PATs are short-lived. Check your tokens at any time inside the container:

agent-status --check          # asks MAG and ALCF whether your tokens work; never prints them
agent-status --models         # lists the models MAG and ALCF offer you

When MAG rejects the PAT, the *-amsc commands ask for a new one for that run. To use a new PAT for the rest of the container shell, paste it once (nothing appears while you paste, then press Enter):

read -rs AMSC_TOKEN && export AMSC_TOKEN

For the next container, replace AMSC_TOKEN on your host as in step 1. Create the new PAT on myAmSC.

2. Start an agent on MAG. The container has one command per tool. Each uses the settings MAG documents for Claude Code, Codex and OpenCode, and leaves your configuration files alone. Plain claude, codex and opencode keep your normal logins.

Command Default model Change it
claude-amsc Claude Code's default claude-amsc --model claude-haiku
codex-amsc gpt-6-luna codex-amsc -m gpt-6.1-sol, or set AMSC_CODEX_MODEL
opencode-amsc claude-sonnet /models in OpenCode, or set AMSC_OPENCODE_MODEL
cd my-project
/path/to/run.sh claude-amsc          # or: start a shell with /path/to/run.sh, then run any of them

Set defaults on your host before starting the container, for example CLAUDE_CODE_AUTO_COMPACT_WINDOW=100000 for Haiku, or ANTHROPIC_CUSTOM_HEADERS="X-AmSC-MAG-Provider: amazon" to choose the provider for Claude. Check access inside the container:

curl -s -H "Authorization: Bearer $AMSC_TOKEN" https://mag.genesis.americansciencecloud.org/v1/models | head -c 300

OpenCode model menu

bin/opencode-amsc defines the MAG menu in OPENCODE_CONFIG_CONTENT each time it runs. The menu is curated from MAG's /v1/models catalog; it is not downloaded at startup. It keeps the rolling aliases from MAG's OpenCode setup (claude-haiku, claude-sonnet, gemini-flash), which follow the newest version, and adds up to two recent pinned versions per model line, without listing every provider, effort, or service-tier variant. Models with small output limits, or on routes MAG doesn't document, are left out until a live check shows they handle OpenCode's tool calls and file edits. List the current menu with:

opencode-amsc models amsc-mag

Context limits are working budgets, not the catalog maximums: long contexts cost more on every turn, and OpenCode compacts only near the limit. Claude follows MAG's caps (100,000 for Haiku, 200,000 for Sonnet and Opus). GPT models other than GPT-OSS use 272,000, and Gemini Flash and Flash Lite use 1,048,576 as MAG documents for Gemini Flash; the rest use at most 200,000. Reasoning effort is set per model, for example high for gpt-6-luna and medium for Gemini; Claude runs without extended thinking. See MAG model names for routing and effort rules. IDs ending in @google or @amazon select that provider; other IDs let MAG choose.

To start with another model, set AMSC_OPENCODE_MODEL to an ID from the list (with or without the amsc-mag/ prefix), or pick one with /models in the app. For a single message:

AMSC_OPENCODE_MODEL=gemini-3.8-flash@google opencode-amsc
opencode-amsc run -m amsc-mag/claude-opus-5-5 "..."

An already running container keeps its installed wrapper. Pull the newest published image, or rebuild locally with ./run.sh build, then start a new container to use an updated model menu.

ALCF Inference Endpoints

ALCF Inference Endpoints serve open-weight models on ALCF hardware. Their access tokens last 48 hours.

1. Log in once. You need an ALCF account. The simplest way is inside the container: run claude-alcf and follow the prompt. It prints a Globus link; open it, log in, and paste the code back. You can also log in yourself with alcf-tokens login inference. The login is saved in the ai-agents-globus volume and tokens refresh on their own; ALCF asks you to log in again every 30 days.

Or log in on your host

If you also use ALCF outside the container, log in on the host instead (needs uv, step 3 of Getting started):

uv tool install alcf-tokens
alcf-tokens login inference

The run script then calls alcf-tokens get-token inference each time it starts and passes a fresh token as ALCF_AI_TOKEN. The commands use it while ALCF accepts it. After 48 hours they fall back to the in-container login, or you can restart the container to get a fresh one.

Which models are hot. An ALCF model answers right away only while it is loaded ("hot"). Otherwise the first request queues it, which can take minutes. agent-status --hot lists the hot models on each cluster; agent-status --models lists them all, with their state.

When a token expires. agent-status --check shows whether the ALCF token works. The commands get fresh tokens on their own, so you only need to log in again (alcf-tokens login inference) when ALCF asks, every 30 days.

2. Start an agent on ALCF. The commands use Minerva, which serves inkling-bf16, nemotron-3-ultra and gpt-oss-120b, and Sophia for gemma-4-31B-it. They pick the cluster from the model name. The ALCF agents page lists the current endpoints and models.

Command Default model Change it Models
claude-alcf inkling-bf16 claude-alcf --model nemotron-3-ultra, or set ALCF_CLAUDE_MODEL inkling, Nemotron
codex-alcf inkling-bf16 codex-alcf -m nemotron-3-ultra, or set ALCF_CODEX_MODEL inkling, Nemotron
opencode-alcf inkling-bf16 /models in OpenCode, or set ALCF_OPENCODE_MODEL inkling, Nemotron, gpt-oss, Gemma

Only OpenCode can use Gemma: Sophia does not stream Anthropic Messages, which Claude Code needs, and its Responses API returns Gemma's tool calls as text, which breaks Codex.

Other endpoints: set ALCF_ANTHROPIC_BASE_URL (Claude Code) or ALCF_OPENAI_BASE_URL (Codex, OpenCode). To set up the tools by hand instead, see Custom endpoints: ALCF Inference Endpoints. Claude Code and Codex warn that they do not know these models and fall back to default settings; that is expected. gpt-oss-120b does not work with Codex on Minerva.

Inside the container, Codex's own sandbox (bubblewrap) usually cannot start, so codex-amsc and codex-alcf turn it off (danger-full-access); the container is the sandbox. With plain codex, use codex --sandbox danger-full-access.

GitHub and git

Your SSH keys and host GitHub login stay outside the container. Inside it, git uses HTTPS with the gh login. SSH remotes such as git@github.com:org/repo.git are switched to HTTPS automatically, so a project you cloned with SSH on the host still pushes from the container.

Log in once inside the container (recommended). The login is saved in the ai-agents-gh volume, and git push uses it:

gh auth login        # GitHub.com, HTTPS, then log in with a web browser
gh auth status

Or reuse your host login for one session. If gh is logged in on your host, pass its token in:

GH_TOKEN=$(gh auth token) /path/to/run.sh
$env:GH_TOKEN = gh auth token; C:\path\to\run.ps1

The agent can use any token you pass in

A token gives the agent everything that token allows, including pushing to every repository you can write to. For the most control, create a fine-grained personal access token limited to the repositories you work on, and log in with it (gh auth login --with-token) or pass it as GH_TOKEN.

Commits carry your name. The run script reads user.name and user.email from your git configuration on the host and passes them in, so you do not need to configure git inside the container.

Tips

  • Commit before you prompt: the container protects your machine, git protects your project.
  • Get the newest image with podman pull ghcr.io/autonomous-scientific-agents/agentic-coding:latest; the run script does not update it on its own. Do this whenever you download a newer run script.
  • Use another port with PORT=8081 /path/to/run.sh code (PowerShell: $env:PORT = "8081" first).
  • Reset all saved logins and settings: podman volume rm ai-agents-claude ai-agents-codex ai-agents-opencode ai-agents-opencode-config ai-agents-code-server ai-agents-gh ai-agents-globus.
  • On Linux the script makes dev use your own user and group ID, so files the agent writes in the project belong to you.
  • Inside the container you are user dev with sudo, so sudo apt-get install … works; it is gone after the container stops. Add permanent tools to the Dockerfile.