Skip to main content
Glama
boxes-mcp
by btafoya

boxes-mcp

Tests TypeScript License: MIT

A lightweight Model Context Protocol (MCP) server that enables Claude Code to manage GNOME Boxes virtual machines through libvirt/virsh. Provides safe, reversible VM operations with comprehensive snapshot management.

Features

  • 🖥️ VM Lifecycle Management - Start, stop, reboot, suspend, and resume VMs

  • 📸 Snapshot Operations - Create, list, revert, and delete VM snapshots

  • 🔍 VM Discovery - List and inspect all VMs with detailed information

  • 🔒 Safe Operations - Storage preservation by default, no destructive actions

  • 🎯 GNOME Boxes Compatible - Works seamlessly with GNOME Boxes VMs

  • ⚡ Fast & Lightweight - Minimal overhead, direct virsh integration

Related MCP server: libvirt-mcp-server

Quick Start

Prerequisites

  • Ubuntu 22.04/24.04 (or compatible Linux distribution)

  • libvirt-daemon-system, qemu-kvm installed

  • Node.js 18+ and npm

  • User in libvirt and kvm groups

# Install dependencies
sudo apt install -y libvirt-daemon-system qemu-kvm virt-manager

# Add your user to required groups
sudo usermod -aG libvirt,kvm "$USER"
newgrp libvirt

Installation

# Clone the repository
git clone https://github.com/your-org/boxes-mcp.git
cd boxes-mcp

# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

Configuration

Add to your Claude Code config (~/.claude/config.json):

{
  "mcpServers": {
    "boxes": {
      "command": "node",
      "args": ["/absolute/path/to/boxes-mcp/dist/src/index.js"],
      "env": {
        "LIBVIRT_URI": "qemu:///system"
      }
    }
  }
}

Available Tools

VM Management

Tool

Description

Parameters

boxes.list

List all VMs

-

boxes.info

Get VM details

nameOrUuid: string

boxes.start

Start a VM

nameOrUuid: string

boxes.shutdown

Shutdown VM (graceful)

nameOrUuid: string, force?: boolean

boxes.reboot

Reboot a VM

nameOrUuid: string

boxes.suspend

Suspend a VM

nameOrUuid: string

boxes.resume

Resume suspended VM

nameOrUuid: string

boxes.undefine

Remove VM (keeps storage)

nameOrUuid: string, keepStorage?: boolean

boxes.display

Get SPICE/VNC address

nameOrUuid: string

Snapshot Management

Tool

Description

Parameters

boxes.snapshots.list

List VM snapshots

nameOrUuid: string

boxes.snapshots.create

Create snapshot

nameOrUuid: string, snapshot: string, description?: string

boxes.snapshots.revert

Revert to snapshot

nameOrUuid: string, snapshot: string

boxes.snapshots.delete

Delete snapshot

nameOrUuid: string, snapshot: string

Usage Examples

With Claude Code

User: "List all my VMs"
Claude: [Uses boxes.list tool]

User: "Start ubuntu-24.04"
Claude: [Uses boxes.start with nameOrUuid="ubuntu-24.04"]

User: "Create a snapshot called 'before-update' for my fedora VM"
Claude: [Uses boxes.snapshots.create]

Direct Usage

# Run the MCP server
LIBVIRT_URI=qemu:///system node dist/src/index.js

Development

Project Structure

boxes-mcp/
├── src/
│   ├── index.ts          # MCP server entry point
│   ├── libvirt.ts        # virsh operations & parsers
│   ├── exec.ts           # Safe command execution
│   ├── *.test.ts         # Unit tests
├── systemd/
│   └── boxes-mcp.service # Systemd user service
├── dist/                 # Compiled JavaScript
├── coverage/             # Test coverage reports
├── package.json
├── tsconfig.json
└── vitest.config.ts

Testing

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Generate coverage report
npm run test:coverage

Test Coverage: 33 tests, 100% passing

  • exec.ts: 100% statements

  • libvirt.ts: 81.3% statements, 92.85% branches

  • Comprehensive unit and integration tests

Building

# Build TypeScript
npm run build

# Watch mode for development
npm run dev

Systemd Service

Install as a user service for automatic startup:

mkdir -p ~/.config/systemd/user
cp systemd/boxes-mcp.service ~/.config/systemd/user/
sed -i "s|%h/projects/virtmcp|$HOME/boxes-mcp|g" ~/.config/systemd/user/boxes-mcp.service
systemctl --user daemon-reload
systemctl --user enable --now boxes-mcp
journalctl --user -fu boxes-mcp

Security Considerations

  • ✅ Sandboxed Execution: Uses Node.js execFile with timeout and buffer limits

  • ✅ No Arbitrary Commands: Only predefined virsh operations allowed

  • ✅ Storage Preservation: VM storage not deleted by default

  • ✅ LIBVIRT_URI Isolation: Respects environment-specified libvirt connection

  • ⚠️ Permissions Required: User must have libvirt group membership

  • ⚠️ Network Exposure: Not designed for remote access without additional security

Troubleshooting

No VMs Listed

# Check libvirt URI
virsh -c qemu:///system list --all
virsh -c qemu:///session list --all

# Verify permissions
groups  # Should include 'libvirt' and 'kvm'

Permission Denied

# Re-add to groups and re-login
sudo usermod -aG libvirt,kvm "$USER"
# Then logout/login or:
newgrp libvirt

VMs Not Showing in Boxes

Open virt-manager and check which connection your VMs use:

  • System connection: qemu:///system

  • User session: qemu:///session

Set LIBVIRT_URI environment variable accordingly.

Roadmap

  • VM creation via virt-install integration

  • Network management (virsh net-list, port forwarding)

  • Storage pool information (virsh vol-list)

  • VM import from OVA/QCOW2

  • Remote libvirt connection support

  • Performance metrics and monitoring

Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/amazing-feature)

  3. Run tests (npm test)

  4. Commit changes (git commit -m 'Add amazing feature')

  5. Push to branch (git push origin feature/amazing-feature)

  6. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Support


Made with ❤️ for the Claude Code community

Available Tools

13 tools
boxes.displayA

Get SPICE/VNC display address for VM (useful to open viewer)

Inputs: nameOrUuid (required).

boxes.infoB

Get detailed domain info

Inputs: nameOrUuid (required).

boxes.listA

List all libvirt domains (VMs) managed by GNOME Boxes/libvirt

Inputs: no named parameters.

boxes.rebootB

Reboot a running domain

Inputs: nameOrUuid (required).

boxes.resumeC

Resume a suspended domain

Inputs: nameOrUuid (required).

boxes.shutdownA

Shutdown/Power off a domain (graceful by default)

Inputs: nameOrUuid (required), force.

boxes.snapshots.createB

Create a snapshot for a domain

Inputs: snapshot (required), nameOrUuid (required), description.

boxes.snapshots.deleteB

Delete a snapshot

Inputs: snapshot (required), nameOrUuid (required).

boxes.snapshots.listA

List snapshots for a domain

Inputs: nameOrUuid (required).

boxes.snapshots.revertB

Revert a domain to a snapshot

Inputs: snapshot (required), nameOrUuid (required).

boxes.startC

Start a domain (VM)

Inputs: nameOrUuid (required).

boxes.suspendC

Suspend a running domain

Inputs: nameOrUuid (required).

boxes.undefineA

Undefine a domain (remove from libvirt). Storage is NOT deleted.

Inputs: nameOrUuid (required), keepStorage.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 13 tools

    Disambiguation5/5

    Each tool targets a distinct action (e.g., start, shutdown, snapshot operations) with no overlap. Snapshots are namespaced under 'snapshots' to further differentiate from domain-level actions.

    Naming Consistency5/5

    All tools follow a consistent 'boxes.<action>' pattern, with snapshot sub-tools using 'boxes.snapshots.<action>'. Names are lowercase with dots and use verbs for actions (list, create, delete).

    Tool Count5/5

    13 tools is well-scoped for managing libvirt domains, covering lifecycle, snapshots, and info display. The number feels complete without being excessive.

    Completeness4/5

    Core VM lifecycle (start, shutdown, reboot, suspend, resume, undefine) and snapshot CRUD are covered. Missing domain modification (e.g., edit config) is a minor gap, but the set handles essential operations.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      B
      maintenance
      Enables AI assistants to manage virtual machines, sandboxes, and dev environments through VirtualBox, Hyper-V, and Windows Sandbox, supporting VM lifecycle, ISO downloads, networking, and unattended installs.
      9
      19
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI models to securely query and manage virtual machines and virtualized resources via the libvirt API through the Model Context Protocol.
      1
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables management of KVM/QEMU virtual machines on remote libvirt hosts via SSH, with tools for inspection, lifecycle management, snapshots, and cloning.
      2
      AGPL 3.0
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables management of oVirt / Red Hat Virtualization environments via AI assistants, supporting VM lifecycle, power operations, snapshots, and infrastructure queries.
      -