boxes-mcp
boxes-mcp
Локальный сервер Model Context Protocol (MCP), который позволяет совместимым агентам и разработческим средам управлять виртуальными машинами GNOME Boxes через libvirt/virsh. Он предоставляет безопасные, обратимые операции с ВМ, снимки, скриншоты, ограниченный ввод с клавиатуры и мыши, а также функции SPICE, управляемые через проверку возможностей.
Проект намеренно ориентирован на стек Linux libvirt/QEMU от GNOME Boxes. VMware и VirtualBox в настоящее время не поддерживаются; их API для отображения, ввода, гостевого агента, буфера обмена и перетаскивания имеют другие контракты доверия и возможностей и должны быть добавлены как отдельные провайдеры с подтверждённой поддержкой, а не выводиться из реализации libvirt.
Содержание
Related MCP server: kwin-mcp
Возможности
🖥️ Управление жизненным циклом ВМ — запуск, остановка, перезагрузка, приостановка и возобновление ВМ
📸 Операции со снимками — создание, список, откат и удаление снимков ВМ
🔍 Обнаружение ВМ — список и просмотр всех ВМ с подробной информацией
🔒 Безопасные операции — сохранение хранилища по умолчанию, отсутствие разрушительных действий
🎯 Совместимость с GNOME Boxes — бесшовная работа с ВМ GNOME Boxes
🖱️ Контролируемое взаимодействие — скриншоты, клавиатура из белого списка и типизированные инструменты мыши
🔌 SPICE с проверкой возможностей — опциональный нативный вспомогательный протокол для ввода, буфера обмена и передачи SPICE
⚡ Быстрый и лёгкий — минимальные накладные расходы, прямая интеграция с virsh
Установка
Требования к хосту
Ubuntu 22.04/24.04 (или совместимый дистрибутив Linux)
Установлены libvirt-daemon-system, qemu-kvm
Node.js 18+ и npm
Пользователь в группах
libvirtиkvmvirshдоступен вPATHдля операций жизненного цикла, скриншотов, клавиатуры и запасного QMP
Инструменты на основе SPICE дополнительно требуют SPICE-дисплей, гостевой канал агента
virtio-serial и запущенный spice-vdagent (или эквивалентный гостевой агент). Поддержка
буфера обмена также зависит от интеграции гостевого рабочего стола, предоставляемой этим
агентом. Стандартный компонент сеанса spice-vdagent ориентирован на X11; гостевая система
Wayland/Hyprland может иметь установленный пакет и запущенную службу, но при этом сообщать
capability-missing для буфера обмена. Собирайте опциональный
нативный вспомогательный модуль только тогда, когда хост предоставляет файлы разработки
spice-client-glib, json-glib и GLib. Для доменов libvirt, чей XML графики использует
listen type='none', вспомогательный модуль использует локальный API графических файловых
дескрипторов libvirt; remote-viewer, virt-viewer или публичный SPICE URI не требуются:
npm run build:spice-helper
BOXES_SPICE_HELPER="$PWD/native/boxes-spice-helper" npm testВспомогательный модуль не устанавливается и не выбирается автоматически. Устанавливайте
BOXES_SPICE_HELPER только на проверенный исполняемый файл, собранный из этого репозитория,
или на другой процесс, реализующий версионированный протокол ниже.
# 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Установка из npm
Пакет npm включает интерактивный установщик для локальных MCP-хостов. Он устанавливает только
Node-сервер; libvirt, virsh, QEMU и опциональные библиотеки разработки SPICE остаются
требованиями к хосту.
# 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 setupПредварительный просмотр конфигурации без записи файлов:
npx -y boxes-mcp@0.1.0 setup --dry-runЯвная настройка одного хоста, если он не обнаруживается в 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 openclawУстановщик обнаруживает или может явно настроить Codex, Claude Code, OpenClaw,
Antigravity, Gemini CLI, OpenCode, Cursor, Windsurf, VS Code, Pi, Cline, Zed и
Goose. Используйте --client generic для вывода переносимой JSON-конфигурации для другого
агента, поддерживающего stdio:
npx -y boxes-mcp@0.1.0 setup --client genericКоманда настройки записывает только выбранную запись MCP, создаёт одноразовую резервную
копию .boxes-mcp.bak перед изменением существующего конфига, использует атомарную замену
и никогда не устанавливает системные пакеты и не изменяет определения ВМ. Перезапустите
настроенного агента или среду после настройки. Запустите boxes-mcp doctor для проверки
Node, virsh и обнаруженных хостов.
Дополнительные настройки хоста можно сохранить во время установки:
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/filesНативный SPICE-помощник не поставляется как универсальный бинарный файл. Соберите его на
совместимом Linux-хосте после установки пакетов разработки SPICE/libvirt, затем передайте
его проверенный абсолютный путь с помощью --spice-helper или BOXES_SPICE_HELPER.
Установка из исходников
# 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 codexКонфигурация
Для ручной настройки добавьте сервер в ваш конфиг 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"
}
}
}
}Доступные инструменты
Управление ВМ
Инструмент | Описание | Параметры |
| Список всех ВМ | - |
| Получить сведения о ВМ |
|
| Запустить ВМ |
|
| Завершить работу ВМ (мягко) |
|
| Перезагрузить ВМ |
|
| Приостановить ВМ |
|
| Возобновить приостановленную ВМ |
|
| Удалить ВМ (сохраняя хранилище) |
|
| Получить адрес SPICE/VNC |
|
Управление снимками
Инструмент | Описание | Параметры |
| Список снимков ВМ |
|
| Создать снимок |
|
| Откатить к снимку |
|
| Удалить снимок |
|
Отображение и взаимодействие
Инструмент | Описание | Параметры | |
| Захват отображения работающего домена как MCP-изображение | `nameOrUuid, screen?: number, backend?: auto | libvirt` |
| Отправка ограниченной последовательности клавиш из белого списка через virsh |
| |
| Отправка типизированного ввода перемещения/кнопки/клика/прокрутки |
| |
| Явное чтение/запись UTF-8 буфера обмена через SPICE-помощник |
| |
| Экспериментальная ограниченная передача плюс последовательность указателя и отдельные доказательства |
|
Инструменты взаимодействия никогда не принимают фрагменты shell, сырой JSON QMP, произвольные флаги virsh, гостевые команды или произвольные места назначения передачи. Новые операции требуют работающего домена и возвращают стабильный код возможности/ошибки, когда их бэкенд недоступен.
Дополнительные переменные окружения
Переменная | По умолчанию | Назначение |
|
| Подключение libvirt, используемое для каждой операции с доменом |
|
| Предпочтение бэкенда мыши по умолчанию: |
| не задано | Явный исполняемый файл, реализующий версионированный протокол SPICE-помощника |
|
| Максимальная длительность одного запроса к помощнику |
| временная папка процесса | Контролируемая родительская папка для временных скриншотов |
|
| Лимит полезной нагрузки скриншота |
| не задано | Требуемый канонический корень хоста для исходных файлов перетаскивания |
|
| Лимит размера исходного файла передачи |
|
| Лимит полезной нагрузки UTF-8 буфера обмена |
BOXES_TRANSFER_ROOT намеренно обязателен, а не выводится. Пути канонизируются,
а обходы символических ссылок, каталоги и специальные файлы отклоняются.
boxes.capabilities сообщает наблюдаемые состояния. Одна лишь конфигурация не считается
подключением: используйте probeQmp: true и/или probeSpice: true, когда требуется
внешний зонд статуса. Буфер обмена и передача SPICE требуют подключённого гостевого агента;
boxes.drag_drop сообщает applicationAccepted: "unknown", если внешняя среда просмотра
не предоставляет доказательства на уровне приложения.
Ввод с клавиатуры использует один фиксированный набор кодов Linux virsh. Публичные имена
клавиш нечувствительны к регистру и канонизируются в верхний регистр, но каждая клавиша
может встречаться только один раз в ограниченном аккорде. Белый список: ALT, BACKSPACE,
CAPSLOCK, CTRL, DELETE, DIGIT_0 – DIGIT_9, DOWN, END, ENTER, ESC,
ESCAPE, F1 – F12, HOME, INSERT, LEFT, META, NUMLOCK, PAGEDOWN,
PAGEUP, PAUSE, PRINT, RIGHT, SHIFT, SPACE, SUPER, TAB, UP
и A – Z. Раскладка клавиатуры гостя определяет результирующий символ;
белый список клавиш не гарантирует текст независимо от этой раскладки.
Примеры использования
С 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]Прямое использование
# Run the MCP server
LIBVIRT_URI=qemu:///system node dist/src/index.jsРазработка
Структура проекта
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.tsТестирование
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverageПокрытие локальных тестов: текущая версия запускает 95 проходящих тестов и 9 ограниченных живых тестов, пропускаемых по умолчанию. Стандартный набор безопасно запускать без доступа к libvirt.
exec.ts: 100% операторовlibvirt.ts: 81.3% операторов, 92.85% ветвейТесты проверки взаимодействия, построения команд, сопоставления ответов QMP, очистки артефактов, кадрирования помощника, обнаружения возможностей и ограничения путей
Запустите явные локальные проверки процесса нативного помощника с помощью:
npm run test:spice-helperЗапустите набор одноразовых ВМ только с установленными всеми тремя переменными безопасности:
BOXES_INTEGRATION=1 \
BOXES_TEST_VM=an-explicit-disposable-domain \
BOXES_TEST_VM_DISPOSABLE=1 \
npm run test:integrationЖивой набор никогда не выбирает перечисленную ВМ, не изменяет определения ВМ и не
останавливает гостевую службу самостоятельно. Покрытие отключения гостевого агента требует,
чтобы оператор вручную отключил spice-vdagent в явно одноразовой гостевой системе и добавил
BOXES_TEST_AGENT_DISCONNECTED=1; никогда не делайте этого с неодноразовой гостевой системой.
Набор тестов по умолчанию использует моки и работает локально: он не доказывает, что QMP, SPICE, буфер обмена или drag-and-drop работают с реальной ВМ. Живые тесты должны быть явно включены (opt-in) и нацелены на конкретную именованную одноразовую ВМ со снапшотами; инструменты взаимодействия никогда не выбирают произвольный первый домен из списка.
Сборка
# Build TypeScript
npm run build
# Watch mode for development
npm run devНеобязательный пользовательский systemd-сервис
Юнит-файл, включённый в репозиторий, предназначен для локальной копии исходников. Он не нужен, когда сервер запускается через MCP-конфигурацию агента или установлен глобально через npm. Установите его как пользовательский сервис для автоматического запуска после сборки локальной копии:
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-mcpВопросы безопасности
✅ Изолированное выполнение: используется Node.js
execFileс ограничениями по таймауту и размеру буфера✅ Никаких произвольных команд: разрешены только предопределённые операции virsh
✅ Типизированная граница входных данных: команды QMP и операции SPICE — это внутренние enum-c`перечисления с проверяемыми аргументами
✅ Ограниченный объём данных: число нажатий клавиш, длительности удержания, координаты, дельты прокрутки, скриншоты, буфер обмена и передачи ограничены сверху
✅ Ограничение пути: источники drag/drop после канонизации должны оставаться в пределах
BOXES_TRANSFER_ROOT✅ Сохранение хранилища: хранилище ВМ по умолчанию не удаляется
✅ Изоляция LIBVIRT_URI: учитывается подключение к libvirt, заданное через переменные окружения
⚠️ Требуются права: пользователь должен состоять в группе libvirt
⚠️ Сетевая доступность: не рассчитан на удалённый доступ без дополнительной защиты
⚠️ Расширенная поверхность управления: скриншоты и данные буфера обмена гостя не считаются доверенными; держите MCP-сервер на локальном stdio
⚠️ Доверие к SPICE-хелперу: исполняемый файл хелпера — явная зависимость хоста; он не должен логировать учётные данные, содержимое буфера обмена или содержимое файлов
Протокол SPICE-хелпера
TypeScript-сервер запускает один постоянный дочерний процесс-хелпер и отправляет через stdin запросы JSON версии 1, разделённые переводами строк, сопоставляя ответы по ID запроса. Хелпер вызывается с явным путём к исполняемогому файлу и без аргументов, управляемых вызывающим. Обёртка запроса выглядит так:
{
"version": 1,
"id": "request-123",
"operation": "clipboard.read",
"domain": "guest-name",
"display": { "uri": "spice://127.0.0.1:5900" },
"arguments": { "selection": "clipboard", "maxBytes": 1048576 }
}Поддерживаемые имена операций — внутренние: (status, mouse, clipboard.read, clipboard.write, file.transfer, drag-drop). Ошибка хелпера сопоставляется со стабильной ошибкой MCP, например SPICE_AGENT_DISCONNECTED, SPICE_CAPABILITY_MISSING или SPICE_UNAVAILABLE. Ограничены объём полезных данных, длина строк, число ожидающих запросов, размеры передач, а также суммарное байты буфера обмена и время операции. События прогресса никогда не завершают запрос. Хелпер не логирует содержимое буфера, содержимое файлов, SPICE-билеты и учётные данные.
Матрица возможностей
Возможность | Libvirt/virsh | Резервный вариант QMP | SPICE-хелпер | |||
Скриншот | Реализован через | Не используется | Адаптер зарезервирован; без хелпера недоступен | |||
Клавиатура | Реализована через разрешённую | Не используется | Не используется | |||
--- | Мышь | Не используется | Типизированный | Выбирается | ? Нужно проверить. |
Стоп, я заметил: в таблице я написал |s-|Мышь | — ошибка. Нужно правильно. Давай переписать таблицу аккуратно.
Возможность | Libvirt/virsh | Резервный вариант QMP | SPICE-хелпер |
Скриншот | Реализован через | Не используется | Адаптер зарезервирован; без хелпера недоступен |
Клавиатура | Реализована через разрешённую | Не используется | Не используется |
Мышь | Не используется | Типизированный |
|
Буфер обмена | Недоступен | Недоступен | Реальный протокол агента в нативном хелпере; Wayland/Hyprland гости могут сообщать |
Передача файлов | Недоступна | Недоступна | Реальный асинхронный путь копирования файлов SPICE в нативном хелпepere; завершение реальной передачи наблюдалось, когда гостевой агент объявляет его |
Drag-and-drop | Недоступен | Недоступен | Экспериментальная передача + подтверждение указателя; приём приложением остаётся неизвестным |
Поддержка буфера обмена зависит от интеграции с рабочим столом гостя. Текущий гостевой агент SPICE ориентирован на X11, поэтому гостевые системы Wayland, такие как Hyprland/Omarchy, могут сообщать SPICE_CAPABILITY_MISSING, даже когда spice-vdagent установлен и запущен. Мышь и передача файлов при этом могут работать независимо.
Устранение неполадок
Список ВМ пуст
# Check libvirt URI
virsh -c qemu:///system list --all
virsh -c qemu:///session list --all
# Verify permissions
groups # Should include 'libvirt' and 'kvm'Отказано в доступе
# Re-add to groups and re-login
sudo usermod -aG libvirt,kvm "$USER"
# Then logout/login or:
newgrp libvirtВМ не отображаются в Boxes
Откройте virt-manager и проверьте, какое подключение используют ваши ВМ:
Системное подключение:
qemu:///systemПользовательская сессия:
qemu:///session
Соответствующе задайте переменную окружения LIBVIRT_URI.
Ошибка возможностей SPICE
Если virsh domdisplay сообщает No graphical display found, а в XML домена содержится <graphics type='spice'><listen type='none'/></graphics>, это намеренная конфигурация libvirt без публичного слушателя. Не выдумывайте порт и не конфигурируйте конфигурацию ВМ только для построения URI просмотрщика. При настройке нативного хелпера boxes-mcp использует внутренний транспорт spice+libvirt-fd://local и запрашивает у libvirt графический дескриптор для каждого канала SPICE. Хелпер должен использовать то же подключение libvirt, что и процесс 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.jsДомен должен быть запущен, хелпер должен быть слинкован с libvirt и spice-client-glib-, а гостевой виртуальный агент должен предоставить канал virtio SPICE. Подключённый агент может при этом не обладать поддержкой буфера обмена; проверяйте boxes.capabilities с probeSpice: true, а не делайте вывод о поддержке только из XML.
Используйте boxes.capabilities со probeSpice: true и прочитайте возвращённое состояние:
configured: провербюённый хелпер и SPICE-endpoint настроены, но подтверждение подключения не запрашивалось;connecting: хелпер наблюдал неполный набор каналов;connected: требуемые каналы подключены;agent-disconnected: гостевой агент не подключён;capability-missing: отсутствует бэкенд, канал, хелпер или возможность гостя.
Например, подключённый гостевой агент, который поддерживает передачу файлов, но не объявляет буфер обмена, — это capability-missing, а не agent-disconnected. Чтобы включить буфер обмена, в гостевой системе должен быть установлен сервис spice-vdagent из дистрибутива, запущенный в сессии рабочего стола и подключённый через канал virtio SPICE agent. На рабочем столе Wayland/Hyprland наглядно проверьте, что агент дистрибутива поддерживает именно этот композитор; одного запущенного сервиса недостаточно. Живой гость Omarchy имел spice-vdагент 0.23.0-1 и активный пользовательский сервис, но в логе были сообщения xrandr output ID NOT\nFOUND и no owner for org.gnome DisplayConfig, поэтому boxes-mcp исправно вернула SPICE_CAPABILITY_MISSING. У севistem; для актуального апстрим-агента используйте гость сессию X11 или же отдельно проверенный мота для буфера обмена в Wayland. Сервер не устанавливает гостевых пакеты и не запускает в гостевой системе сервисы автоматически.
Постоянный SPICE-клиент также принимает сигнал прерывания. Отмена завершает текущий процесс хелпера, детерминированно завершает все ожидающие операции и позволяет следующему запросу создать чистую сессию; это регистрируется как OPERATION_CANCELLED.
Проверить хостозависимые элементы и хелпер напрямую, не отправляя ввод в ВМ:
pkg-config --modversion spice-client-glib-2.0 json-glib-1.0 gio-unix-2.0
npm run build:spice-helperЛокальный тест протокола хелпера намеренно подключается к 127.0.0.1:1 и ждёт типизированного результата unavailable/disconnected. Это не доказательство живого SPICE.
План работы
Создание ВМ через
virt-installУправление сетями (
virshnet-list, проброс портов)Информация о пулах хранения (
virsh vol-list)Импорт ВМ из OVA/QCOW2
Поддержка удалённого подключения к libvirt
Метрики производительности и мониторинг
Вклад
Вклад вкладом приветствуется! Пожалуйста, ознакомьтетесь с условиями в файле CONTRIBUTING.md.
Сделайте fork репозитория
Создайте ветвь фичи (
git checkout -b feature/amazing-feature)Запустите тестик (
npm test)Закоммитьте изменения (
git commit -m 'Add amazing feature')Отёлchange поднят (
git push origin feature/amazing-feature)Откройте Pull Request
Лицензия
Проект распространяется под лицензией MIT — подробности в файле LICENSE.
Благодарности
Сделано для Claude Code
Используется Model Context Protocol SDK
Интеграция с libvirt API виртуализации
Поддержка
Issues: GitHub Issues
Обсуждения: GitHub Discussions
Документация: Project Wiki
Сделано с ❤️ для сообщества 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