JetKVM MCP Server
JetKVM MCP Server
Ein stdio-Server, der die offizielle lokale WebUI von JetKVM mit Playwright öffnet und Bildschirmaufnahmen des angeschlossenen Computers sowie HID-Eingaben als MCP-Tools bereitstellt.
In diesem Dokument wird der Computer, der mit JetKVM verbunden ist und gesteuert wird, als „PC1“ bezeichnet, und der Computer, auf dem der MCP-Server und Playwright ausgeführt werden, als „PC2“. HID bezieht sich auf Maus- und Tastatureingaben, die JetKVM an PC1 sendet.
Implementierte Funktionen
PNG-Erfassung mit denselben Pixelabmessungen wie die von PC1 empfangenen Videobilder
Absolute Mausbewegung, Klick, Doppelklick, Scrollen
Einzeltaste, Hotkeys für macOS, druckbare ASCII-Eingabe
macOS-Sperrbildschirmerkennung, die mehrere Bildschirmmerkmale erfordert, und maximal ein Entsperrversuch
Wiederverwendung von BrowserContext, WebRTC und HID-Datenkanal im laufenden Betrieb
Einmaliger erneuter Verbindungsversuch bei WebRTC-Trennung und Diagnosespeicherung als HTML/PNG
Ausgabepfadbeschränkung, Ablehnung von Dateinamen, die auf Verzeichnisse außerhalb des Pfads verweisen, und Unterdrückung von Anmeldeinformationen in Protokollen
Related MCP server: Playwright MCP
Auf Untersuchungen basierender Ansatz
Das offizielle JetKVM-Repository jetkvm/kvm (Stand dev, Commit b3c29a44d9e2862b8ff7530830781803ce27b060) wurde zum Stand 2026-08-18 überprüft.
Die lokale Authentifizierungs-UI verwendet
POST /auth/login-localund setzt bei Erfolg ein HttpOnlyauthToken-Cookie.Das lokale WebRTC-Signaling verwendet das authentifizierungsgeschützte
GET /webrtc/signaling/client.Die UI fügt dem
RTCPeerConnectioneinenrecvonly-Video-Transceiver hinzu und setzt den empfangenen MediaStream alssrcObjecteines<video>-Elements.Diese Implementierung führt diese offizielle UI unverändert mit Playwright aus und zeichnet das decodierte Videobild auf eine Canvas, um es als PNG zu speichern.
Eigenes Signaling, Developer Mode, eigene Firmware, Cloud/Remote Access und JetKVM-Konfigurationsänderungen werden nicht verwendet. Virtuelle Medien, Wake-on-LAN, Terminal, Serielle Schnittstelle usw. werden ebenfalls nicht bereitgestellt.
Architektur
Beim Start des MCP-Servers werden jeweils eine Playwright-Chromium-Instanz, ein BrowserContext und eine Seite erstellt, einmalig bei JetKVM angemeldet und gewartet, bis das WebRTC-Video bereit ist. Alle Tools teilen sich dieselbe Seite und dieselbe WebRTC-/DataChannel-Sitzung; gleichzeitige Aufrufe werden nacheinander verarbeitet. Bei normalen Tool-Aufrufen wird der Browser weder neu gestartet noch eine erneute Anmeldung durchgeführt.
Für Eingaben werden page.mouse / page.keyboard von Playwright nicht verwendet. Diese würden nur Chromium auf PC2 steuern und können nicht garantieren, dass die Eingaben bei PC1 ankommen.
Maus und Tastatur werden bevorzugt über window.__kvmTestHooks aufgerufen, die die offizielle JetKVM-WebUI für E2E-Tests bereitstellt. Falls der Hook nicht verfügbar ist, werden DOM-Ereignisse an die Ereignis-Listener gesendet, die die offizielle UI auf <video> und document registriert hat. Das Scrollen erfolgt immer über den offiziellen Wheel-Listener der UI für das Video. Dieses Design vermeidet die Implementierung eigener HID-Pakete und nutzt den HID-RPC-Handshake, die DataChannel-Auswahl und den Fallback für ältere Versionen innerhalb der offiziellen UI.
__kvmTestHooks ist keine stabile externe API von JetKVM. Da diese Implementierung auf dem genannten Commit basiert, muss die Kompatibilität der Eingabesysteme nach JetKVM-Updates erneut überprüft werden.
Hauptkomponenten:
Datei | Verantwortung | Designbegründung |
| MCP-Schema und stdio-Lebenszyklus | Playwright und Anmeldeinformationen nicht der MCP-Grenze aussetzen |
| Browser/WebRTC-Persistenz, Serialisierung, Wiederverbindung | Konflikte vermeiden, denselben DataChannel für alle Tools verwenden |
| Bilderfassung mit Original-Pixelabmessungen des empfangenen Videos, Fehlerdiagnose | Nur das PC1-Video verarbeiten, nicht die gesamte JetKVM-UI |
| Dispatch an offizielle HID-Hooks und Wheel-RPC | Eingaben zuverlässig an PC1 senden, nicht an den PC2-Browser |
| Zuordnung von MCP-Tastennamen, KeyboardEvent.code und USB-HID | Schlüsselumwandlung und -sendung trennen |
| OCR-Dreifachbewertung und maximal eine Authentifizierung | Falscheingaben in normale Anwendungen bei Fehlentscheidungen verhindern |
Tool-Aufruffluss:
MCP client
→ Zod引数検証
→ JetKvmSession内の直列実行キュー
→ WebRTC video健全性確認
→ 映像取得、または公式UIのHID/RPC経路
→ MCP responseBei einer WebRTC-Trennung wird dieselbe Seite einmal neu geladen, um die Verbindung wiederherzustellen. Wenn die Verbindung nicht innerhalb von 30 Sekunden wiederhergestellt ist, werden Diagnosedateien gespeichert und ein Fehler zurückgegeben, der die Möglichkeit einer anderen JetKVM-WebRTC-Sitzung einschließt.
JetKVM kann bei gleichzeitigen WebRTC-Sitzungen zu Konflikten führen. Öffnen Sie während der Nutzung des MCP-Servers nicht dieselbe JetKVM-KVM-Ansicht in einem normalen Chrome/Safari usw.
Offizielle Quellen:
https://github.com/jetkvm/kvm/blob/dev/ui/src/routes/login-local.tsx
https://github.com/jetkvm/kvm/blob/dev/ui/src/routes/devices.%24id.tsx
https://github.com/jetkvm/kvm/blob/dev/ui/src/components/WebRTCVideo.tsx
Einrichtung
Node.js 20 oder höher ist erforderlich.
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 buildBei Verwendung einer .env-Datei lädt der Server selbst dotenv nicht automatisch; die Datei muss daher in der Start-Shell geladen werden.
cp .env.example .env
# .envへ実値を設定(Gitにはcommitしない)
set -a
source .env
set +a
npm run build
npm startNur beim ersten Mal wird Chromium installiert. Bei normalen Starts ohne Aktualisierung der Abhängigkeiten ist eine erneute Ausführung nicht erforderlich.
npx playwright install chromiumJETKVM_PC_PASSWORD ist ausschließlich für die Entsperrung von PC1 (macOS) vorgesehen. Übergeben Sie es nicht als Tool-Argument und verwalten Sie es nur in der lokalen .env-Datei auf PC2. Die .env-Datei ist in der gitignore enthalten, aber duplizieren Sie sie nicht versehentlich unter einem anderen Namen. Es wird empfohlen, sie nicht im Klartext in Konfigurationsdateien wie Hermes zu speichern, sondern die Umgebungsvariable von der Start-Shell zu erben.
Direkte Überprüfung der PNG-Erfassung
npm run screenshot -- current-screen.pngBei Erfolg wird die Datei screenshots/current-screen.png gespeichert. Der Dateiname darf nicht außerhalb von JETKVM_SCREENSHOT_DIR liegen und nur .png ist erlaubt.
Bei jeder Ausführung wird nach einer 5-sekündigen Wartezeit für die SPA-Initialisierung vor dem Warten auf das Video auch die folgende Diagnoseinformation gespeichert und auf stderr ausgegeben. Wenn kein Video erfasst werden kann, bleiben die Diagnosedateien erhalten.
Aktuelle URL, Seitentitel, erste 2000 Zeichen des Texts
Anzahl der Elemente
video, password input,form,#root,text=JetKVMscreenshots/debug-page.htmlscreenshots/debug-page.png(ganze Seite)
MCP-Konfigurationsbeispiel
{
"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"
}
}
}
}Veröffentlichte Tools und MCP-Argumente:
Tool | Argumente | Aktion |
|
| PNG mit denselben Pixelabmessungen wie das empfangene Video speichern und zurückgeben |
|
| Absolute Bewegung zu PC1-Videokoordinaten |
|
| Einmaliger Klick an der angegebenen Position |
|
| Zwei Sätze von linkem Button down/up senden |
|
| Scroll-RPC über den offiziellen Wheel-Listener der UI senden |
|
| Entsprechende Taste down/up |
|
| Tasten nacheinander down, in umgekehrter Reihenfolge up. |
|
| Druckbare ASCII-Zeichen als US-Tastaturlayout eingeben |
| Keine | Nur bei eindeutigem Sperrbildschirm maximal einen Authentifizierungsversuch durchführen |
| Keine | Wenn bereits entsperrt, keine Eingabe; nur bei gesperrtem Bildschirm gemeinsame Entsperrung durchführen |
Das Schreibziel für Screenshots ist auf das Verzeichnis screenshots/ direkt im aktuellen Arbeitsverzeichnis des Serverprozesses beschränkt. Wenn JETKVM_SCREENSHOT_DIR angegeben ist, muss der normalisierte Pfad mit diesem Ort übereinstimmen. Dateinamen, die auf Verzeichnisse außerhalb dieses Pfads verweisen (z. B. ../ oder absolute Pfade), werden abgelehnt.
Sicherheitsspezifikation für die PC1-Entsperrung
Der Sperrzustand wird durch bereichsbezogene OCR des PC1-Videos mit Tesseract.js (WASM, inklusive englischer und japanischer Sprachdaten) auf PC2 bestimmt und als einer von drei Werten (locked / unlocked / unknown) klassifiziert. Bilder oder OCR-Ergebnisse werden nicht an externe Dienste gesendet.
OCR-Implementierung: https://github.com/naptha/tesseract.js
locked: In einem bestimmten Bereich werden alle drei Elemente (Uhrzeit, Datum, Passworthinweis) bestätigt.unlocked: Kein Passworthinweis vorhanden, und im oberen Bildschirmbereich werden drei oder mehr bekannte macOS-Menüleistenbegriffe bestätigt.unknown: Die oben genannten Nachweise liegen nicht vollständig vor. Es werden weder Passwort noch Enter gesendet.
Dies ist keine Methode, die den macOS-Status über eine OS-API abruft, sondern eine konservative Bewertung basierend auf der Textanordnung auf dem Bildschirm. Aufgrund der Anzeigesprache, Auflösung, des Hintergrundbilds oder von macOS-UI-Änderungen kann der Zustand unknown sein. Um Falscheingaben zu vermeiden, wird bei unzureichenden Nachweisen kein Entsperrversuch unternommen.
unlock_pc() und ensure_unlocked() akzeptieren keine MCP-Argumente. Die Anmeldeinformationen werden nur aus JETKVM_PC_PASSWORD gelesen und nicht in Protokollen, Ausnahmen, MCP-Antworten oder Dateinamen aufgenommen. Die Eingabe der Anmeldeinformationen erfolgt über einen speziellen internen HID-Pfad, der keine Diagnoseprotokolle ausgibt. Pro Tool-Aufruf erfolgt maximal eine Passworteingabe und ein Enter; es gibt keine automatischen Wiederholungsversuche. Die Bewertungsbilder werden als unlock-before.png, ensure-unlocked-before.png und das Ergebnis als unlock-after.png nur innerhalb von screenshots/ gespeichert.
Der zurückgegebene status ist einer der folgenden: unlocked, already_unlocked, not_lock_screen, state_unknown, unlock_failed.
Tests
npm test
npm run buildRoadmap
Zukünftige Kandidaten:
Verkürzung der Latenz bei der Zustandsbewertung durch Wiederverwendung des OCR-Workers innerhalb der Sitzung
Erweiterung der Lock-Erkennungs-Fixtures um Variationen der macOS-Anzeigesprache, -auflösung und -hintergrundbilder
Strukturierte Audit-Ereignisse (ohne vertrauliche Informationen) für jedes Eingabe-Tool
Read-only Health-Tool zur Überprüfung des WebRTC-/DataChannel-Status ohne Eingabe
Start-Wrapper für Hermes Agent, der vertrauliche Informationen nicht direkt in Konfigurationsdateien speichert
Explizite Nicht-Ziele:
Nutzung von Developer Mode, eigener Firmware, Cloud/Remote Access
Bereitstellung von JetKVM-Konfigurationsänderungs-API, Terminal, Serieller Schnittstelle, Virtuellen Medien, Wake-on-LAN
Direkte Zeichenketteneingabe in japanische IMEs, automatische Wiederholungsversuche bei Authentifizierungsfehlern
Protokoll der Hardware-Überprüfung
2026-08-18 SCHRITT 1:
take_screenshot3 Mal,move_mouse2 Mal in derselben WebRTC-Sitzung ausgeführt.(100,100)→ HID(1708,3037),(1700,900)→ HID(29028,27331).Beide Male wurden der offizielle E2E-HID-Hook, HID ready, RPC DataChannel open und WebRTC connected bestätigt.
In
mouse-a.pngundmouse-b.pngwurde bestätigt, dass sich der PC1-Cursor zu zwei verschiedenen Punkten bewegt hat.Hardware-Aufrufe von click, double_click, scroll, press_key, hotkey, type_text: 0 Mal.
2026-08-18 SCHRITT 2:
take_screenshot2 Mal,move_mouse1 Mal, leftclick1 Mal in derselben WebRTC-Sitzung ausgeführt.(960,540)→ HID(16392,16399). Sowohl für move als auch click wurden der offizielle E2E-HID-Hook, HID ready, RPC DataChannel open und WebRTC connected bestätigt.Da auf einen sicheren Hintergrund des Sperrbildschirms geklickt wurde, gab es außer der Cursorbewegung keine Änderungen der PC1-Benutzeroberfläche.
Hardware-Aufrufe von double_click, right click, scroll, press_key, hotkey, type_text in SCHRITT 2: 0 Mal.
2026-08-18 SCHRITT 3:
take_screenshot2 Mal,press_key("Tab")1 Mal (jeweils 1 Mal down/up) in derselben WebRTC-Sitzung ausgeführt.Tab wurde über den offiziellen
sendKeypressE2E-HID-Hook (USB-HID Usage0x2b) gesendet. HID ready, RPC DataChannel open und WebRTC connected wurden bestätigt.In den Before/After-Bildern konnte keine eindeutige Fokusänderung auf dem Sperrbildschirm festgestellt werden. Hardware-Aufrufe von anderen Tasten als Tab, click, double_click, scroll, hotkey, type_text in SCHRITT 3: 0 Mal.
2026-08-18 SCHRITT 4:
take_screenshot3 Mal,type_text("abc")1 Mal,press_key("Backspace")3 Mal in derselben WebRTC-Sitzung ausgeführt.abcund Backspace wurden über den offiziellensendKeypressE2E-HID-Hook gesendet. HID ready, RPC DataChannel open und WebRTC connected wurden bei allen Eingaben bestätigt. Da Kleinbuchstaben eingegeben wurden, gab es 0 Mal Shift und 0 Mal Enter.Nach der Eingabe wurden im Passwortfeld Markierungen für drei Zeichen angezeigt, die nach 3 Mal Backspace alle verschwanden. Es gab keinen Übergang vom Sperrbildschirm und keine weiteren Aktionen.
2026-08-18 SCHRITT 5:
take_screenshot2 Mal,move_mouse(1400,700)1 Mal, leftdouble_click(1400,700)1 Mal in derselben WebRTC-Sitzung ausgeführt.Der Doppelklick wurde über den offiziellen
sendAbsMouseMoveE2E-HID-Hook gesendet, wobei der linke Button jeweils 2 Mal down/up gesendet wurde. HID ready, RPC DataChannel open und WebRTC connected wurden bestätigt.Die Aktion wurde an einer leeren Stelle auf dem Sperrbildschirm durchgeführt, ohne den Bildschirmzustand zu ändern. Es gab 0 einzelne Klicks und keine weiteren Eingaben.
2026-08-18 SCHRITT 6:
take_screenshot2 Mal,move_mouse(1150,540)1 Mal in den Textbereich einer Slack-Nachricht,scroll(0,500)1 Mal in derselben WebRTC-Sitzung ausgeführt.Das Scrollen wurde über den offiziellen Video-Wheel-Listener an den JetKVM-Wheel-RPC-Pfad gesendet, der normalisierte Wheel-Wert war
(0,-5). HID ready, RPC DataChannel open und WebRTC connected wurden bestätigt.In den Before/After-Bildern wurde bestätigt, dass sich der Slack-Nachrichtentext nach oben bewegt hat. Es gab 0 Klicks, Doppelklicks, Tastatur-Tools und keine weiteren Eingaben.
2026-08-18 SCHRITT 7 erster Versuch:
hotkey(["SHIFT","TAB"])wurde aufgrund eines Normalisierungsfehlers für den GroßbuchstabenTABvor dem HID-Dispatch gestoppt. 2 Screenshots, 0 HID-Eingaben an PC1, keine Bildschirmänderung.Eine Korrektur zur Normalisierung des
TAB-Alias aufTabund ein Unit-Test wurden hinzugefügt. Gemäß den Sicherheitsbedingungen wurde in diesem Durchgang kein erneuter Hardware-Test durchgeführt.2026-08-18 SCHRITT 7 erneuter Versuch:
take_screenshot2 Mal,hotkey(["SHIFT","TAB"])1 Mal in derselben WebRTC-Sitzung ausgeführt.Über den offiziellen
sendKeypressE2E-HID-Hook wurden nacheinander ShiftLeft down (0xe1), Tab down (0x2b), Tab up, ShiftLeft up gesendet. HID ready, RPC DataChannel open und WebRTC connected wurden bestätigt.PC1 wechselte von der Anzeige nur des Hintergrundbilds zur Anzeige des Sperrbildschirms. Es gab 0 andere Eingabe-Tools und keine weiteren Hardware-Eingaben.
This server cannot be installed
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
- Alicense-qualityDmaintenanceEnables 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.1MIT
- AlicenseAquality-maintenanceEnables 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.14237,6235
- Alicense-qualityDmaintenanceEnables AI to control a computer through mouse, keyboard, and screen capture tools, with support for local native and Docker sandboxed environments.115MIT
- AlicenseCqualityBmaintenanceExposes 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.40228Apache 2.0
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.
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/YokihitoOkiBiz/jetkvm-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server