boxes-mcp

btafoya/boxes-mcp

3.2

If you are the rightful owner of boxes-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

A lightweight Model Context Protocol (MCP) server designed to manage GNOME Boxes virtual machines through libvirt/virsh, providing safe and reversible VM operations with comprehensive snapshot management.

Tools
13
Resources
0
Prompts
0

boxes-mcp

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

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

ToolDescriptionParameters
boxes.listList all VMs-
boxes.infoGet VM detailsnameOrUuid: string
boxes.startStart a VMnameOrUuid: string
boxes.shutdownShutdown VM (graceful)nameOrUuid: string, force?: boolean
boxes.rebootReboot a VMnameOrUuid: string
boxes.suspendSuspend a VMnameOrUuid: string
boxes.resumeResume suspended VMnameOrUuid: string
boxes.undefineRemove VM (keeps storage)nameOrUuid: string, keepStorage?: boolean
boxes.displayGet SPICE/VNC addressnameOrUuid: string

Snapshot Management

ToolDescriptionParameters
boxes.snapshots.listList VM snapshotsnameOrUuid: string
boxes.snapshots.createCreate snapshotnameOrUuid: string, snapshot: string, description?: string
boxes.snapshots.revertRevert to snapshotnameOrUuid: string, snapshot: string
boxes.snapshots.deleteDelete snapshotnameOrUuid: 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 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 file for details.

Acknowledgments

Support


Made with ā¤ļø for the Claude Code community