Boxdeck docs
Everything you need to install Vagrant, a provider and Boxdeck, connect AI agents, and fix the problems people run into most.
Installing#
Boxdeck is a front end for HashiCorp Vagrant: it runs the vagrant you have installed. You need three things:
- Vagrant 2.3 or newer.
- A provider: the software that actually runs the VMs (VMware, VirtualBox, Parallels, libvirt, Hyper-V or Docker), plus any Vagrant plugin it needs.
- Boxdeck itself.
1. Install Vagrant#
| System | Command |
|---|---|
| macOS (Homebrew) | brew tap hashicorp/tap && brew install hashicorp/tap/hashicorp-vagrant |
| Windows (winget) | winget install Hashicorp.Vagrant |
| Ubuntu / Debian | Add HashiCorp's apt repository, then sudo apt install vagrant (see below) |
| Fedora / RHEL / others | Follow HashiCorp's install page |
On Ubuntu or Debian:
wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vagrant
Check it: vagrant --version should print 2.3 or newer.
2. Set up a provider#
Pick the one you use. Vagrant needs both the virtualization software and, for some providers, a plugin.
VMware (Fusion on macOS, Workstation on Windows/Linux)#
VMware needs three pieces:
- VMware Fusion (macOS) or VMware Workstation Pro (Windows, Linux), installed and opened once.
- The Vagrant plugin:
vagrant plugin install vagrant-vmware-desktop - The Vagrant VMware Utility, a small system service the plugin talks to. It's separate from the plugin and easy to miss.
- macOS:
brew install --cask vagrant-vmware-utility - Windows and Linux: download it from HashiCorp's VMware page and run the installer.
DriverAPICertificateErrorand Boxdeck shows that error on the project. - macOS:
Use it with config.vm.provider "vmware_desktop" in your Vagrantfile, or set VAGRANT_DEFAULT_PROVIDER=vmware_desktop in Boxdeck's Settings → Environment variables.
VirtualBox#
Install VirtualBox (on macOS: brew install --cask virtualbox). No plugin is needed. On Apple Silicon Macs, use VirtualBox 7.1 or newer and arm64 boxes.
Parallels (macOS)#
Install Parallels Desktop (Pro or Business edition), then:
vagrant plugin install vagrant-parallels
libvirt (Linux)#
Install libvirt and QEMU from your distribution, then the plugin. See the vagrant-libvirt install guide for the build dependencies, then:
vagrant plugin install vagrant-libvirt
Hyper-V (Windows)#
Turn on the Hyper-V Windows feature. Vagrant supports it without a plugin, but it must run as administrator, so start Boxdeck with "Run as administrator".
Docker#
Install Docker. Vagrant's Docker provider is built in.
Check the provider#
In an empty folder:
printf 'Vagrant.configure("2") { |c| c.vm.box = "bento/ubuntu-24.04" }\n' > Vagrantfile
VAGRANT_DEFAULT_PROVIDER=vmware_desktop vagrant status
Replace vmware_desktop with your provider (virtualbox, parallels, libvirt, hyperv, docker). It should say not created, not an error.
3. Install Boxdeck#
Download the latest release from GitHub Releases:
| System | File | First launch |
|---|---|---|
| macOS | .dmg (Apple Silicon or Intel) | Drag Boxdeck to Applications. Early builds aren't notarized, so macOS blocks the first launch: see unsigned app warnings. |
| Windows | .msi or -setup.exe | Early builds aren't signed. If SmartScreen warns, choose More info → Run anyway. |
| Linux | .deb, .rpm or .AppImage | Install the package, or chmod +x the AppImage and run it. On GNOME, install the AppIndicator extension for the tray icon. |
When Boxdeck starts, it finds vagrant on your PATH and lists every machine Vagrant knows about. If it can't find Vagrant, it shows these steps; after installing, click Look again.
To use Boxdeck from AI agents, see Boxdeck for AI agents.
Building from source#
See Development in the README. You'll also need Rust, Node.js 22+, the Tauri prerequisites and cargo install cargo-deny.
Boxdeck for AI agents (MCP)#
Boxdeck includes a Model Context Protocol server, so AI agents and coding assistants can list, start, stop and inspect your Vagrant machines, and, if you allow it, run commands and move files inside them. Agents use the same code paths as the app, and you decide what they may do.
Agent access is off until you turn it on in Settings → MCP / Agents.
Connecting a client#
Under Settings → MCP / Agents → Connect a client, click Connect next to your client:
| Client | Config file Boxdeck edits |
|---|---|
| Claude Code | ~/.claude.json |
| Claude Desktop | claude_desktop_config.json in ~/Library/Application Support/Claude (macOS), %APPDATA%\Claude (Windows) or ~/.config/Claude (Linux) |
| Cursor | ~/.cursor/mcp.json |
| Gemini CLI | ~/.gemini/settings.json |
| Codex | ~/.codex/config.toml (or $CODEX_HOME/config.toml) |
Connect adds one boxdeck entry that starts the boxdeck-mcp program bundled with the app. It keeps everything else in the file, including key order and comments, and Disconnect removes only that entry. Restart the client afterwards. If you move or update Boxdeck and the stored path goes stale, the row shows Reconnect.
There is no token and no network port. The client starts boxdeck-mcp itself over stdio, and boxdeck-mcp reads the same settings as the app. For any other client, copy the snippet from the same page:
{
"mcpServers": {
"boxdeck": { "command": "/Applications/Boxdeck.app/Contents/MacOS/boxdeck-mcp", "args": [] }
}
}
Access levels#
| Level | Tools |
|---|---|
| Read (default) | list_machines, get_machine_status, get_machine_details, list_boxes, check_box_updates, read_vagrantfile, validate_vagrantfile, get_job, list_jobs |
| Operate | Read, plus machine_up, machine_halt, machine_suspend, machine_resume, machine_reload, machine_provision, box_add, box_update, cancel_job (only jobs the agent started) |
| Full | Operate, plus machine_destroy, box_remove, box_prune, write_vagrantfile, each approved by you |
Every tool carries MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) so clients can show and gate them.
Long actions such as vagrant up run as jobs. Action tools wait up to wait_seconds (default 60, max 600) and then return the result, or a job id to poll with get_job. Clients that send a progress token get Vagrant's output as progress notifications.
Shell access inside VMs#
With Shell access in VMs turned on (it needs Operate), agents get three more tools:
ssh_execruns a shell command in a running VM throughvagrant ssh -c, optionally in acwd. It returns stdout, stderr and the exit code. A command still running afterwait_secondsbecomes a job to poll withget_job;timeout_seconds(default 600, max 3600) stops it. Each stream returns at most its last 200 KB, withtruncatedset when output was cut.vm_uploadcopies a file or folder from the project folder into the VM (vagrant upload).vm_downloadreturns a text file from the VM (up to 1 MB), or saves any file under the project folder withsave_to(up to 50 MB).
Agents get full control inside the VM. On the host they can only reach the project folder: upload sources and download destinations must stay inside it, symlinks included.
| Mode | What happens |
|---|---|
| Off | Shell tools are refused (default). |
| Ask once | A VM with a two-way synced folder can change files on your computer. The first shell call to such a VM asks you; Allow for this session trusts that VM until Boxdeck restarts. VMs with no synced folders, or only rsync ones, don't ask. |
| Always | No questions. |
Each project can override the mode under Settings → Projects. Machines you allowed for the session are listed under the setting, each with Revoke. Boxdeck reads which folders are synced from Vagrant's own record in .vagrant/machines/<name>/<provider>/synced_folders. When there's no record yet, it asks.
Approvals#
Boxdeck opens a small window naming the agent, the tool, the project, the machine and the exact arguments:
- for every destructive tool (Full level)
- for the first shell call to a VM that can change host files (Ask once)
Deny is the default button, and no answer within two minutes counts as a denial.
boxdeck-mcp sends these requests to the app through files in Boxdeck's data folder, which only your user account can read. If the app isn't running, nobody can answer, so those calls are refused with a message telling the agent to open Boxdeck. Two switches under When Boxdeck isn't running change that, both off by default:
- Allow shell access without asking: Ask once lets calls through instead.
- Allow destructive tools without approval: agents can then destroy machines with nobody asked.
Projects#
Every project follows the global setting (all projects, or only the ones you allow) unless you set it to Allow or Deny under Settings → Projects. Agents can't see denied projects at all.
Pausing and auditing#
- Pause Agent Access in the tray menu refuses every call at once in every running
boxdeck-mcp. - Every call, allowed or not, is appended to
audit.jsonlin Boxdeck's data folder with the time, client, tool, arguments, decision and result. Activity → Agent calls shows it.
Security notes#
- Boxdeck opens no network port for agents. Only programs running as you can start
boxdeck-mcpor write to the data folder, and those programs could already runvagrantdirectly. - There is no generic "run a vagrant command" tool. Inputs are checked against known projects, known machine names and allowlisted values before Vagrant runs.
ssh_exec's command is the only free-form input. get_machine_detailsreturns SSH host, port and user only. Private keys are never read.
Tool output is untrusted. VM logs, Vagrantfile contents and ssh_exec output can contain text written to steer an agent. Boxdeck can't control what an agent does with it, so it limits the damage instead: access levels, shell mode, approvals, per-project deny and the pause switch.
Troubleshooting#
"Boxdeck can't find Vagrant"#
Apps started from Finder, the Dock or the Start menu don't always get your shell's PATH. Boxdeck imports your login shell's PATH at startup; if Vagrant still isn't found, set its full path in Settings → Vagrant program, then click Look again.
A provider isn't found, or "No usable default provider"#
Provider tools (vmrun, VBoxManage, …) are looked up on the same PATH. Add their folder under Settings → Extra PATH folders. For VMware, Vagrant also needs the vagrant-vmware-desktop plugin and the Vagrant VMware Utility service; see VMware setup.
DriverAPICertificateError with VMware#
The Vagrant VMware Utility isn't installed (it's separate from the plugin). On macOS: brew install --cask vagrant-vmware-utility; elsewhere, use HashiCorp's installer.
"Port collision" although nothing uses the port#
If vagrant up reports a forwarded-port collision for every port it tries (the ports in the auto-correction range are all also used), something on your computer is answering every local connection. VPN, proxy and security software can do this. Vagrant then believes every port is taken. Pause that software, or remove forwarded_port lines and reach the VM by its own IP address. This is outside Boxdeck; plain vagrant up in a terminal fails the same way.
A job fails asking for a password (for example NFS on macOS)#
Boxdeck runs Vagrant without a terminal, so prompts fail instead of hanging. Open the job's log and click Run in terminal to repeat it in a terminal tab where you can type the password.
Hyper-V on Windows#
Hyper-V needs Vagrant to run as administrator. Start Boxdeck with "Run as administrator".
No tray icon on Linux#
GNOME needs the AppIndicator extension to show tray icons. Everything in the tray is also available in the main window.
Unsigned app warnings (macOS and Windows)#
Boxdeck releases aren't signed with a developer certificate or notarized yet, so macOS and Windows warn the first time you open them. Every release is built in public by the Release workflow; if you'd rather not bypass the warning, build it from source. You only need to do this once per install.
macOS: "Boxdeck is damaged and can't be opened"#
v0.1.0-beta.1 isn't signed at all, and macOS reports unsigned apps downloaded from the internet this way, mostly on Apple Silicon. The file isn't broken. After dragging Boxdeck to Applications, clear the download flag in Terminal:
xattr -dr com.apple.quarantine /Applications/Boxdeck.app
macOS: "Apple could not verify Boxdeck is free of malware"#
Later releases are ad-hoc signed, so macOS shows this instead.
- Open Boxdeck once and close the dialog with Done (not Move to Trash).
- Open System Settings → Privacy & Security, scroll to Security and click Open Anyway next to the Boxdeck message.
- Open Boxdeck again, choose Open Anyway and enter your password.
On macOS 14 and earlier, right-clicking the app and choosing Open, then Open again, also works.
Windows: "Windows protected your PC"#
SmartScreen warns about new unsigned apps. Choose More info → Run anyway.
Agents can't connect#
Check Settings → MCP / Agents: agent access must be on, and the client's row under Connect a client should say Connected. Restart the client after connecting. If the row says Points to an old copy of Boxdeck (you moved or reinstalled the app), click Reconnect. If an agent says a call needs approval, open the Boxdeck app: approvals only work while it's running.
Architecture#
Boxdeck is a Cargo workspace plus a React frontend.
React UI (src/) ──invoke / Channel──► Tauri app (src-tauri/) ──► boxdeck-core ──► vagrant CLI
tray, approval windows ▲
▲ │
approval requests (data folder) │
│ │
MCP clients ──stdio──► boxdeck-mcp ───────────────┴────────────────────┘
| Crate / folder | Role |
|---|---|
crates/boxdeck-core | Everything that knows about Vagrant: locating it, parsing --machine-readable output, reading the machine index (read-only, under a shared lock), the job runner (queues, per-machine locks, cancel), boxes, settings, the MCP access policy and the audit log. No Tauri dependency. |
crates/boxdeck-mcp | The MCP tools (via rmcp) on top of core, plus the boxdeck-mcp stdio binary. |
src-tauri | The desktop app: IPC commands, tray, approval windows and Connect for MCP clients. Thin glue over core. |
src | React + TypeScript UI. Types in src/ipc/generated/ are generated from Rust with ts-rs (npm run gen:types). |
tests/fake-vagrant | A scriptable stand-in for vagrant, used by integration tests. |
Key decisions#
- Vagrant is only ever run as a separate process, with an argument list (never a shell string), its project folder as working directory and stdin closed. Actions get
--no-tty;--machine-readablequeries must not, because--no-ttyoverrides machine-readable output. - Machine names come from Vagrant's machine index, not
global-status, whose machine-readable output has no names. - Live state comes from one
vagrant statusper project, with a concurrency limit and a cache, refreshed on demand, on focus, after jobs, when the index file changes, and optionally on an interval. - Cancel interrupts first (Vagrant cleans up), then kills the whole process tree.
- Settings are versioned JSON written atomically by the app;
boxdeck-mcpreads the same file and follows changes, so the pause switch works for both.