Skip to main content
Glama

JetKVM MCP Server

Это stdio-сервер, который открывает официальный локальный веб-интерфейс JetKVM через Playwright и предоставляет захват экрана подключенного компьютера и HID-ввод в качестве MCP Tool.

В этом документе компьютер, подключенный к JetKVM и управляемый им, называется «ПК1», а компьютер, на котором выполняются MCP Server и Playwright, — «ПК2». HID относится к вводу мыши и клавиатуры, которые JetKVM отправляет на ПК1.

Реализованные функции

  • Получение PNG с теми же размерами в пикселях, что и видеокадр, полученный от ПК1

  • Абсолютное перемещение мыши, щелчок, двойной щелчок, прокрутка

  • Ввод одиночной клавиши, горячих клавиш для macOS, печатных ASCII-символов

  • Определение экрана блокировки macOS, требующего нескольких визуальных признаков, и попытка разблокировки, ограниченная максимум одним разом

  • Постоянное повторное использование BrowserContext, WebRTC и HID DataChannel

  • Однократное повторное подключение при разрыве WebRTC и сохранение диагностики в HTML/PNG

  • Ограничение выходного каталога, отклонение имен файлов, указывающих за его пределы, подавление учетных данных в журналах

Related MCP server: Playwright MCP

Метод, основанный на исследовании

Был проверен официальный репозиторий JetKVM jetkvm/kvm (ветка dev, коммит b3c29a44d9e2862b8ff7530830781803ce27b060) по состоянию на 2026-08-18.

  • Локальный интерфейс аутентификации использует POST /auth/login-local и при успехе устанавливает HttpOnly cookie authToken.

  • Локальный WebRTC signaling использует защищенный аутентификацией GET /webrtc/signaling/client.

  • Интерфейс добавляет recvonly видеотрансивер к RTCPeerConnection и устанавливает полученный MediaStream как srcObject для <video>.

  • Данная реализация просто запускает этот официальный интерфейс через Playwright, рисует декодированный видеокадр на canvas и преобразует его в PNG.

Собственный signaling, Developer Mode, собственная прошивка, Cloud/Remote Access и изменение настроек JetKVM не используются. Виртуальные носители, Wake on LAN, Terminal, Serial и т. д. также не предоставляются.

Архитектура

При запуске MCP Server создается по одному экземпляру Playwright Chromium, BrowserContext и page, выполняется однократный вход в JetKVM и ожидание готовности WebRTC-видео. Все инструменты используют один и тот же page и сеанс WebRTC/DataChannel; одновременные вызовы обрабатываются последовательно. Обычные вызовы инструментов не вызывают перезапуск браузера или повторный вход.

Для ввода не используются page.mouse / page.keyboard из Playwright, так как они управляют только Chromium на ПК2 и не гарантируют доставку на ПК1.

Для мыши и клавиатуры в первую очередь вызывается window.__kvmTestHooks, который официальный веб-интерфейс JetKVM предоставляет для E2E-тестирования. Если hook недоступен, DOM-события отправляются слушателям событий, зарегистрированным официальным интерфейсом на <video> и document. Прокрутка всегда осуществляется через wheel-слушатель официального интерфейса, предназначенный для видео. Такая конструкция позволяет повторно использовать handshake HID RPC, выбор DataChannel и fallback для старых версий из официального интерфейса, не реализуя собственные HID-пакеты.

__kvmTestHooks не является стабильным внешним API JetKVM. Поскольку данная реализация проверена на указанном коммите, после обновления JetKVM необходимо повторно проверить совместимость системы ввода.

Основные компоненты:

Файл

Обязанность

Причина разработки

server.ts

Схема MCP и stdio lifecycle

Не допускать Playwright и учетные данные к границе MCP

session.ts

Постоянное использование Browser/WebRTC, сериализация, переподключение

Избежать конфликтов, использовать один DataChannel для всех инструментов

capture.ts

Получение кадра с исходными размерами пикселей, диагностика ошибок

Обрабатывать только видео с ПК1, а не весь интерфейс JetKVM

input.ts

Диспетчеризация к официальному HID hook и wheel RPC

Гарантированная доставка на ПК1, а не управление браузером ПК2

keyboard.ts

Соответствие имен клавиш MCP, KeyboardEvent.code и USB HID

Разделение преобразования клавиш и отправки

unlock.ts

Троичное определение OCR и максимум одна аутентификация

Предотвращение ввода секретов в обычные приложения при ошибочном определении

ПОТОК вызова инструмента:

MCP client
  → Zod引数検証
  → JetKvmSession内の直列実行キュー
  → WebRTC video健全性確認
  → 映像取得、または公式UIのHID/RPC経路
  → MCP response

При разрыве WebRTC та же страница перезагружается один раз для повторного подключения. Если восстановление не происходит в течение 30 секунд, сохраняются диагностические файлы и возвращается ошибка, включающая возможность существования другого сеанса WebRTC JetKVM.

JetKVM может конфликтовать при одновременных сеансах WebRTC. Во время использования MCP Server не открывайте экран KVM того же JetKVM в обычном Chrome/Safari и т. д.

Официальные материалы:

Настройка

Требуется Node.js 20 или выше.

npm install
npx playwright install chromium
export JETKVM_URL=http://jetkvm.local
export JETKVM_PASSWORD='your-local-password'
export JETKVM_SCREENSHOT_DIR=./screenshots
export JETKVM_PC_PASSWORD='your-pc1-macos-password'
npm run build

При использовании .env сервер сам не загружает dotenv автоматически, поэтому его нужно загрузить в оболочке запуска.

cp .env.example .env
# .envへ実値を設定(Gitにはcommitしない)
set -a
source .env
set +a
npm run build
npm start

При первом запуске устанавливается Chromium. При обычном запуске без обновления зависимостей повторное выполнение не требуется.

npx playwright install chromium

JETKVM_PC_PASSWORD предназначен только для разблокировки ПК1 (macOS). Не передавайте его в аргументах инструмента, управляйте им только через локальный .env на ПК2. .env уже добавлен в gitignore, но не копируйте его случайно под другим именем. Рекомендуется не записывать его в открытом виде в файлы конфигурации, такие как Hermes, а наследовать переменные окружения из оболочки запуска.

Прямая проверка получения PNG

npm run screenshot -- current-screen.png

При успехе сохраняется screenshots/current-screen.png. Имя файла не может выходить за пределы JETKVM_SCREENSHOT_DIR, разрешено только расширение .png.

При каждом выполнении после 5-секундного ожидания инициализации SPA, до ожидания видео, также сохраняется и выводится в stderr следующая диагностическая информация. Если видео не получено, диагностические файлы все равно сохраняются.

  • Текущий URL, заголовок страницы, первые 2000 символов текста

  • Количество элементов video, password input, form, #root, text=JetKVM

  • screenshots/debug-page.html

  • screenshots/debug-page.png (full-page)

Пример настройки MCP

{
  "mcpServers": {
    "jetkvm": {
      "command": "node",
      "args": ["/path/to/jetkvm-mcp/dist/server.js"],
      "env": {
        "JETKVM_URL": "http://jetkvm.local",
        "JETKVM_PASSWORD": "<local-password>",
        "JETKVM_SCREENSHOT_DIR": "/path/to/jetkvm-mcp/screenshots"
      }
    }
  }
}

Предоставляемые инструменты и аргументы MCP:

Инструмент

Аргументы

Действие

take_screenshot

filename?: string

Сохраняет и возвращает PNG с теми же размерами в пикселях, что и полученное видео

move_mouse

x: int, y: int

Абсолютное перемещение в координаты видео ПК1

click

x, y, button?: left|right|middle

Один щелчок в указанной позиции

double_click

x: int, y: int

Отправляет две пары нажатий/отпусканий левой кнопки

scroll

dx: number, dy: number

Отправляет RPC прокрутки через wheel-слушатель официального интерфейса

press_key

key: string

Нажатие/отпускание соответствующей клавиши

hotkey

keys: string[]

Нажатие по порядку, отпускание в обратном порядке. Поддержка META/CMD

type_text

text: string

Ввод печатных ASCII-символов в раскладке US

unlock_pc

Нет

Попытка аутентификации только при явном экране блокировки, максимум один раз

ensure_unlocked

Нет

Если разблокирован — без ввода, если заблокирован — общая обработка разблокировки

Запись скриншотов ограничена каталогом screenshots/, находящимся непосредственно в текущем каталоге серверного процесса. При указании JETKVM_SCREENSHOT_DIR он также должен совпадать с этим местоположением после нормализации. Имена файлов, указывающие за пределы этого каталога, такие как ../ или абсолютные пути, отклоняются.

Спецификация безопасности разблокировки ПК1

Состояние блокировки определяется путем OCR по областям видео ПК1 с помощью Tesseract.js (WASM, включает английские и японские языковые данные) на ПК2 и выносится троичное решение: locked / unlocked / unknown. Изображения и результаты OCR не отправляются внешним сервисам.

Реализация OCR: https://github.com/naptha/tesseract.js

  • locked: В заданной области подтверждены все три типа: время, дата и подсказка для ввода пароля.

  • unlocked: Нет подсказки для ввода пароля, в верхней части экрана подтверждены 3 или более известных слов из строки меню macOS.

  • unknown: Состояние, когда вышеуказанные доказательства не собраны. Пароль и Enter не отправляются.

Это консервативное определение, основанное на расположении текста на экране, а не на получении состояния macOS через OS API. Возможно состояние unknown из-за языка отображения, разрешения, обоев или изменений в UI macOS. Во избежание ошибочного ввода приоритет отдается отсутствию попыток разблокировки при недостатке доказательств.

unlock_pc() и ensure_unlocked() не принимают аргументов MCP. Учетные данные считываются только из JETKVM_PC_PASSWORD и не включаются в журналы, исключения, ответы MCP или имена файлов. Ввод учетных данных осуществляется через специальный внутренний HID-канал, не выводящий диагностические журналы. На один вызов инструмента приходится максимум один ввод пароля и Enter, автоматические повторные попытки не выполняются. Изображения для определения сохраняются как unlock-before.png, ensure-unlocked-before.png, а для проверки результата — как unlock-after.png только в каталоге screenshots/.

Возвращаемый status может быть одним из: unlocked, already_unlocked, not_lock_screen, state_unknown, unlock_failed.

Тестирование

npm test
npm run build

Дорожная карта

Будущие кандидаты:

  • Сокращение задержки определения состояния за счет повторного использования OCR worker в сеансе

  • Добавление fixture для определения блокировки с большим разнообразием языков отображения, разрешений и обоев macOS

  • Структурированные события аудита для каждого инструмента ввода (без включения секретной информации)

  • Read-only health Tool для проверки состояния WebRTC/DataChannel без ввода

  • Оболочка запуска для Hermes Agent, не записывающая секреты в открытом виде в файлы конфигурации

Явные нецели:

  • Использование Developer Mode, собственной прошивки, Cloud/Remote Access

  • Предоставление API изменения настроек JetKVM, Terminal, Serial, виртуальных носителей, Wake on LAN

  • Прямая вставка строк в японскую IME, автоматические повторные попытки при сбое аутентификации

Журнал проверки на реальном оборудовании

  • 2026-08-18 ШАГ 1: В одном сеансе WebRTC выполнено 3 вызова take_screenshot и 2 вызова move_mouse.

  • (100,100) → HID (1708,3037), (1700,900) → HID (29028,27331).

  • В обоих случаях подтверждены официальный E2E HID hook, HID ready, RPC DataChannel open, WebRTC connected.

  • На mouse-a.png и mouse-b.png подтверждено перемещение курсора ПК1 в две разные точки.

  • Реальных вызовов click, double_click, scroll, press_key, hotkey, type_text: 0.

  • 2026-08-18 ШАГ 2: В одном сеансе WebRTC выполнено 2 вызова take_screenshot, 1 вызов move_mouse и 1 вызов left click.

  • (960,540) → HID (16392,16399). Для move/click подтверждены официальный E2E HID hook, HID ready, RPC DataChannel open, WebRTC connected.

  • Поскольку был выполнен щелчок по безопасному фону экрана блокировки, изменений в UI ПК1, кроме перемещения курсора, не было.

  • Реальных вызовов double_click, right click, scroll, press_key, hotkey, type_text на ШАГЕ 2: 0.

  • 2026-08-18 ШАГ 3: В одном сеансе WebRTC выполнено 2 вызова take_screenshot и 1 вызов press_key("Tab") (по одному нажатию/отпусканию).

  • Tab отправлен через официальный E2E HID hook sendKeypress (USB HID usage 0x2b). Подтверждены HID ready, RPC DataChannel open, WebRTC connected.

  • На изображениях before/after не удалось определить четкое изменение фокуса на экране блокировки. Реальных вызовов клавиш, отличных от Tab, click, double_click, scroll, hotkey, type_text на ШАГЕ 3: 0.

  • 2026-08-18 ШАГ 4: В одном сеансе WebRTC выполнено 3 вызова take_screenshot, 1 вызов type_text("abc") и 3 вызова press_key("Backspace").

  • abc и Backspace отправлены через официальный E2E HID hook sendKeypress. Для всех вводов подтверждены HID ready, RPC DataChannel open, WebRTC connected. Для ввода строчных букв Shift не использовался (0 раз), Enter не использовался (0 раз).

  • После ввода в поле пароля отобразились маркеры на 3 символа, которые исчезли после 3 нажатий Backspace. Перехода с экрана блокировки и дополнительных операций не было.

  • 2026-08-18 ШАГ 5: В одном сеансе WebRTC выполнено 2 вызова take_screenshot, 1 вызов move_mouse(1400,700) и 1 вызов left double_click(1400,700).

  • Двойной щелчок отправлен через официальный E2E HID hook sendAbsMouseMove с двумя парами нажатий/отпусканий левой кнопки. Подтверждены HID ready, RPC DataChannel open, WebRTC connected.

  • Выполнено в пустом месте экрана блокировки, состояние экрана не изменилось. Одиночных щелчков и других дополнительных вводов: 0.

  • 2026-08-18 ШАГ 6: В одном сеансе WebRTC выполнено 2 вызова take_screenshot, 1 вызов move_mouse(1150,540) в область текста сообщения Slack и 1 вызов scroll(0,500).

  • Прокрутка отправлена через официальный wheel-слушатель видео по пути wheel RPC JetKVM, нормализованное значение колеса: (0,-5). Подтверждены HID ready, RPC DataChannel open, WebRTC connected.

  • На before/after подтверждено перемещение текста сообщения Slack вверх. Щелчков, двойных щелчков, инструментов клавиатуры и других дополнительных вводов: 0.

  • 2026-08-18 ШАГ 7 (первая попытка): hotkey(["SHIFT","TAB"]) остановлен перед отправкой HID из-за ошибки нормализации заглавного TAB. Выполнено 2 скриншота, 0 HID-вводов на ПК1, изменений экрана нет.

  • Добавлено исправление для нормализации псевдонима TAB в Tab и unit-тест. В соответствии с условиями безопасности повторная попытка на реальном оборудовании в этот раз не выполнялась.

  • 2026-08-18 ШАГ 7 (повторная попытка): В одном сеансе WebRTC выполнено 2 вызова take_screenshot и 1 вызов hotkey(["SHIFT","TAB"]).

  • Отправка через официальный E2E HID hook sendKeypress в порядке: ShiftLeft down (0xe1), Tab down (0x2b), Tab up, ShiftLeft up. Подтверждены HID ready, RPC DataChannel open, WebRTC connected.

  • ПК1 изменился с отображения только обоев на отображение экрана блокировки. Других инструментов ввода и дополнительных реальных вводов: 0.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    -
    quality
    D
    maintenance
    Enables browser automation through Playwright with persistent sessions and cookie state management. Supports web navigation, page interaction, and browser control via JSON-RPC protocol over stdin/stdout.
    1
    MIT
  • A
    license
    A
    quality
    -
    maintenance
    Enables browser automation through Playwright using accessibility tree snapshots instead of screenshots. Supports web scraping, form interactions, testing, and connecting to existing browser sessions with logged-in accounts.
    14
    23
    7,623
    5
  • A
    license
    -
    quality
    D
    maintenance
    Enables AI to control a computer through mouse, keyboard, and screen capture tools, with support for local native and Docker sandboxed environments.
    11
    5
    MIT
  • A
    license
    C
    quality
    B
    maintenance
    Exposes a remote browser as MCP tools via Playwright, enabling AI agents to navigate and interact with web pages through DOM snapshots, clicks, typing, and form operations.
    40
    22
    8
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

  • AI-powered browser automation — navigate, click, fill forms, and extract data from any website.

View all MCP Connectors

Latest Blog Posts

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/YokihitoOkiBiz/jetkvm-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server