Customizing VM Images
The VM image is defined by TOML configs in guest/config/. To change what’s installed in the VM — packages, AI providers, MCP servers, security policy — you edit these configs and rebuild.
The config directory
Section titled “The config directory”guest/ config/ build.toml Build settings (base image, compression, kernel branch) manifest.toml Package metadata ai/ anthropic.toml Claude Code provider google.toml Gemini CLI provider openai.toml Codex provider packages/ apt.toml System packages (coreutils, git, curl, python3, ...) python.toml Python packages (numpy, requests, pytest, ...) mcp/ capsem.toml Built-in MCP server security/ web.toml Domain allow/block policy vm/ resources.toml CPU, RAM, disk limits environment.toml Shell config, bashrc, PATH, TLS kernel/ defconfig.arm64 Kernel config (arm64) defconfig.x86_64 Kernel config (x86_64) artifacts/ banner.txt Login banner (ASCII art shown at session start) tips.txt Random tips (one shown per login) capsem-bashrc Shell configuration (PS1, aliases, banner/tips display) capsem-init PID 1 init script capsem-doctor In-VM diagnostic suite capsem-bench In-VM benchmarks diagnostics/ Test scripts for capsem-doctorCommon changes
Section titled “Common changes”Add a system package
Section titled “Add a system package”Edit guest/config/packages/apt.toml:
[apt]packages = [ # ... existing packages ... "your-package",]Add a Python package
Section titled “Add a Python package”Edit guest/config/packages/python.toml:
[python]packages = ["numpy", "pandas", "requests", "pytest", "your-package"]Add an AI provider
Section titled “Add an AI provider”Create guest/config/ai/your-provider.toml:
[your_provider]name = "Your Provider"description = "Your LLM provider"enabled = true
[your_provider.api_key]name = "API Key"env_vars = ["YOUR_PROVIDER_API_KEY"]prefix = "sk-"docs_url = "https://your-provider.com/keys"
[your_provider.network]domains = ["api.your-provider.com"]allow_get = trueallow_post = true
[your_provider.install]manager = "npm"prefix = "/opt/ai-clis"packages = ["your-provider-cli"]Change network policy
Section titled “Change network policy”Edit guest/config/security/web.toml to allow or block domains:
[web]custom_allow = ["*.your-corp.com"]custom_block = ["*.banned-domain.com"]Customize login tips
Section titled “Customize login tips”Edit guest/artifacts/tips.txt — one tip per line, # lines are ignored. A random tip is shown each time a user opens a session:
pip install and uv pip install work out of the box.npm install -g works -- packages go to your scratch disk.Run capsem-doctor to verify sandbox integrity.Your custom tip here.Customize the login banner
Section titled “Customize the login banner”Edit guest/artifacts/banner.txt — shown at the top of every new session, before the AI tool status and tips.
Change VM resources
Section titled “Change VM resources”Edit guest/config/vm/resources.toml:
[resources]cpu_count = 8ram_gb = 8scratch_disk_size_gb = 32Rebuild and test
Section titled “Rebuild and test”After editing configs:
# 1. Validate your changes (fast, catches typos)uv run capsem-builder validate guest/
# 2. Preview the generated Dockerfile without buildinguv run capsem-builder build guest/ --dry-run
# 3. Rebuild the rootfs (kernel rebuild only needed if you changed defconfig)just build-rootfs
# 4. Boot and verifyjust run "capsem-doctor"If you changed kernel config, rebuild everything:
just build-assetsjust run "capsem-doctor"What triggers a full rebuild?
Section titled “What triggers a full rebuild?”| What you changed | Rebuild command |
|---|---|
packages/*.toml | just build-rootfs |
ai/*.toml | just build-rootfs |
mcp/*.toml | just build-rootfs |
security/web.toml | No rebuild — applied at boot via settings |
vm/resources.toml | No rebuild — applied at boot via settings |
vm/environment.toml | No rebuild — applied at boot via settings |
kernel/defconfig.* | just build-kernel |
build.toml | just build-assets (full rebuild) |
guest/artifacts/tips.txt | just build-rootfs (baked into rootfs) |
guest/artifacts/banner.txt | just build-rootfs (baked into rootfs) |
guest/artifacts/capsem-bashrc | just build-rootfs (baked into rootfs) |
guest/artifacts/capsem-init | just run (repacks initrd automatically) |
Settings-only changes (security, resources, environment) take effect on the next just run without any rebuild — capsem-builder generates defaults.json which the host reads at boot.
Builder CLI reference
Section titled “Builder CLI reference”uv run capsem-builder validate guest/ # lint all configsuv run capsem-builder inspect guest/ # show resolved config summaryuv run capsem-builder build guest/ --arch arm64 # build for arm64uv run capsem-builder build guest/ --dry-run # preview Dockerfilesuv run capsem-builder doctor guest/ # check prerequisitesFurther reading
Section titled “Further reading”- Build System Architecture — how capsem-builder works internally (Pydantic models, Jinja2 templates, Docker pipeline)
- Custom Images Reference — full config schema, corporate deployment, install methods, manifest format
- Life of a Build — how image assets flow into the boot pipeline