boxes-mcp
boxes-mcp
Un servidor local del Model Context Protocol (MCP) que permite a agentes compatibles y entornos de desarrollo gestionar máquinas virtuales de GNOME Boxes a través de libvirt/virsh. Proporciona operaciones de VM seguras y reversibles, instantáneas, capturas de pantalla, entrada de teclado y ratón acotada, y funciones SPICE controladas por capacidades.
El proyecto se dirige intencionalmente a la pila Linux libvirt/QEMU de GNOME Boxes. VMware y VirtualBox no están soportados actualmente; sus APIs de pantalla, entrada, agente invitado, portapapeles y arrastrar/soltar tienen contratos de confianza y capacidades diferentes y deberían añadirse como proveedores separados basados en evidencia, en lugar de inferirse de la implementación de libvirt.
Contenido
Related MCP server: kwin-mcp
Características
🖥️ Gestión del ciclo de vida de VM - Iniciar, detener, reiniciar, suspender y reanudar VMs
📸 Operaciones de instantáneas - Crear, listar, revertir y eliminar instantáneas de VM
🔍 Descubrimiento de VM - Listar e inspeccionar todas las VMs con información detallada
🔒 Operaciones seguras - Preservación de almacenamiento por defecto, sin acciones destructivas
🎯 Compatible con GNOME Boxes - Funciona perfectamente con VMs de GNOME Boxes
🖱️ Interacción controlada - Captura de pantalla, teclado en lista blanca y herramientas de ratón tipadas
🔌 SPICE controlado por capacidades - Protocolo auxiliar nativo opcional para entrada, portapapeles y transferencia SPICE
⚡ Rápido y ligero - Sobrecarga mínima, integración directa con virsh
Instalación
Requisitos del host
Ubuntu 22.04/24.04 (o distribución Linux compatible)
libvirt-daemon-system, qemu-kvm instalados
Node.js 18+ y npm
Usuario en los grupos
libvirtykvmvirshdisponible enPATHpara operaciones de ciclo de vida, captura de pantalla, teclado y respaldo QMP
Las herramientas respaldadas por SPICE requieren adicionalmente una pantalla SPICE, un canal de agente
virtio-serial invitado y un spice-vdagent en ejecución (o agente invitado equivalente). El soporte de
portapapeles también depende de la integración de escritorio invitado proporcionada por ese agente. El
componente de sesión estándar de spice-vdagent está orientado a X11; un invitado Wayland/Hyprland puede
tener el paquete y el servicio en ejecución mientras sigue informando capability-missing para el
portapapeles. Construya el auxiliar nativo opcional solo cuando el host proporcione los archivos de
desarrollo de spice-client-glib, json-glib y GLib. Para dominios libvirt cuyo XML de gráficos use
listen type='none', el auxiliar usa la API local de descriptores de archivos de gráficos de libvirt; no se
requiere remote-viewer, virt-viewer ni una URI SPICE pública:
npm run build:spice-helper
BOXES_SPICE_HELPER="$PWD/native/boxes-spice-helper" npm testEl auxiliar no se instala ni se selecciona automáticamente. Establezca BOXES_SPICE_HELPER solo
al ejecutable revisado construido desde este repositorio u otro proceso que implemente el
protocolo versionado a continuación.
# 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 libvirtInstalar desde npm
El paquete npm incluye un instalador guiado para hosts MCP locales. Instala solo el servidor Node;
libvirt, virsh, QEMU y las bibliotecas de desarrollo SPICE opcionales siguen siendo requisitos del host.
# Detect installed MCP hosts and configure them
npx -y boxes-mcp@0.1.0 setup
# Or install the command globally
npm install --global boxes-mcp@0.1.0
boxes-mcp setupVista previa de la configuración sin escribir archivos:
npx -y boxes-mcp@0.1.0 setup --dry-runConfigure un host explícitamente cuando no sea detectable en PATH:
npx -y boxes-mcp@0.1.0 setup --client codex
npx -y boxes-mcp@0.1.0 setup --client claude
npx -y boxes-mcp@0.1.0 setup --client openclawEl instalador detecta o puede configurar explícitamente Codex, Claude Code, OpenClaw,
Antigravity, Gemini CLI, OpenCode, Cursor, Windsurf, VS Code, Pi, Cline, Zed y
Goose. Use --client generic para imprimir una configuración JSON portátil para otro
agente compatible con stdio:
npx -y boxes-mcp@0.1.0 setup --client genericEl comando de configuración escribe solo la entrada MCP seleccionada, crea una copia de seguridad
.boxes-mcp.bak de una sola vez antes de cambiar una configuración existente, usa reemplazo atómico,
y nunca instala paquetes del sistema operativo ni cambia definiciones de VM. Reinicie el agente o
entorno configurado después de la configuración. Ejecute boxes-mcp doctor para inspeccionar Node,
virsh y los hosts detectados.
La configuración opcional del host se puede persistir durante la configuración:
npx -y boxes-mcp@0.1.0 setup \
--libvirt-uri qemu:///session \
--input-backend auto \
--spice-helper /absolute/path/to/native/boxes-spice-helper \
--transfer-root /absolute/path/to/approved/filesEl auxiliar SPICE nativo no se incluye como binario universal. Constrúyalo en un host Linux
compatible después de instalar los paquetes de desarrollo SPICE/libvirt del host, luego pase
su ruta absoluta revisada con --spice-helper o BOXES_SPICE_HELPER.
Instalar desde el código fuente
# Clone the repository for unreleased changes or development
git clone https://github.com/EF-Code/boxes-mcp.git
cd boxes-mcp
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
# Configure a local checkout with the same guided installer
npm run setup:guided -- --client codexConfiguración
Para una configuración manual, agregue el servidor a su configuración de Claude Code (~/.claude.json):
{
"mcpServers": {
"boxes": {
"command": "node",
"args": ["/absolute/path/to/boxes-mcp/dist/src/index.js"],
"env": {
"LIBVIRT_URI": "qemu:///system",
"BOXES_INPUT_BACKEND": "auto"
}
}
}
}Herramientas disponibles
Gestión de VM
Herramienta | Descripción | Parámetros |
| Listar todas las VMs | - |
| Obtener detalles de la VM |
|
| Iniciar una VM |
|
| Apagar VM (con gracia) |
|
| Reiniciar una VM |
|
| Suspender una VM |
|
| Reanudar VM suspendida |
|
| Eliminar VM (conserva almacenamiento) |
|
| Obtener dirección SPICE/VNC |
|
Gestión de instantáneas
Herramienta | Descripción | Parámetros |
| Listar instantáneas de VM |
|
| Crear instantánea |
|
| Revertir a instantánea |
|
| Eliminar instantánea |
|
Pantalla e interacción
Herramienta | Descripción | Parámetros | |
| Capturar la pantalla de un dominio en ejecución como contenido de imagen MCP | `nameOrUuid, screen?: number, backend?: auto | libvirt` |
| Enviar una secuencia de teclas Linux acotada y en lista blanca a través de virsh |
| |
| Enviar entrada tipada de movimiento/botón/clic/desplazamiento |
| |
| Lectura/escritura explícita de portapapeles UTF-8 a través del auxiliar SPICE |
| |
| Transferencia confinada experimental más secuencia de puntero y evidencia separada |
|
Las herramientas de interacción nunca aceptan fragmentos de shell, JSON QMP sin procesar, banderas arbitrarias de virsh, comandos invitados o destinos de transferencia arbitrarios. Las nuevas operaciones requieren un dominio en ejecución y devuelven un código de capacidad/error estable cuando su backend no está disponible.
Variables de entorno opcionales
Variable | Valor por defecto | Propósito |
|
| Conexión libvirt utilizada por cada operación de dominio |
|
| Preferencia de backend de ratón por defecto: |
| sin establecer | Ejecutable explícito que implementa el protocolo auxiliar SPICE versionado |
|
| Duración máxima de una solicitud auxiliar |
| directorio temporal del proceso | Directorio padre controlado para capturas de pantalla temporales |
|
| Límite de carga útil de captura de pantalla |
| sin establecer | Raíz canónica del host requerida para archivos fuente de arrastrar/soltar |
|
| Límite de tamaño de fuente de transferencia |
|
| Límite de carga útil de portapapeles UTF-8 |
BOXES_TRANSFER_ROOT se requiere deliberadamente en lugar de inferirse. Las rutas se
canonicalizan y se rechazan escapes de enlaces simbólicos, directorios y archivos especiales.
boxes.capabilities informa los estados observados. La configuración por sí sola no se trata como
conectada: use probeQmp: true y/o probeSpice: true cuando se requiera una sonda de estado externa.
El portapapeles y la transferencia SPICE requieren un agente invitado conectado;
boxes.drag_drop informa applicationAccepted: "unknown" a menos que un entorno de visor externo
proporcione evidencia a nivel de aplicación.
La entrada de teclado usa un conjunto de códigos virsh Linux fijo. Los nombres de teclas públicos son
insensibles a mayúsculas y se canonicalizan a mayúsculas, pero cada tecla puede aparecer solo una vez
por acorde acotado. La lista blanca es: ALT, BACKSPACE, CAPSLOCK, CTRL,
DELETE, DIGIT_0 a DIGIT_9, DOWN, END, ENTER, ESC, ESCAPE,
F1 a F12, HOME, INSERT, LEFT, META, NUMLOCK, PAGEDOWN,
PAGEUP, PAUSE, PRINT, RIGHT, SHIFT, SPACE, SUPER, TAB, UP,
y A a Z. La distribución del teclado invitado determina el carácter resultante;
la lista blanca de teclas no garantiza texto independiente de esa distribución.
Ejemplos de uso
Con 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]Uso directo
# Run the MCP server
LIBVIRT_URI=qemu:///system node dist/src/index.jsDesarrollo
Estructura del proyecto
boxes-mcp/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── tools.ts # Side-effect-free tool registry and handler boundary
│ ├── libvirt.ts # virsh operations & parsers
│ ├── virsh.ts # Shared executable and libvirt URI arguments
│ ├── exec.ts # Safe command execution
│ ├── screenshot.ts # Controlled libvirt screenshot capture
│ ├── keyboard.ts # Allowlisted virsh send-key adapter
│ ├── mouse.ts/qmp.ts # Typed mouse actions and QMP fallback
│ ├── spice.ts # Versioned companion-helper protocol client
│ ├── clipboard.ts # Explicit SPICE clipboard orchestration
│ ├── transfer.ts # Confined host-file validation
│ ├── drag-drop.ts # Experimental transfer/input coordination
│ ├── *.test.ts # Unit tests
├── systemd/
│ └── boxes-mcp.service # Systemd user service
├── dist/ # Compiled JavaScript
├── coverage/ # Test coverage reports
├── package.json
├── tsconfig.json
└── vitest.config.tsPruebas
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverageCobertura de pruebas local: el checkout actual ejecuta 95 pruebas que pasan y 9 pruebas en vivo restringidas que se omiten por defecto. El conjunto predeterminado es seguro de ejecutar sin acceso a libvirt.
exec.ts: 100% de declaracioneslibvirt.ts: 81.3% de declaraciones, 92.85% de ramasPruebas de validación de interacción, construcción de comandos, mapeo de respuestas QMP, limpieza de artefactos, enmarcado auxiliar, descubrimiento de capacidades y confinamiento de rutas
Ejecute las comprobaciones explícitas del proceso auxiliar nativo local con:
npm run test:spice-helperEjecute el conjunto de VM desechable solo con las tres variables de seguridad establecidas:
BOXES_INTEGRATION=1 \
BOXES_TEST_VM=an-explicit-disposable-domain \
BOXES_TEST_VM_DISPOSABLE=1 \
npm run test:integrationEl conjunto en vivo nunca selecciona una VM listada, cambia definiciones de VM ni detiene un servicio
invitado por sí mismo. La cobertura de desconexión del agente invitado requiere que el operador desconecte
manualmente spice-vdagent en el invitado explícitamente desechable y agregue
BOXES_TEST_AGENT_DISCONNECTED=1; nunca haga esto a un invitado no desechable.
Suite predeterminada
La suite predeterminada está simulada/local: no demuestra que QMP, SPICE, portapapeles, o arrastrar y soltar funcionen contra una VM real. Las pruebas en vivo deben ser opcionales y apuntar a una VM desechable específica con instantáneas; ninguna primera entrada de dominio arbitraria es seleccionada por las herramientas de interacción.
Compilación
# Build TypeScript
npm run build
# Watch mode for development
npm run devServicio systemd opcional
El servicio incluido está destinado a una fuente. No es necesario cuando el servidor se inicia mediante la configuración MCP de un agente o se instala globalmente con npm. Instálalo como un servicio de usuario para el inicio automático después de compilar el checkout:
BOXES_MCP_DIR="$(pwd)"
NODE_BIN="$(command -v node)"
mkdir -p ~/.config/systemd/user
cp systemd/boxes-mcp.service ~/.config/systemd/user/
sed -i \
-e "s|/usr/bin/node|$NODE_BIN|g" \
-e "s|%h/projects/boxes-mcp|$BOXES_MCP_DIR|g" \
~/.config/systemd/user/boxes-mcp.service
systemctl --user daemon-reload
systemctl --user enable --now boxes-mcp
journalctl --user -fu boxes-mcpConsideraciones de seguridad
✅ Ejecución en sandbox: Usa
execFilede Node.js con límites de tiempo de espera y buffer✅ Sin comandos arbitrarios: Solo se permiten operaciones virsh predefinidas
✅ Límite de entrada tipado: Los comandos QMP y las operaciones SPICE son enumeraciones internas con argumentos validados
✅ Cargas útiles limitadas: Conteos de teclas, duraciones, coordenadas, deltas de desplazamiento, capturas de pantalla, portapapeles y transferencias están limitados
✅ Restricción de rutas: Las fuentes de arrastrar y soltar deben permanecer bajo
BOXES_TRANSFER_ROOTdespués de la canonicalización✅ Preservación del almacenamiento: El almacenamiento de la VM no se elimina por defecto
✅ Aislamiento de URI: Respeta la conexión libvirt especificada por el entorno
⚠️ Permisos requeridos: El usuario debe pertenecer al grupo libvirt
⚠️ Exposición de red: No está diseñado para acceso remoto sin seguridad adicional
⚠️ Superficie de control ampliada: Las capturas de pantalla y los datos del portapapeles del invitado no son confiables; mantén el servidor MCP en stdio local
⚠️ Confianza en el helper SPICE: El ejecutable del helper es una dependencia explícita del anfitrión y no debe registrar credenciales, contenidos del portapapeles o archivos
Protocolo del helper SPICE
El servidor TypeScript inicia un único proceso hijo persistente y envía solicitudes JSON de la versión 1 delimitadas por nueva línea a través de stdin, correlacionando las respuestas por ID de solicitud. El helper se invoca con una ruta de ejecutable explícita y sin argumentos controlables por el llamador. El formato de la solicitud es:
{
"version": 1,
"id": "request-123",
"operation": "clipboard.read",
"domain": "guest-name",
"display": { "uri": "spice://127.0.0.1:5900" },
"arguments": { "selection": "clipboard", "maxBytes": 1048576 }
}Los nombres de operación admitidos son internos (status, mouse, clipboard.read,
clipboard.write, file.transfer y drag-drop). Un error del helper se asigna a un
error MCP estable como SPICE_AGENT_DISCONNECTED, SPICE_CAPABILITY_MISSING o
SPICE_UNAVAILABLE. Las cargas útiles, líneas, solicitudes pendientes, tamaños de transferencia, bytes del portapapeles
y el tiempo de operación están limitados. Los eventos de progreso nunca completan una solicitud.
El helper no registra contenidos del portapapeles, contenidos de archivos, tickets SPICE o
credenciales.
Matriz de capacidades
Capacidad | Libvirt/virsh | Respaldo QMP | Helper SPICE |
Captura de pantalla | Implementada mediante | No se usa | Adaptador reservado, no disponible sin helper |
Teclado | Implementado mediante | No se usa | No se usa |
Ratón | No se usa |
| Seleccionado por |
Portapapeles | No disponible | No disponible | Protocolo real del agente en el helper nativo; los invitados Wayland/Hyprland pueden informar |
Transferencia de archivos | No disponible | No disponible | Ruta real de copia de archivos SPICE asíncrona en el helper nativo; se observa la finalización en vivo cuando el agente invitado lo anuncia |
Arrastrar y soltar | No disponible | No disponible | Experimental: transferencia + evidencia del puntero; se desconoce la aceptación de la aplicación |
Solución de problemas
No se ven VMs
# Check libvirt URI
virsh -c qemu:///system list --all
virsh -c qemu:///session list --all
# Verify permissions
groups # Should include 'libvirt' and 'kvm'Permiso denegado
# Re-add to groups and re-login
sudo usermod -aG libvirt,kvm "$USER"
# Then logout/login or:
newgrp libvirtLas VMs no aparecen en la caja
Abre virt-manager y verifica qué conexión usan tus VMs:
Conexión del sistema:
qemu:///systemSesión de usuario:
qemu:///session
Establece la variable de entorno LIBVIRT_URI en consecuencia.
Errores de capacidad de SPICE
Si virsh domdisplay informa No graphical display found y el XML del dominio tiene
<graphics type='spice'><listen type='none'/></graphics>, esa es una configuración intencional de
libvirt sin listener público. No inventes un puerto ni modifiques la definición de la VM
solo para obtener una URI de visor. Con el helper nativo configurado, boxes-mcp
usa el transporte interno spice+libvirt-fd://local y solicita a libvirt un descriptor de archivo (FD)
para cada canal SPICE. El helper debe usar la misma conexión libvirt que el proceso MCP:
LIBVIRT_URI=qemu:///session npm run build:spice-helper
BOXES_SPICE_HELPER="$PWD/native/boxes-spice-helper" \
LIBVIRT_URI=qemu:///session node dist/src/index.jsEl dominio debe estar en ejecución, el helper debe estar vinculado contra libvirt y
spice-client-glib, y el invitado debe exponer el canal del agente virtio SPICE. Un
agente conectado puede carecer de capacidad de portapapeles; inspecciona boxes.capabilities con
probeSpice: true en lugar de inferir la compatibilidad solo desde el XML.
Usa boxes.capabilities con probeSpice: true e inspecciona el estado devuelto:
configured: se configuró un helper y un endpoint SPICE revisados, pero la prueba de conexión no se ha solicitado;connecting: el helper observó un conjunto de canales incompleto;connected: los canales requeridos están conectados;agent-disconnected: el agente invitado no está conectado;capability-missing: falta la capacidad del backend, canal, helper o invitado.
Por ejemplo, un agente invitado conectado que admite transferencia de archivos pero no anuncia
portapapeles es capability-missing, no agent-disconnected. Para habilitar el portapapeles, el
invitado debe tener el servicio spice-vdagent de su distribución instalado, ejecutándose en la
sesión de escritorio y conectado a través del canal del agente virtio SPICE. En un
escritorio Wayland/Hyprland, verifica que el agente de esa distribución realmente admita ese
compositor; un servicio activo por sí solo no es prueba suficiente. El invitado Omarchy en vivo tenía
spice-vdagent 0.23.0-1 y un servicio de usuario activo, pero registró xrandr output ID NOT FOUND y ningún propietario para org.gnome.Mutter.DisplayConfig, por lo que boxes-mcp correctamente
devolvió SPICE_CAPABILITY_MISSING. Usa una sesión de invitado X11 para el
agente oficial, o proporciona un puente de portapapeles para Wayland validado por separado. El
servidor no instala paquetes en el invitado ni inicia servicios automáticamente.
El cliente SPICE persistente también acepta una señal de aborto. La cancelación termina el
proceso del helper actual, falla todas las operaciones pendientes de manera determinista y permite que la
siguiente solicitud cree una sesión limpia; esto se informa como OPERATION_CANCELLED.
Verifica las dependencias del anfitrión y el helper directamente sin enviar entrada a una VM:
pkg-config --modversion spice-client-glib-2.0 json-glib-1.0 gio-unix-2.0
npm run build:spice-helperLa prueba de protocolo local del helper se conecta intencionalmente a 127.0.0.1:1 y
espera un resultado de no disponible/desconectado tipado. Esa no es una prueba de SPICE en vivo.
Hoja de ruta
Creación de VMs mediante integración con
virt-installGestión de red (
virsh net-list, reenvío de puertos)Información de pools de almacenamiento (
virsh vol-list)Importación de VMs desde OVA/QCOW2
Soporte de conexión remota a libvirt
Métricas de rendimiento y monitoreo
Contribuciones
¡Las contribuciones son bienvenidas! Lee CONTRIBUTING.md para conocer las pautas.
Haz un fork del repositorio
Crea una rama de funcionalidad (
git checkout -b feature/caracteristica-increible)Ejecuta las pruebas (
npm test)Haz commit de los cambios (
git commit -m 'Añadir característica increíble')Sube la rama (
git push origin feature/caracteristica-increible)Abre una Solicitud de extracción (Pull Request)
Licencia
Este proyecto está licenciado bajo la Licencia MIT; consulta el archivo LICENSE para más detalles.
Agradecimientos
Construido para Claude Code
Utiliza el SDK del Protocolo de Contexto de Modelos
Se integra con la API de virtualización libvirt
Soporte
Problemas: Problemas de GitHub
Discusiones: Discusiones de GitHub
Documentación: Wiki del proyecto
Hecho con ❤️ para la comunidad de Claude Code
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables 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.913MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to automate Linux desktop GUI by launching and interacting with Wayland applications in isolated virtual KWin sessions, or connecting to live desktops for collaborative automation.39MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI models to securely query and manage virtual machines and virtualized resources via the libvirt API through the Model Context Protocol.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables management of KVM/QEMU virtual machines on remote libvirt hosts via SSH, with tools for inspection, lifecycle management, snapshots, and cloning.1AGPL 3.0
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Control Unreal Engine to browse assets, import content, and manage levels and sequences. Automate…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/EF-Code/boxes-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server