Skip to content
github-actions[bot] edited this page Jul 1, 2026 · 16 revisions

name: kvm-pilot description: >- AI-driven bare-metal control of PiKVM and GL.iNet GLKVM devices (GL-RM1 / GL-RM1PE). Use whenever the user wants to remotely operate a headless server or workstation through a KVM — power on/off/cycle, mount an install ISO, enter BIOS/UEFI, type at a console, or watch the screen to detect boot phase (POST, GRUB, installer, login, crash). Backed by the kvm-pilot Python package; vision runs on Claude or a local OpenAI-compatible VLM. Early alpha, never validated on real hardware — treat every operation as unverified and confirm destructive steps with the user.

kvm-pilot skill

⚠️ Untested alpha. kvm-pilot has never been run against real hardware — it is unit-tested with mocks only. Treat every result as unverified, expect bugs, and never point a destructive operation (power, reset, media, keystrokes) at a machine the user can't afford to have power-cycled unexpectedly. Surface each destructive step to the user before executing it.

This skill is a thin wrapper over the installable kvm-pilot package. The code lives in the package, not here — install it and import it rather than copying client logic into a script.

Setup

pip install kvm-pilot==0.1.0a1            # core, stdlib-only
pip install "kvm-pilot[totp]==0.1.0a1"    # if the device has 2FA enabled

0.1.0a1 is an untested early alpha and is yanked on PyPI (opt-in only), so pin the exact version — a bare pip install kvm-pilot installs nothing. It also predates the newer drivers and CLI (make_driver, the GLKVM/BliKVM/Redfish/fake drivers, capabilities/events/eject); for those, install the current tree instead:

pip install "kvm-pilot[totp,ws] @ git+https://github.com/DustinTrap/kvm-pilot"

Credentials resolve from KVM_PILOT_HOST / KVM_PILOT_USER / KVM_PILOT_PASSWD (or a --profile in ~/.config/kvm-pilot/config.toml — full reference: docs/configuration.md). For Claude vision set ANTHROPIC_API_KEY; for a local VLM, point at its /v1 URL and model.

GLKVM devices: the PiKVM REST API is disabled by default on GL firmware. The user must enable it in /etc/kvmd/nginx-kvmd.conf on the device first, or every call returns 404. A firmware upgrade can revert it.

Use the library, not raw HTTP

First contact: rehearse with dry_run=True. Dry-run short-circuits before anything else — destructive calls are logged and skipped (the confirm callback is never invoked), so the whole flow can be validated without changing the machine's state:

from kvm_pilot import KVMClient

kvm = KVMClient("192.168.8.1", "admin", "secret", dry_run=True)
kvm.mount_iso("https://example.com/distro.iso")   # logged, not sent
kvm.hard_cycle()                                  # logged, not sent

Real run: gate every destructive step on explicit approval. interactive_confirm prompts on stdin and fails closed (denies) when there is no TTY. In an agent context, ask the user in chat before each destructive step and wire their answer into the callback:

from kvm_pilot import KVMClient
from kvm_pilot.safety import interactive_confirm
from kvm_pilot.vision import ScreenAnalyzer, make_backend

kvm = KVMClient("192.168.8.1", "admin", "secret", confirm=interactive_confirm)
analyzer = ScreenAnalyzer(kvm, make_backend("anthropic"))   # or "local"

kvm.mount_iso("https://example.com/distro.iso")   # gate: asks before mounting
kvm.hard_cycle()                                  # gate: asks before power off/on
analyzer.wait_for_state("grub_menu", timeout=120)
kvm.press_key("Enter")                            # keystroke injection is gated too
analyzer.wait_for_state("installer_complete", timeout=1800)

Never pass an allow-all confirm callback (e.g. lambda op, d: True) unless the user has explicitly approved unattended destructive operation in this session. And note that omitting confirm is also unattended — the library default allows everything so plain scripts work — so actively pass interactive_confirm (or a callback that relays the question to the user); the ask-first duty sits with you, not the library.

Safety

Destructive operations — power off/reset, virtual-media connect/disconnect and image uploads, keyboard/mouse injection (type_text, press_key, shortcuts, clicks), GPIO, Redfish resets — are gated by SafetyPolicy (kvm_pilot.safety.DESTRUCTIVE_OPS is the explicit, auditable set):

  • dry_run=True short-circuits first: the call is logged and skipped and the confirm callback is never invoked, so dry runs never prompt or block.
  • The confirm callback runs only for calls that would really be sent; returning False blocks the call with SafetyError.

When acting on a user's real hardware — which, again, this package has never been validated against — confirm each destructive step with the user first unless they have explicitly said otherwise.

CLI

kvm-pilot info | capabilities | snapshot | power | power-cycle | type | key | mount | eject | classify | watch | events. --dry-run logs destructive actions without sending them (it short-circuits before any prompt, so it is safe in automation); --yes skips the interactive y/N confirmation on a real run. See kvm-pilot --help.

Worked examples

In the repository (the examples/ directory is not shipped inside the pip package):

All three default to the safe path (dry run and/or interactive confirmation); copy that pattern, not an allow-all one.

Clone this wiki locally