Jetkvm
БесплатноНе проверенMCP server that enables AI to see and control a physical computer via a JetKVM device for screen viewing, mouse/keyboard input, media mounting, and power manage
Описание
MCP server that enables AI to see and control a physical computer via a JetKVM device for screen viewing, mouse/keyboard input, media mounting, and power management.
README
Give an AI eyes and hands on a physical computer.
jetkvm-mcp is an MCP server that turns a JetKVM — a small open-source KVM-over-IP device — into a machine that Claude (or any MCP client) can see and operate directly: watch the screen, type, click, mount boot media, and control power. Because the JetKVM sits on the HDMI and USB ports, the AI drives the computer below the OS — BIOS screens, bootloaders, installers, headless boxes with no network, machines that are wedged. No agent, no SSH, nothing installed on the target.
you: "Screenshot the machine. It's stuck — what's wrong?"
claude: → screenshot → "It's sitting at a GRUB rescue prompt. The root partition
UUID changed. Want me to boot it manually?" → type_text → enter → fixed
Works against stock JetKVM firmware — no modifications to the device.
The two planes
| Plane | Tools | Nature |
|---|---|---|
| Screen control (eyes + hands) | screenshot, click, double_click, move_mouse, type_text, press_key, scroll |
vision loop — the AI looks, then acts |
| Device control | mount_media_url, mount_media_storage, upload_media, upload_and_mount, unmount_media, list_storage, delete_storage_file, storage_space, virtual_media_state, power, power_state, dc_power, wake_host, wol, usb_emulation, video_state, reboot_device |
deterministic RPC |
Full parameter reference: docs/tools.md.
How it works
One WebRTC peer connection to the device drives everything:
Claude ──MCP/stdio──▶ server.py (this repo, runs on your workstation)
│
└──WebRTC over LAN──▶ JetKVM ──HDMI-in / USB-HID-out──▶ target machine
├─ H.264 video track ─▶ decoded locally (PyAV) ─▶ JPEG screenshots
└─ "rpc" data channel ─▶ keyboard / mouse / media / power JSON-RPC
- The device already streams its HDMI capture as an H.264 video track — the client decodes it locally and hands the AI JPEG snapshots on demand. (JetKVM has no snapshot endpoint; it doesn't need one.)
- A reliable
rpcdata channel carries every JSON-RPC method the device's own web UI uses:keyboardReport,absMouseReport(absolute 0–32767, drift-free),mountWithHTTP,setATXPowerAction, and friends. - The server connects lazily on the first tool call and keeps the one connection alive.
Deep dive — handshake, codec negotiation, the keyframe/PLI story, coordinate mapping: docs/architecture.md.
Requirements
- A JetKVM attached to the target machine, reachable on your network
- Python 3.11+ on the machine that runs Claude
aiortc/avwheels bundle FFmpeg on macOS/Linux; if a build from source is triggered, install FFmpeg dev libraries first (brew install ffmpeg/apt install libavdevice-dev)
Quickstart
git clone https://github.com/shvartzj1/jetkvm-mcp.git
cd jetkvm-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # set JETKVM_URL (+ JETKVM_PASSWORD if your device has one)
Prove the pipeline before wiring it into anything — this connects, holds the stream open, and saves four screenshots:
set -a; source .env; set +a
python smoke_test.py
Expected output — sustained ~60 fps, snapshots in single-digit milliseconds after the first:
connected. video_state: {'ready': True, 'width': 1280, 'height': 1024, 'fps': 60}
snapshot 0: 1280x1024 179578 bytes (grab 3129 ms) frames_seen=1
snapshot 1: 1280x1024 178280 bytes (grab 11 ms) frames_seen=128
...
Wire it into Claude
Claude Code (one command, available in every session):
claude mcp add jetkvm --scope user \
--env JETKVM_URL=http://192.168.1.50 \
--env JETKVM_VERIFY_TLS=false \
-- /abs/path/jetkvm-mcp/.venv/bin/python /abs/path/jetkvm-mcp/server.py
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"jetkvm": {
"command": "/abs/path/jetkvm-mcp/.venv/bin/python",
"args": ["/abs/path/jetkvm-mcp/server.py"],
"env": {
"JETKVM_URL": "http://192.168.1.50",
"JETKVM_PASSWORD": "",
"JETKVM_VERIFY_TLS": "false"
}
}
}
}
Then just talk to it: "Screenshot the machine, open a terminal, and check disk usage."
The AI calls screenshot → reasons → click / type_text → repeats.
The killer workflow: hands-free bare-metal provisioning
Device control and screen control compose into something no in-OS agent can do — installing an operating system on an empty machine:
mount_media_url("https://mirror.lan/rocky-9.iso", "CDROM") # host the ISO yourself
power("reset") # reboot into the installer
# screenshot → click → type_text … the AI walks through the installer by sight
unmount_media()
The device's own storage partition is tiny, so mount_media_url (the device streams the image
over HTTP with range requests) is the right path for full-size ISOs; upload_and_mount is for
small recovery images.
Gotchas (read this before filing a bug)
- First screenshot takes ~3 s; the rest are instant. The device only emits an H.264
keyframe when asked via RTCP PLI. Browsers request keyframes automatically; aiortc does not —
so this client sends PLI on connect and whenever frames go stale (
_request_keyframeinclient.py). Without that, decode fails on every packet forever (avcodec_send_packet: Invalid data). If you're building your own client: this is the trap. - Keyboard layout:
type_textmaps ASCII → USB HID usage codes assuming the US layout on the target OS. On other layouts, shifted symbols swap (on a UK target,"arrives as@). Letters, digits, and/ - . ; =are layout-stable; prefer them in critical commands. - Coordinates:
click/move_mousetake pixel coordinates on the most recentscreenshot; the client maps them to the HID absolute range using the live frame dimensions, so there is no drift. getVideoStatemay reportstreaming: 0even while frames flow at 60 fps — cosmetic quirk, ignore it.- TLS: stock firmware serves plain HTTP on the LAN. The device supports optional TLS
(Settings → Advanced) — enable it and set
JETKVM_URL=https://…, plusJETKVM_VERIFY_TLS=trueif the cert is trusted. WebRTC media/control is DTLS/SRTP-encrypted peer-to-peer regardless of how the signaling travelled. powerneeds the ATX extension board wired to the motherboard header; without it the tool is a no-op (power_statereadspower: false).
Safety
This lets a language model drive a real computer with real consequences. Recommendations:
- Point it at a test box or lab machine first, not your production NAS.
- The destructive tools are
power,reboot_device,dc_power,mount_*,delete_storage_file, and anypress_keyof a reboot chord — consider requiring per-call confirmation for them in your MCP client's permission settings. - Set a device password (and TLS) if the JetKVM is reachable by anyone but you.
Development
jetkvm/client.py WebRTC + JSON-RPC client (connect, snapshot, HID input, uploads)
jetkvm/keymap.py ASCII / key-combo → USB HID usage codes
server.py FastMCP server exposing the 24 tools
smoke_test.py live end-to-end check against a real device
docs/ architecture + tool reference
Validated end-to-end against a JetKVM v2 on firmware/app 0.5.8 (Jul 2026): sustained 60 fps decode, keyboard input, HTTP CDROM mount/unmount, ATX/DC state reads — including driving it from a live Claude session. The RPC surface is verified against the jetkvm/kvm source.
Ideas / roadmap
- Keyboard layout profiles for
type_text(US hardcoded today) - Gate destructive tools behind an env flag
- Native
getSnapshotRPC upstream in the firmware would remove the H.264 decode dependency entirely (see jetkvm/kvm#1459)
License
MIT. Not affiliated with JetKVM/Improve Robotics — this is an independent client of the device's public API.
Установка Jetkvm
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/shvartzj1/jetkvm-mcpFAQ
Jetkvm MCP бесплатный?
Да, Jetkvm MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Jetkvm?
Нет, Jetkvm работает без API-ключей и переменных окружения.
Jetkvm — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Jetkvm в Claude Desktop, Claude Code или Cursor?
Открой Jetkvm на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
Omni Video
An MCP server that transforms LLM-enabled IDEs into professional video editors by pre-processing footage into text proxies, generating motion graphics via HTML/
автор: buildwithtazaARA
Generate images, video and audio from any AI agent — one connector.
автор: ARAYouTube
Transcripts, channel stats, search
автор: YouTubeEverArt
AI image generation using various models.
автор: modelcontextprotocolCompare Jetkvm with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории media
