A NixOS-based virtual machine for providing safe, isolated development environments for AI agents.
Agentbox creates reproducible, sandboxed Linux VMs where AI coding agents can safely execute code, run tests, and interact with development tools without affecting the host system.
- Isolated execution - Agents run in a fully sandboxed NixOS VM
- Flexible project sources - Mount from host, copy for isolation, or clone from git
- Host file sharing - Securely share project files and configurations via 9p virtfs
- Reproducible environments - Declarative Nix configuration ensures consistency
- Customizable - Override any option to match your project's needs
- Cross-platform - Works on macOS (Apple Silicon & Intel) and Linux
No additional setup required. Just ensure you have Nix with flakes enabled.
Building Linux VMs on macOS requires a Linux builder. You have two options:
-
nix-darwin with linux-builder based on QEMU
-
Determinate Nix with linux-builder - uses Apple's virtualization framework (at the time of writing this, it is not a publicly available feature)
# Clone and run
git clone https://github.com/gotha/agentbox
cd agentbox
nix run .#vmAgentbox provides an installable skill that teaches AI coding agents how to create and manage VMs autonomously. This enables agents to safely execute code in isolated environments.
Install the skill for your AI coding agent using npx skills:
# Install for all supported agents
npx skills add gotha/agentbox
# Install for specific agents
npx skills add gotha/agentbox --agent claude-code --agent cursor --agent augmentSupported agents: Claude Code, Cursor, Augment, Codex, OpenCode, Cline, Roo, Windsurf, GitHub Copilot.
Once installed, instruct your AI agent to use agentbox when you need isolated execution:
"Use agentbox to run the tests for this project in an isolated VM"
"Create an agentbox VM for this project so we can safely experiment with the code"
"Set up an isolated development environment using agentbox"
The agent will:
- Analyze your project to detect required packages and dependencies
- Create a
.agentbox/flake.nixconfiguration tailored to your project - Start a VM and connect via SSH
- Execute tasks safely inside the isolated environment
- Commit and push changes via git when using git source type
- Source type: Git clone (if remote exists) → Copy (no remote) → Mount (only if explicitly requested)
- Packages: Auto-detected from project files (package.json → Node.js, go.mod → Go, etc.)
- Docker: Enabled if Dockerfile or docker-compose.yml is detected
- AI tools: Enables its own CLI tool (auggie, cursor, etc.) inside the VM
Import agentbox into your own flake to create project-specific VMs. See the examples folder for complete configurations:
- minimal-auggie-mount - Minimal VM with Auggie CLI and mounted project source
- minimal-cursor-mount - Minimal VM with Cursor CLI and mounted project source
- custom-tools-git-clone - Full-featured Go project VM with git source, SSH keys, Docker, and custom packages
- custom-tools-dotfiles-git-clone - Full-featured Go project VM with git source, SSH keys, Docker, custom packages and user's dotfiles to configure neovim, tmux, zsh and git via home-manager
After creating your flake.nix, run the VM with:
# Run VM in headless mode (recommended)
nix run .#vmThe default credentials are:
- Username:
dev - Password: empty
| Option | Type | Default | Description |
|---|---|---|---|
agentbox.vm.hostname |
string | "dev-vm" |
VM hostname |
agentbox.vm.cores |
int | 4 |
Number of CPU cores |
agentbox.vm.memorySize |
int | 8192 |
RAM in megabytes |
agentbox.vm.diskSize |
int | 50000 |
Disk size in megabytes |
agentbox.user.name |
string | "dev" |
Primary user name |
agentbox.networking.ports |
list of int | [22] |
TCP ports to open |
agentbox.packages.extra |
list of package | [] |
Additional packages to install |
agentbox.environment.variables |
attrs of string | {} |
Environment variables |
agentbox.hostShares |
list of hostShare | [] |
Host directories to sync into VM |
| Option | Type | Default | Description |
|---|---|---|---|
agentbox.project.source.type |
enum | "mount" |
Source type: "mount", "copy", or "git" |
agentbox.project.source.path |
string or null | null |
Host path for mount/copy (auto-detects via marker if null) |
agentbox.project.source.refresh |
enum | "if-missing" |
Refresh policy: "always" or "if-missing" (copy/git only) |
agentbox.project.source.required |
bool | true |
Fail boot if source setup fails |
agentbox.project.source.git.url |
string or null | null |
Git repository URL (required for git type) |
agentbox.project.source.git.ref |
string or null | null |
Git ref to checkout (uses default branch if null) |
agentbox.project.source.git.shallow |
bool | false |
Use shallow clone |
agentbox.project.source.git.depth |
int | 1 |
Clone depth (when shallow is true) |
agentbox.project.source.copy.excludePatterns |
list of string | [] |
Patterns to exclude from rsync copy |
agentbox.project.destPath |
string | "/home/dev/project" |
Destination path in VM |
agentbox.project.marker |
string | "flake.nix" |
File that identifies project root |
agentbox.project.validateMarker |
bool | true |
Validate marker file exists after setup |
| Option | Type | Default | Description |
|---|---|---|---|
agentbox.docker.enable |
bool | false |
Enable Docker daemon and packages |
agentbox.docker.syncConfigFromHost |
bool | false |
Copy ~/.docker from host to guest |
agentbox.auggie.enable |
bool | false |
Enable Auggie (Augment Code CLI) |
agentbox.auggie.syncConfigFromHost |
bool | false |
Copy ~/.augment from host to guest |
agentbox.claudecode.enable |
bool | false |
Enable Claude Code CLI |
agentbox.claudecode.syncConfigFromHost |
bool | false |
Copy ~/.claude from host to guest |
agentbox.codex.enable |
bool | false |
Enable OpenAI Codex CLI |
agentbox.codex.syncConfigFromHost |
bool | false |
Copy ~/.codex from host to guest |
agentbox.crush.enable |
bool | false |
Enable Charmbracelet Crush |
agentbox.crush.syncConfigFromHost |
bool | false |
Copy ~/.local/share/crush from host to guest |
agentbox.cursor.enable |
bool | false |
Enable Cursor CLI |
agentbox.cursor.syncConfigFromHost |
bool | false |
Copy ~/.cursor from host to guest |
Agentbox supports three methods to provide project source code to the VM:
Mounts the host project directory directly into the VM via 9p virtfs. Changes in the VM are immediately reflected on the host (read-write).
agentbox.project = {
source.type = "mount";
# source.path is auto-detected by walking up to find marker file
destPath = "/home/dev/project";
marker = "flake.nix";
};Use case: Interactive development where you want changes to persist to the host.
Copies the project from host to VM using rsync at boot time. The VM has its own isolated copy (changes don't affect host).
agentbox.project = {
source.type = "copy";
source.refresh = "always"; # or "if-missing" to persist changes across reboots
source.copy.excludePatterns = [ ".git" "node_modules" "target" ];
destPath = "/home/dev/project";
};Use case: AI agent sandboxes where you want isolation from the host filesystem.
Clones a git repository directly into the VM at boot time. Supports private repos via SSH keys shared through hostShares.
agentbox.project = {
source.type = "git";
source.git.url = "https://github.com/user/repo.git";
source.git.ref = "main"; # optional: branch, tag, or commit
source.git.shallow = true; # optional: shallow clone
destPath = "/home/dev/project";
};For private repositories, share SSH keys:
agentbox.hostShares = [{
tag = "ssh-keys";
hostPath = ".ssh";
dest = ".ssh";
mode = "700";
fileOverrides = [ "id_ed25519:600" "id_rsa:600" ];
}];
agentbox.project = {
source.type = "git";
source.git.url = "git@github.com:user/private-repo.git";
};Use case: CI/CD environments, reproducible builds, or when you don't have the project locally.
Docker is disabled by default. To enable it:
extraConfig = {
agentbox.docker.enable = true;
# Optionally sync Docker config (credentials, settings) from host
agentbox.docker.syncConfigFromHost = true;
};When enabled, this installs the Docker daemon, docker and docker-compose CLI tools, and adds the user to the docker group.
Auggie is the Augment Code CLI tool for AI-assisted development. It is disabled by default. To enable it:
extraConfig = {
agentbox.auggie.enable = true;
# Optionally sync Augment config (credentials, settings) from host
agentbox.auggie.syncConfigFromHost = true;
};When enabled, this installs the auggie CLI tool from gotha/nixpkgs.
If syncConfigFromHost is enabled, the ~/.augment directory from your host machine will be copied into the VM on boot, allowing the agent to use your Augment credentials.
Cursor CLI for AI-assisted development. It is disabled by default. To enable it:
extraConfig = {
agentbox.cursor.enable = true;
# Optionally sync Cursor config from host
agentbox.cursor.syncConfigFromHost = true;
};When enabled, this installs the cursor-cli from nixpkgs.
If syncConfigFromHost is enabled, the ~/.cursor directory from your host machine will be copied into the VM on boot.
Claude Code is Anthropic's agentic coding tool. It is disabled by default. To enable it:
extraConfig = {
agentbox.claudecode.enable = true;
# Optionally sync Claude config from host
agentbox.claudecode.syncConfigFromHost = true;
};When enabled, this installs claude-code from nixpkgs.
If syncConfigFromHost is enabled, the ~/.claude directory from your host machine will be copied into the VM on boot.
Codex CLI is OpenAI's lightweight coding agent. It is disabled by default. To enable it:
extraConfig = {
agentbox.codex.enable = true;
# Optionally sync Codex config from host
agentbox.codex.syncConfigFromHost = true;
};When enabled, this installs codex from nixpkgs.
If syncConfigFromHost is enabled, the ~/.codex directory from your host machine will be copied into the VM on boot.
Crush is Charmbracelet's glamorous terminal-based AI coding assistant. It is disabled by default. To enable it:
extraConfig = {
agentbox.crush.enable = true;
# Optionally sync Crush config from host
agentbox.crush.syncConfigFromHost = true;
};When enabled, this installs crush from nixpkgs.
If syncConfigFromHost is enabled, the ~/.local/share/crush directory from your host machine will be copied into the VM on boot.
Share host directories (like dotfiles) with the VM:
agentbox.hostShares = [
{
tag = "host-config"; # 9p mount tag
hostPath = ".config"; # Path relative to $HOME on host
dest = ".config"; # Path relative to user home in VM
mode = "700"; # Directory permissions
fileOverrides = [ "secrets.json:600" ]; # Per-file permissions
}
];Agentbox uses the NixOS VM testing framework for end-to-end tests. Tests boot actual VMs and verify functionality.
# Run all tests
nix flake check
# Run a specific test with build logs
nix build .#checks.x86_64-linux.boot --print-build-logs
# Available tests:
# boot - Basic VM boot tests (B1-B5)
# project-mount - Mount source type tests (M1-M6)
# project-copy - Copy source type tests (C1-C6)
# project-git - Git source type tests (G1-G7)
# host-shares - Host shares sync tests (H1-H4)
# tools-docker - Docker integration tests (D1-D4)For interactive debugging, you can run the test driver manually:
# Build the interactive test driver
nix build .#checks.x86_64-linux.boot.driverInteractive
# Run the driver
./result/bin/nixos-test-driver
# In the Python REPL:
>>> start_all() # Start the VM
>>> machine.shell_interact() # Get an interactive shell
>>> machine.succeed("id dev") # Run commands
>>> machine.screenshot("debug") # Take a screenshotTests are located in tests/. Each test file follows this pattern:
# tests/my-feature.nix
{ pkgs, self }:
pkgs.nixosTest {
name = "agentbox-my-feature";
nodes.machine = { config, pkgs, ... }: {
imports = [ self.nixosModules.default ];
# Configure the VM...
};
testScript = ''
machine.start()
machine.wait_for_unit("multi-user.target")
# Add assertions...
'';
}Then add the test to tests/default.nix and update flake.nix if needed.
BSD 3-Clause License. See LICENSE.txt for details.