Skip to main content
Glama

docker-vm-mcp

Создано sundar.

MCP-сервер, который даёт ИИ-агенту полный контроль над жизненным циклом виртуальных машин — создание, вход по SSH, выполнение команд, остановка/запуск/перезапуск, удаление, логи и статистика ресурсов — на «ВМ», работающих поверх Docker-контейнеров. Каждая ВМ — это настоящая система Ubuntu с реально запущенным sshd, sudo и постоянным диском, поэтому она ведёт себя как обычная машина, в которую можно залогиниться, — без облачного аккаунта и без вложенной виртуализации. Сам сервер контейнеризирован и публикуется как Docker-образ, а управляется целиком через Model Context Protocol.

После настройки вы можете просто попросить Claude, например:

  • «Создай ВМ с именем dev-box с 2 CPU и 2 ГБ RAM»

  • «Подключи меня по SSH к dev-box» / «Какой SSH-логин у dev-box?»

  • «Установи nginx на dev-box и запусти его»

  • «Останови dev-box» / «Удали dev-box»

  • «Покажи список моих ВМ»

и Claude выполнит весь жизненный цикл через инструменты ниже.

Как это работает

Каждая «ВМ» — это Docker-контейнер, собранный из небольшого образа Ubuntu 22.04 (vm-image/Dockerfile), в котором работает настоящий sshd, есть sudo, а в качестве домашнего каталога подмонтирован именованный том (поэтому данные переживают остановку/перезапуск — аналогично EBS-тому, подключённому к EC2). Сам MCP-сервер общается с вашим локальным Docker-демоном через /var/run/docker.sock — он не запускает ВМ сам, он управляет уже установленным у вас Docker Desktop.

Claude  <--MCP/stdio-->  docker-vm-mcp container  <--docker.sock-->  Docker Desktop
                                                                          |
                                                                    vm-dev-box (Ubuntu + sshd)
                                                                    vm-staging (Ubuntu + sshd)
                                                                    ...

Related MCP server: Docker MCP Server

Предварительные требования

  • Установленный и запущенный Docker Desktop на вашем Mac

  • Node.js 20+ — только если вы хотите запускать сервер вне Docker (не обязательно)

1. Сборка

Из этой папки:

docker build -t docker-vm-mcp:latest .

Собирается только образ MCP-сервера. Базовый образ ВМ (docker-vm-mcp/vm-base:latest) собирается автоматически при первом вызове vm_create. Также вы можете собрать его заранее самостоятельно:

docker build -t docker-vm-mcp/vm-base:latest ./vm-image
{
  "mcpServers": {
    "docker-vm-mcp": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/var/run/docker.sock:/var/run/docker.sock",
        "-v", "docker-vm-mcp-state:/data",
        "docker-vm-mcp:latest"
      ]
    }
  }
}
docker run -i --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v docker-vm-mcp-state:/data \
  docker-vm-mcp:latest
# should print nothing and just wait on stdin (that's correct — it's
# speaking MCP, not a REPL). Ctrl+C to exit.

2. Запуск

MCP-серверы через stdio запускаются клиентом, а не как отдельный процесс. Добавьте это в конфигурацию Claude Desktop (путь ~/Library/Application Support/Claude/claude_desktop_config.json):

ssh vmuser@localhost -p <port>   # port and password from vm_create / vm_ssh_info

Оба монтирования обязательны:

  • /var/run/docker.sock — доступ к демону Docker.

  • docker-vm-mcp-state — именованный том, где сервер хранит сгенерированные SSH-пароли, чтобы они переживали перезапуски. Без него пароли теряются при каждом перезапуске контейнера MCP-сервера (сами ВМ продолжают работать).

Проверить, что образ работает и видит Docker, до подключения к Claude Desktop можно так:

docker tag docker-vm-mcp:latest <your-dockerhub-username>/docker-vm-mcp:latest
docker push <your-dockerhub-username>/docker-vm-mcp:latest

Инструменты, которые предоставляет сервер

Инструмент

Что делает

vm_create

Создаёт и запускает новую ВМ. Параметры: name, cpus, memoryMb, sshPort, sshUser, sshPublicKey. Возвращает SSH-команду и сгенерированный пароль.

vm_list

Список всех управляемых ВМ со статусом и SSH-портом.

vm_start

Запускает остановленную ВМ.

vm_stop

Останавливает работающую ВМ (диск сохраняется).

vm_restart

Перезагружает ВМ.

vm_delete

Удаляет ВМ навсегда (и её диск, если не указано removeVolume=false).

vm_exec

Выполняет команду в shell внутри ВМ напрямую через Docker (без SSH).

vm_ssh_info

Возвращает SSH-команду, хост, порт, пользователя и пароль для ВМ.

vm_set_password

Генерирует или меняет SSH-пароль ВМ (также синхронизирует vm_ssh_info после ручной смены пароля).

vm_logs

Показывает последние записи из консоли/системного лога ВМ.

vm_stats

Живая статистика CPU и памяти для запущенной ВМ.

Вход вручную

Каждая ВМ публикует свой SSH-порт на ваш Mac, поэтому после того как Claude создал ВМ, вы можете подключиться к ней по SSH напрямую:

docker-vm-mcp/
├── Dockerfile              # MCP server image
├── package.json
├── tsconfig.json
├── vm-image/
│   └── Dockerfile          # base "VM" image (Ubuntu + sshd), built on first vm_create
└── src/
    ├── index.ts            # MCP server entrypoint (stdio transport)
    ├── docker.ts            # Docker client, image-build, container lookup helpers
    ├── state.ts             # local credential store (/data/credentials.json)
    ├── util.ts              # exec/log demuxing helpers
    └── tools/
        ├── createVm.ts
        ├── listVms.ts
        ├── startVm.ts
        ├── stopVm.ts
        ├── restartVm.ts
        ├── deleteVm.ts
        ├── execVm.ts
        ├── sshInfo.ts
        ├── setPassword.ts
        ├── logsVm.ts
        └── statsVm.ts

Передайте sshPublicKey (содержимое вашего ~/.ssh/id_ed25519.pub или ~/.ssh/id_rsa.pub) при вызове vm_create, чтобы входить без пароля — по ключу.

Публикация этого образа

Чтобы поделиться им (например, чтобы коллега или другая машина могли просто сделать docker pull вместо сборки из исходников):

npm install
npm run build

В образе нет ничего секретного — пароли генерируются отдельно для каждой ВМ в момент запуска и хранятся только в локальном томе docker-vm-mcp-state на той машине, где запущен контейнер. Публиковать безопасно.

Безопасность (прочитайте, прежде чем открывать доступ за пределами своей машины)

  • Монтирование Docker-сокета равносильно root-доступу. Любой, у кого есть доступ к /var/run/docker.sock, может управлять всеми контейнерами на вашей машине, а не только ВМ этого инструмента. Запускайте этот образ с таким монтированием только на доверенной машине и никогда не открывайте сам MCP-сервер (или его порт) для недоверенных вызывающих.

  • SSH-пароли хранятся в открытом виде в томе docker-vm-mcp-state (/data/credentials.json), чтобы vm_ssh_info мог их вернуть. Для личного локального инструмента это нормально; не используйте его в продакшене или мультитенантных сценариях без доработки (например, перехода на авторизацию по ключам и отказа от хранения паролей).

По умолчанию SSH-порт ВМ публикуется на 0.0.0.0, то есть на всех сетевых интерфейсах вашего Mac. Если это нежелательно, измените привязку в src/index.ts (поле, задающее адрес публикации) и пересоберите образ.

Как залогиниться самому

Каждая ВМ публикует свой SSH-порт на вашем Mac, так что после создания ВМ вы можете зайти в неё прямо из терминала:

docker-vm-mcp/
├── Dockerfile              # MCP server image
├── package.json
├── tsconfig.json
├── vm-image/
│   └── Dockerfile          # base "VM" image (Ubuntu + sshd), built on first vm_create
└── src/
    ├── index.ts            # MCP server entrypoint (stdio transport)
    ├── docker.ts            # Docker client, image-build, container lookup helpers
    ├── state.ts             # local credential store (/data/credentials.json)
    ├── util.ts              # exec/log demuxing helpers
    └── tools/
        ├── createVm.ts
        ├── listVms.ts
        ├── startVm.ts
        ├── stopVm.ts
        ├── restartVm.ts
        ├── deleteVm.ts
        ├── execVm.ts
        ├── sshInfo.ts
        ├── setPassword.ts
        ├── logsVm.ts
        └── statsVm.ts

Передайте содержимое вашего ~/.ssh/id_ed25519.pub в параметре sshPublicKey при вызове vm_create, чтобы пропустить пароль и использовать свой ключ.

Публикация образа

Чтобы опубликовать образ (например, чтобы коллега или другая машина могли просто docker pull, не собирая из исходников):

npm install
npm run build

В образ не зашито никаких секретов — учётные данные генерируются для каждой ВМ отдельно и хранятся только в локальном томе docker-vm-mcp-state на той машине, где запущен контейнер. Публиковать безопасно.

Замечания по безопасности (прочитайте, прежде чем открывать доступ за пределами вашей машины)

  • Монтирование Docker-сокета равносильно root-доступу. Любой, у кого есть доступ к /var/run/docker.sock, может управлять всеми контейнерами на вашей машине, а не только ВМ, созданными этим инструментом. Запускайте этот образ только на доверенной машине и никогда не открывайте сам MCP-сервер (или порт к нему) для недоверенных клиентов.

  • SSH-пароли хранятся в открытом виде в томе docker-vm-mcp-state (/data/passwords.json), чтобы vm_ssh_info мог их возвращать. Для личного/локального использования это приемлемо, но не используйте этот проект для production или мультитенантных сценариев.

  • ВМ публикуют свой SSH-порт на 0.0.0.0 (все интерфейсы Mac), поэтому другие устройства в вашей локальной сети могут попытаться подключиться, если брандмауэр это разрешает. Если это важно, укажите bindIp или настройте сеть под свои нужды.

Проверка на реальном примере: ServiceNow Discovery

Этот проект проверялся на реальном экземпляре ServiceNow через Dockerized MID Server — подтверждение, что это настоящая SSH-достижимая Linux-система, а не игрушка:

  • Standard Discovery: MID Server → ВМ через LAN-IP Mac и опубликованный SSH-порт ВМ (например, 192.168.x.x:<port>) — успешно создавалась запись cmdb_ci_linux_server с hostname, ОС, RAM и CPU, собранными по SSH.

  • Horizon Discovery тоже работает.

  • Поскольку MID Server и ВМ находятся в одной bridge-сети Docker, они могут общаться напрямую по внутренним IP без опубликованного порта.

  • Один нюанс: в обнаруженных данных CPU будет указан как «Apple» — это не баг. Docker Desktop на Mac запускает контейнеры внутри linuxkit VM на чипе Apple Silicon, поэтому SSH-пробы видят реальное железо хоста.

Структура проекта

docker-vm-mcp/
├── Dockerfile              # MCP server image
├── package.json
├── tsconfig.json
├── vm-image/
│   └── Dockerfile          # base "VM" image (Ubuntu + sshd), built on first vm_create
└── src/
    ├── index.ts            # MCP server entrypoint (stdio transport)
    ├── docker.ts            # Docker client, image-build, container lookup helpers
    ├── state.ts             # local credential store (/data/credentials.json)
    ├── util.ts              # exec/log demuxing helpers
    └── tools/
        ├── createVm.ts
        ├── listVms.ts
        ├── startVm.ts
        ├── stopVm.ts
        ├── restartVm.ts
        ├── deleteVm.ts
        ├── execVm.ts
        ├── sshInfo.ts
        ├── setPassword.ts
        ├── logsVm.ts
        └── statsVm.ts

Как проводилась проверка

Проект собирался и проверялся в среде с доступом к сети и Docker. npm install, сборка и запуск MCP-сервера выполнялись локально; инструменты проверялись вызовами через MCP. Полная автоматизация тестов не входит в проект.

Лицензия

npm install
npm run build

Related MCP Connectors

Related MCP Servers