Skip to main content
Agent VMs come pre-configured with development tools and Claude Code. You can customize the environment with custom baked images and repo hooks. This page explains what is available and how to extend it. For per-repo setup that runs after cloning, including dependency installs and code generation, see Repo Hooks.

Pre-installed tools

Every agent VM starts from a base image built on Debian 12 (Bookworm) with the following tools pre-installed: Language runtimes (Go, Python, Node.js, Ruby, Rust, etc.) are not installed. They belong in a custom image baked from your recipe. The base image is maintained by the Murmur platform and updated regularly with security patches. Because agents have passwordless sudo, they can install missing packages at runtime with commands such as sudo apt-get install. On an image whose recipe adds Node.js, npx playwright install --with-deps chromium also works. Runtime installs add time to every spawn, so bake stable dependencies into a custom image. Organizations that want a non-root agent can remove /etc/sudoers.d/murmur in their recipe’s provisioning script. See Agent VM controls for why root on the VM is not an isolation boundary.

The base image provisioning script

The exact script that builds the base image, for reference when deciding what your recipe still needs to install:

Per-spawn setup

Murmur has no environment-level startup script: an environment is a pure compute shape (substrate, machine type, disk type, and disk size). Setup that must run on every spawn belongs in a repo hook, which runs after the repos are cloned and before the agent starts. Everything stable belongs in a custom image.

Custom images

For toolchains and system packages, bake a custom image instead of installing them on every spawn. Custom images use recipes and murmur bake to produce VM images with your toolchain pre-installed.

Recipes

A recipe defines how to build a custom image:

Baking an image

This starts an image build process. You can monitor progress with:
Once the bake completes, set the workspace’s image_ref to the resulting catalog image. The image is named <recipe>-<first 16 characters of the image hash> (with -<region> appended on AWS). List your images with murmur get image. Every VM the workspace launches then boots from it.

When the image is used

A VM that boots from a custom image already has all your tools installed, with no per-spawn install delay.

Identifying the image from inside a VM

Every image baked from a recipe records its own build at /etc/murmur/baked-image.json. The file is written during the bake, so every VM booted from that image reads the same values, and it is readable by any user on the VM. No sudo, no network, no Murmur CLI:
Pull out one field with jq:
The catalog image record for the same build is named <recipe>-<first 16 characters of imageHash>, with -<region> appended on AWS, so you can go from a running VM to the record it came from:
Every value describes the build and is fixed at bake time. The recipe may have been edited or deleted since, and the workspace may have been moved to a newer image. Under every recipe build sits the platform base image, which stamps two files of its own, so a VM booted from a recipe build has all three:

Environment variables on VMs

Agent VMs have several environment variables available: Mounted secrets appear as their own environment variables, described below.

Secrets

Secrets are delivered as environment variables (or files) through secret mounts. A workspace declares them in runtime_secret_mounts; your own secrets are mounted with murmur secret mount; murmur spawn -e NAME forwards one variable for a single spawn. An environment mount uses the secret’s name as the variable name unless the mount sets env_name:
Secrets are decrypted from KMS in memory only. They are never written to disk. See Encryption for details on how secrets are protected.

Claude Code configuration

Murmur writes Claude Code’s ~/.claude/settings.json on the VM before each turn, merging into any existing file. It configures:
  • Fast mode: fastMode, on when the spawn asks for fast mode (fast_mode: true in .murmur/murmur.yaml sets the default)
  • Permissions: a permissions.allow list of pre-approved tools, such as murmur MCP tools and read-only gh pr commands
  • Hooks: a Stop hook that keeps the agent from finishing while checklist tasks are incomplete, and PreToolUse hooks that redirect interactive tools that cannot work unattended
The murmur MCP server is registered separately in ~/.claude.json. The model is not set in settings.json; it reaches Claude Code through ANTHROPIC_MODEL and the agent definition (see Model Selection). Agents should not modify settings.json directly. To customize Claude Code behavior, use murmur spawn --append-system-prompt or define an agent persona.

Repo hooks vs. baked images

Use this decision table to choose between a repo hook and a custom image:

Rules of thumb

  • If the setup changes with the code (dependencies, codegen), use a repo hook.
  • If the install takes over 2 minutes, bake it into an image.
  • If you need GPU drivers or CUDA, always use a custom image: these installations are too large and slow to repeat on every spawn.
  • If a tool is needed rarely or unpredictably, skip both. Agents have passwordless sudo and can install it themselves when a task actually needs it.
You can combine both approaches: use a custom image for the heavy base (Go, Docker, etc.) and a repo hook for the per-branch remainder (dependency installs, config files).