kvm-pilot
kvm-pilot is a write-capable, gated MCP server that lets an agent see, decide, and act on physical machines through IP-KVMs, BMCs, Intel AMT, and SSH — with no agent on the target.
Sense the screen & boot phase —
snapshot(withframe_refstaleness guards),classify_screen,wait_for_state(bounded polling to a named boot phase), plus cheap gates like power/signal/OCR before invoking vision.Read device state —
info,healthcheck(readiness/recovery posture, CRITICAL findings),power_state,logs,events,boot_options,access_paths(independent recovery domains),list_virtual_media.Inspect the ecosystem —
capabilities(what the driver supports),support_matrix(per device+firmware+capability live evidence),firmware_check,doctrine(bundled playbooks),session(gates, approvals, act journal).Control power & boot —
power(on/off/off-hard/reset),set_boot_device,wake(Wake-on-LAN),ctrl_alt_delete, andamt_enablefor Intel AMT SOL/KVM listeners.Drive keyboard & mouse —
type_text,press_key,send_shortcut,mouse(click requires anobserved_frame_ref),calibrate_mouse.Manage virtual media —
mount_iso(local path or URL, CD or USB),eject.Act in-band over SSH —
ssh_reachable,ssh_exec,appliance_status,appliance_reboot(clear a wedged KVM encoder).Contribute evidence —
file_firmware_report(gated GitHub external write) andssh_discover(opted-in CIDR scan).Safety — every destructive effect is gated per class (READ_ONLY → DRY_RUN → per-effect
ALLOW_*) plus per-call approval with signed single-use receipts, dry-run short-circuits before prompting, and denials return typed outcomes.
Provides control of GL.iNet KVM devices (GLKVM, GL-RM1/GL-RM1PE) through the KVM plane, including screen snapshots, power management, keyboard/mouse input, and virtual media operations.
Provides out-of-band management of Intel AMT/vPro firmware, enabling power control, boot device selection, SOL console access, and screenshots of firmware screens (BIOS/POST/GRUB).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@kvm-pilot Take a KVM screenshot and tell me which boot phase the machine is in"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
kvm-pilot
Smart hands for your AI agents. A write-capable, multi-plane (KVM + BMC + SSH) MCP server for controlling physical machines — gated, verified, audited.
kvm-pilot lets an agent drive a headless box through POST, firmware, the
bootloader, and an OS install with no agent on the target: it works at the
pixel level through an IP-KVM (PiKVM, the GL.iNet GLKVM fork GL-RM1 /
GL-RM1PE, BliKVM), at the structured-state level through a BMC (Redfish on
iDRAC/iLO/OpenBMC, IPMI on BMCs that predate Redfish), at the firmware level
through Intel AMT/vPro (a BIOS/POST/GRUB screenshot + power + SOL on a
business laptop an HDMI-capture KVM can't see boot on), and over SSH once an OS
is up. A pluggable vision subsystem reads a KVM screenshot and tells you what
boot phase the machine is in — bios_menu, grub_menu, installer_progress,
login_prompt, crash_screen, and so on — and a safety layer gates every
destructive operation behind operator opt-ins and per-call approvals.
Vision runs on Claude or any local OpenAI-compatible VLM (LM Studio, Ollama, vLLM, llama.cpp). Point it at a model on your own GPU and the screenshots never leave your network and cost nothing per frame.
How it works
kvm-pilot runs a see → decide → act loop, and the screen is its only sensor:
it pulls a screenshot from the KVM, a vision model classifies the boot phase, and
kvm-pilot acts back through the KVM's keyboard and power. Because it works at the
pixel level, there is no agent on the target — the same loop drives POST,
firmware, the bootloader, and an OS install.
A real, unedited run against a GLKVM on the home fleet — an honest preflight, a headless snapshot (watch it wake the on-demand encoder), a gated dry-run power-cycle, and the boot console the agent actually saw:

Related MCP server: qemu-mcp-server
Quickstart
One install gives you the whole product — the kvm-pilot CLI, the
kvm-pilot-mcp MCP server, and the bundled Claude skill — nothing to
clone.
pip install kvm-pilot # CLI + skill + MCP server + WebSocket events
pip install "kvm-pilot[totp]" # + 2FA / TOTP support (pyotp)
kvm-pilot install-skill # optional: put the bundled skill where Claude Code loads itDriving a KVM from an AI agent (MCP)
claude mcp add kvm-pilot -s user \
-e KVM_PILOT_PROFILE=mykvm -e KVM_PILOT_MCP_READ_ONLY=1 -- \
kvm-pilot-mcpKVM_PILOT_MCP_READ_ONLY=1 is the recommended first rung of the trust ladder
— the agent can see everything and touch nothing until your hardware is
verified. The Getting started guide
covers credentials, Claude Desktop JSON config, sample prompts, and climbing
the ladder. The server is published to the official
MCP registry
as io.github.DustinTrap/kvm-pilot, so registry-aware hosts can discover
and install it by name. Agents: the repo root carries an
llms.txt doc map.
Scripting from Python
from kvm_pilot import KVMClient
from kvm_pilot.vision import ScreenAnalyzer, make_backend
kvm = KVMClient("192.168.8.1", "admin", "secret")
# Classify the current screen with Claude (model auto-resolved at runtime)
analyzer = ScreenAnalyzer(kvm, make_backend("anthropic"))
print(analyzer.classify().phase)
# Or run entirely on a local VLM — nothing leaves your network
local = make_backend("local", base_url="http://127.0.0.1:1234/v1", model="qwen2.5-vl-7b")
analyzer = ScreenAnalyzer(kvm, local)
# Block until the box reaches the GRUB menu, then pick the first entry
analyzer.wait_for_state("grub_menu", timeout=120)
kvm.press_key("Enter")For the latest unreleased tree:
pip install "kvm-pilot[totp] @ git+https://github.com/DustinTrap/kvm-pilot"CLI
kvm-pilot info --host 192.168.8.1 --user admin --ask-passwd # prompt (no echo)
kvm-pilot capabilities --profile homelab # what this driver supports
kvm-pilot snapshot screen.jpg --profile homelab
kvm-pilot --timeout 60 power-cycle --profile homelab --dry-run # log, don't send
kvm-pilot eject --profile homelab # detach virtual media
kvm-pilot events --profile homelab --count 5 # stream device events
kvm-pilot watch grub_menu --profile homelab \
--backend local --vision-url http://127.0.0.1:1234/v1 --vision-model qwen2.5-vl-7bThe CLI prompts for confirmation before any destructive action (power, virtual
media — including uploads — keyboard/mouse injection, GPIO). Use --yes to
skip prompts in automation, or --dry-run to log intended actions without
sending them — dry-run short-circuits before the prompt, so it never blocks
waiting for input. --timeout (HTTP per-request timeout) is a global flag and
goes before the subcommand; watch keeps its own --timeout for the vision
wait deadline.
Profiles like homelab live in ~/.config/kvm-pilot/config.toml. See
docs/cli.md for the full command table (every subcommand, the
capability it needs, and its gating), and
docs/configuration.md for the config-file format,
every KVM_PILOT_* environment variable, and the precedence between flags,
env, and profiles.
GLKVM setup note: on GL.iNet firmware the PiKVM REST API is disabled by default and a firmware upgrade can re-disable it — enable it first, per Every
/api/*call returns 404.
The tool surface, by plane
The same capability protocols span three actuation planes, so one agent workflow can mix pixels, structured BMC state, and shell access — with every destructive effect gated per class:
Plane | Read | Act (operator-gated) |
KVM — pixels & HID (PiKVM · GLKVM · BliKVM) |
|
|
BMC — structured state (Redfish · IPMI) |
|
|
Firmware — Intel AMT/vPro (spans both planes) |
|
|
SSH — in-band & appliance |
|
|
Meta — evidence & intake |
|
|
A machine with no KVM and no BMC at all is itself a first-class target:
driver = "ssh" plus ssh_host (the machine's own address, #248) stands
kvm-pilot on the recovery ladder's in-band rung — every device capability
honestly absent, and the healthcheck saying plainly that there is no
out-of-band recovery path there.
The canonical per-tool reference — annotations, effect gates, approval lifecycle — is the MCP server README; the CLI covers the full surface in docs/cli.md.
Status & maturity
Status: 1.0, general availability — on the strength of the run ledger, not beyond it. Three device types have run live (GL-RM1PE, Dell R710 over iDRAC6/IPMI, Dell Latitude 5411 over Intel AMT); three of the seven device drivers (
redfish,pikvm,blikvm) have only ever run against emulators. See the Hardware-Compatibility list for what has actually been exercised — and please add to it. (The exact version lives in the CHANGELOG.) The core paths have graduated from mocked-only to live-verified: a fleet of GL-RM1PE units has exercisedsnapshot/healthcheck/logs/power_state/virtual_media/infoacross two firmware lines — on V1.9.1 the run ledger that ships in the wheel putsinfo/logs/healthcheck/power_stateat ga,snapshotat rc, andvirtual_mediaat beta — derived from real runs, never hand-edited — and a Dell iDRAC6 has exercised the IPMI driver live end-to-end (power, boot-device, sensors, event log, SOL serial console). The paths that can hurt are hardened: transports never re-fire a destructive request, MCP approvals are signed single-use receipts with an audit trail, and every destructive effect — power, HID, media, boot-config, appliance, SSH, external writes — has its own operator opt-in gate. Recent betas added remote boot-device control (Redfish, IPMI, and in-bandefibootmgr), Wake-on-LAN, an IPMI driver for BMCs that predate Redfish, a serial (SOL) console, mouse auto-calibration, and headless native-resolution GLKVM snapshots;kvm-pilot test-reportturns contributing evidence into one command, and the firmware registry feeds itself (firmware-checkauto-files registry updates). Now we need your hardware. PiKVM, BliKVM, other GLKVM models, and Redfish BMCs (iDRAC/iLO/OpenBMC) are the combos the matrix needs most — success or failure, a hardware report takes two minutes and the hourly ingest does the rest. Anything the Hardware-Compatibility list doesn't show as exercised is still unverified: the 1.x line keeps the public API stable, but a rating only moves when a live run moves it; note the remote firmware-flash no-op on GL-RM1PE (#94/#95), and don't point destructive ops at a machine you can't afford to have power-cycled unexpectedly. See Compatibility.
Boot-phase detection
The vision classifier maps each screenshot to a phase — bios_menu,
grub_menu, installer_progress, login_prompt, crash_screen, and so on.
wait_for_state() polls the screen and blocks until the phase you asked for
appears (or a timeout fires), so an unattended install becomes a few waits with
actions wired between them:
Sensing model
Vision is the most expensive way to read a screen — a model call per frame — and
most of what it infers (power state, boot phase, liveness, a crash) is also
available as a field, an event, or a line of text. The direction of
kvm-pilot is to treat classification as a hierarchy: answer from the cheapest
signal the device exposes, and fall through to OCR and finally a vision model
only when nothing cheaper can.
The PiKVM/GLKVM client already exposes the cheap end — ATX and HID LEDs,
video-signal and resolution, on-device OCR (?ocr=true), logs, Prometheus
metrics, and a WebSocket event stream. The capability protocols
add Logs, BootProgress, Sensors, SerialConsole, Watchdog, and
BootConfig as the seam for BMC drivers (Redfish/IPMI), where the boot phase
is a structured enum (BootProgress.LastState) and the console is a serial
text stream rather than pixels. Different device classes are nearly
complementary: capture devices are strong on pixels, BMCs on structured state
and serial text.
Safety model
Power-offs, hard resets, virtual-media connect/disconnect and image uploads,
keyboard/mouse injection (type_text, press_key, shortcuts, clicks), GPIO,
boot-config changes, and Redfish/IPMI resets are classified as destructive
and pass through a safety layer:
dry-run short-circuits first: it logs the intended call and skips it entirely — the confirm callback is never invoked, so dry runs never prompt or block.
confirmation — a callback that can veto any destructive call that would really be sent. The library default allows everything (so plain scripts work); the CLI installs an interactive
y/Nprompt unless you pass--yes.
The destructive set is defined explicitly in kvm_pilot.safety.DESTRUCTIVE_OPS
so it is auditable rather than guessed. A vision classification can never
trigger a destructive action on its own — you wire that yourself, and the
safety layer still applies. On the MCP side each destructive effect class
additionally needs an operator opt-in env gate plus a per-call approval backed
by a signed single-use receipt — the trust ladder
(READ_ONLY → DRY_RUN → per-effect ALLOW_*) is drawn in the
MCP server README.
This software controls real hardware and can power-cycle or interrupt a running machine. Read SECURITY.md before exposing a KVM to the internet.
No hard-coded model version
There is no model version string anywhere in the code. The Anthropic backend
resolves the newest vision-capable model at runtime via the Models API and
caches it; set KVM_PILOT_VISION_MODEL or pass model= to pin one. The local
backend uses whatever model you loaded on your server. Bring your own backend,
endpoint, and model.
How this differs from other clients
pikvm-lib is a fine general-purpose
PiKVM client. kvm-pilot is aimed at a different job:
Vision-based boot-phase detection — classify BIOS/GRUB/installer/crash states from screenshots, with blocking
wait_for_stateloops. This is the core feature andpikvm-libhas no equivalent.Pluggable local or cloud VLM — run inference on your own GPU at zero per-frame cost, or on Claude.
A safety layer around destructive operations (dry-run + confirmation).
GLKVM-fork awareness — documents the API-enable prerequisite and GL hardware quirks that bite GL-RM1PE users.
Stdlib-only client core — the driver/vision code imports only the standard library (the bundled MCP server pulls the
mcpSDK; feature extras are opt-in).
If you just want to script power and HID against a stock PiKVM and don't need
the vision layer, pikvm-lib may be the simpler choice.
On the BMC side, sushy, DMTF's
python-redfish-library, and
pyghmi (IPMI) are mature, far more complete BMC
management SDKs — if you need account/firmware/network configuration,
EventService subscriptions, or hardware-proven maturity, use them. kvm-pilot
trades that completeness for one uniform capability surface across device
classes (IP-KVMs and BMCs behind the same protocols), the same safety layer
gating every destructive call, and the vision loop on devices that have pixels.
Compatibility
Device | Status |
GL-RM1PE (Comet PoE) | Primary target — exercised live: read/ |
Dell iDRAC6 — IPMI (PowerEdge R710) | Exercised live: power / boot-device / sensors / event log (SEL) / SOL serial console all verified over |
Dell Latitude 5411 — Intel AMT/vPro | Exercised live (AMT 14.1.67): WS-Man power / info / single-use boot, remote SOL + KVM enablement, and a 1920×1080 BIOS/POST screenshot over KVM redirection — the firmware screen an HDMI-capture KVM can't see on a laptop. Captures graphical screens only (not legacy VGA text mode) |
GL-RM1 (Comet) | Expected to work (same firmware family); untested |
PiKVM v3 / v4 | Expected to work (upstream API); untested |
BliKVM | Expected to work (PiKVM-compatible API); untested |
Redfish BMCs (iDRAC7+, iLO, OpenBMC) | Emulator-verified (in-repo emulator + DMTF sushy-tools in CI); live-BMC validation pending (#29) |
The GL-RM1PE (read/snapshot paths), a Dell iDRAC6 over IPMI, and a Dell Latitude 5411 over Intel AMT are the combos run live so far — everything else is "expected to work" pending validation. The Hardware-Compatibility list is the authoritative, per-capability record. ATX power control needs the ATX adapter wired to the target's front-panel header: on the GL Comet family (GL-RM1 / GL-RM1PE) that is GL.iNet's separately sold ATX board (GL-ATXPC), while PiKVM v3/v4 kits include the ATX adapter in the box and BliKVM bundles vary by model — check yours. Without ATX wiring, ATX calls return errors from the device. Reports of success or failure on any hardware are exactly what this project needs — please open a hardware report.
Architecture
kvm-pilot is built on a modular, driver-plugin architecture so support can
expand to many KVM/BMC devices (PiKVM family, Redfish BMCs, IPMI BMCs, JetKVM, …).
Each device implements only the capability protocols its hardware supports; the
CLI, safety layer, and vision subsystem stay device-agnostic. A make_driver(kind)
registry (mirroring make_backend) builds drivers by name, and a hardware-free
FakeDriver lets you exercise the whole loop — capabilities, safety gating, the
analyzer — with no device (kvm-pilot capabilities --driver fake). See
docs/architecture.md for the design and diagram.
A RedfishDriver (make_driver("redfish")) speaks the DMTF Redfish API to
server BMCs — Dell iDRAC, HPE iLO, Supermicro, Lenovo XCC, OpenBMC — in one
stdlib-only client. It shows why capabilities are segmented: a BMC's set is
complementary to a PiKVM's (strong on structured state — power, boot phase,
sensors, logs, virtual media — with no keyboard/mouse/screenshot), and the driver
stays portable by following Redfish hypermedia rather than hard-coding vendor ids:
from kvm_pilot.drivers import make_driver
bmc = make_driver("redfish", host="idrac.lan", user="root", passwd="…")
bmc.get_boot_progress() # 'os_running' — structured, no screenshot
bmc.read_sensors()["temperatures"]
bmc.power_off(wait=True) # mapped to the target's actual ResetType, gatedAn IpmiDriver (make_driver("ipmi")) covers BMCs that predate Redfish
(e.g. Dell iDRAC6) over the system ipmitool: power, boot-device control,
sensors, the SEL event log, and an SOL serial console (kvm-pilot console).
Both are on the CLI too — kvm-pilot info --driver redfish --host idrac.lan ….
Capability-specific subcommands a BMC can't serve (type, snapshot, events)
fail cleanly rather than crashing. Add --redfish-auth basic for an endpoint
without a SessionService (emulators, or a BMC with session auth disabled).
An AmtDriver (make_driver("amt")) manages Intel AMT/vPro laptops and
desktops out-of-band over AMT's three native protocols — WS-Man (power / info /
single-use boot), SOL (kvm-pilot console), and KVM redirection — all
pure-stdlib. It is the first non-PiKVM driver with Video + HID: snapshot
returns a real firmware-level BIOS/POST/GRUB screenshot on a machine whose
HDMI a capture-KVM can't see boot on a laptop. SOL and KVM listeners are opened
remotely over WS-Man (kvm-pilot amt enable-sol / enable-kvm), no MEBx trip.
Help shape it — this is where you come in
kvm-pilot is built in the open. 1.0 shipped on the evidence of three device
types; what it still needs is not code — it's breadth of real hardware.
Three of the seven drivers
(redfish, pikvm, blikvm) have never run against a physical device, only
emulators. Every rating you see is derived from a run ledger that ships inside
the wheel, never hand-set, so the matrix only grows when someone runs it on real
metal. That someone could be you.
The single most valuable thing you can send: a
hardware report.
kvm-pilot test-report --profile <name> turns it into one command, it is
read-only by default, and an hourly job folds the result into the published
compatibility matrix. Failures are as welcome as successes — a driver that
returns a confident wrong answer on your BMC is a more useful report than one
that works, and it will be treated as a first-class finding, not swept up.
Also genuinely wanted:
⭐ Star the repo if the idea is useful to you. It is the cheapest signal that this problem is worth solving, and it is what brings in the operators whose hardware the matrix still needs.
🐛 Open an issue for anything: a bug, a device that misbehaves, a confusing error, a doc that lied to you. This repo is issue-per-finding — an issue is the unit of record, and "the error message didn't tell me what to do" is a legitimate report.
💬 Tell us what it got wrong. Review the safety model, the approval flow, the tool surface. Push back on the defaults. If an agent did something with your machine that surprised you, that is exactly the feedback that makes this safe for everyone else.
🔌 Ask for your device. Missing driver, unsupported BMC, a KVM we've never heard of? Open a driver request — the plugin architecture exists precisely so that adding one doesn't mean forking the project, and
docs/plugin-development.mdis the contract.🛠️ Send a PR.
docs/CONTRIBUTING.mdhas the full pre-PR checklist; good first issues are labelled.
Nothing here phones home. The project has no telemetry that reports itself — every row in the compatibility matrix is there because a human chose to send it. That's the deal, and it's why your report actually matters.
Documentation
Full user and developer docs live in docs/ (architecture, design
decisions, the Redfish reference, the
troubleshooting & FAQ,
contributing, and the security policy). The
project wiki is an
auto-generated, nicely formatted mirror of that folder, and the repo root
carries an llms.txt
doc map for AI agents.
License
Apache License 2.0 — see LICENSE and NOTICE. kvm-pilot is
independent and not affiliated with or endorsed by the PiKVM project, GL.iNet,
or Anthropic; those names are used only for compatibility description.
Available Tools
34 toolsaccess_pathsARead-onlyIdempotent
Which INDEPENDENT recovery paths are live for the device — the lockout view.
Rolls up the REST API, appliance-SSH, target-SSH, out-of-band power, and
console-HID paths, each labeled by its failure domain so redundancy is not
oversold: several live paths that all ride the same appliance are ONE
independent domain. summary.out_of_band_live=false means every path shares
the appliance's fate — a fully hung box can't be recovered remotely.
summary.out_of_band is live, down (the path exists but management
access to its plane failed — restore it) or none (no such path).
Inputs: profile.
amt_enableADestructive
Enable an Intel AMT redirection listener over WS-Man (Intel AMT/vPro only). CONFIG MUTATION.
feature='sol' opens the SOL/IDE-R listener (16994); feature='kvm' opens
KVM redirection (5900) and sets the RFB password. Gated by the config effect
gate + per-invocation approval (typed same-path denials, #234).
consent_off=true (KVM only) DISABLES the on-screen user-consent prompt —
a surveillance escalation — and additionally requires the dedicated
KVM_PILOT_MCP_ALLOW_CONSENT_OFF operator gate (see README.md); leaving
it false keeps the prompt.
Inputs: feature (required), confirm, profile, consent_off.
appliance_rebootADestructive
Reboot the KVM APPLIANCE (not the target) to clear a wedged encoder. DESTRUCTIVE.
Recovers the RV1126 encoder wedge (the only fix — the stuck threads are unkillable kernel threads). Drops all KVM control for ~60s; the target's power is untouched. Gated by the appliance effect gate + per-invocation approval, with typed same-path denials (#234). There is no out-of-band power to the appliance, so use this deliberately, never in an automated loop.
Inputs: confirm, profile.
appliance_statusARead-onlyIdempotent
Read-only diagnostics from the KVM APPLIANCE's own OS over SSH.
Targets the KVM appliance itself (its appliance_ssh channel), NOT the
managed target. Reports the 1-minute load and the RV1126 video-pipeline threads
in D-state. NOTE: on these units load sits at ~10 even when perfectly idle
(the driver parks those threads in D-state), so it is NOT a health signal on
its own — use the healthcheck encoder-wedge finding for the real tell.
Inputs: profile.
boot_optionsARead-onlyIdempotent
Show the host's current boot override (Redfish BootSourceOverride) — read-only.
Reports enabled (Disabled/Once/Continuous), the normalized target, the
mode (UEFI/Legacy, or null if the BMC doesn't expose it), and the
allowable targets the BMC advertises — so an actuator knows what
set_boot_device values this box will accept before trying one.
Inputs: profile.
calibrate_mouseAIdempotent
Measure and store this host's mouse commanded→observed correction (#128).
Fixes "clicks where the button should be and misses". Pointer moves only —
no clicks, no keystrokes — but it visibly moves the live cursor ~10-30s,
so it is gated like HID input (KVM_PILOT_MCP_ALLOW_HID; one approval
covers the whole run). Preconditions: live video signal, a static
screen, and a visible cursor. Afterwards mouse percent
coords apply it transparently (calibrated: true); stored per (host,
capture resolution) — a resolution change makes it stale, never applied.
Mechanism details: the MCP server README.
Inputs: confirm, profile, tolerance.
capabilitiesARead-onlyIdempotent
List the capabilities the target's driver supports (read-only, offline).
Structural — makes no network call and runs no preflight; it answers "which
tools/actions can this device serve?" so you can pick the right interface up
front (a Redfish BMC has no video; a PiKVM has no BootProgress). Returned in
the capability enum's declaration order for stable output. video_scope
answers the question video cannot — whether BIOS/POST/GRUB are visible
through this interface (an HDMI-capture KVM is blind below the OS on a
laptop; AMT/BMC firmware video is not). live_evidence
additionally names which device+firmware combos this driver has real-hardware
run evidence for — structural support is not live verification; call
support_matrix for per-combo evidence and healthcheck for this exact
device+firmware.
Inputs: profile.
classify_screenARead-onlyIdempotent
Classify the current screen's boot/run phase (read-only).
Uses the server-side vision backend when configured; cheap on-device gates (power-off, no-signal, boot-progress, OCR rules) resolve with no credentials at all. Return shapes:
server-side / cheap-gate → a dict with
mode="server"+ phase fields.no server vision → caller-side fallback, a
[json_text, Image]list: classify the image yourself against thesystem_prompt/phasesin the JSON block.
Inputs: hint, profile.
ctrl_alt_deleteADestructive
Send Ctrl+Alt+Del to the managed host over the keyboard. DESTRUCTIVE (reboot).
A reboot (or the OS's secure-attention screen) delivered through HID, so it
is classified power_soft and needs KVM_PILOT_MCP_ALLOW_POWER — the
power tool's gate — never the weaker HID gate. Prefer
power(action='reset') when the device has out-of-band power: that is
verifiable, this chord is not (a hung host simply ignores it). Returns the
typed act outcome; confirm with wait_for_state or snapshot.
Inputs: confirm, profile.
doctrineARead-onlyIdempotent
Re-serve the bundled operating doctrine (read-only; offline, no device I/O).
The skill's playbooks ship inside this package; this tool re-serves them so
a session that never loaded the skill file — or has long since compacted it
away — can re-anchor on the written doctrine instead of a faded memory of
it. Call with no topic to list the topics; call with one for that
playbook's full text. Read recovery the moment a host goes dark or a
snapshot fails, and interfaces before picking how to do an action you
haven't done this session.
Inputs: topic.
ejectAIdempotent
Detach the virtual media presented to the host (inverse of mount_iso). GATED, reversible.
Needs KVM_PILOT_MCP_ALLOW_MEDIA + per-invocation approval. With nothing
attached it returns detached=false and says so — not an error. Touches
neither power nor the boot order: a host running from the ISO keeps running
until it reboots; on BMCs, set_boot_device picks what boots next.
Returns the typed act outcome.
Inputs: confirm, profile.
eventsARead-onlyIdempotent
Collect typed device events from the kvmd stream (read-only, bounded).
MCP twin of CLI events minus follow mode (#233 — an endless stream
doesn't fit the synchronous stdio transport): returns up to count
events or duration seconds' worth (capped 30 s), whichever first.
logs is the better first diagnostic; events add the live typed stream
(atx/msd/streamer state changes) to cross-check a vision wait against.
Inputs: count, profile, duration.
file_firmware_reportAIdempotent
File the device's firmware-currency report as a GitHub issue when the
registry is behind (MCP twin of CLI firmware-check, #189/#190).
EXTERNAL WRITE — writes outside the managed device.
The read/reconcile half always runs; registry current → nothing to file,
the result says so. Filing is gated as its own external_write effect
(KVM_PILOT_MCP_ALLOW_EXTERNAL_WRITE + per-invocation approval);
dry_run=true previews the exact issue title/body; a missing or
unauthenticated gh is a graceful filed=false reason.
Inputs: repo, source, confirm, dry_run, +1 more.
firmware_checkARead-onlyIdempotent
Report the device's firmware currency vs the bundled registry (read-only).
The read half of file_firmware_report (#233): reconciles the device's
reported firmware/update state against the registry SSoT and says whether
the registry is behind — nothing is filed, no gate is consulted. When
registry_behind is true, file_firmware_report contributes the
report (gated external write).
Inputs: profile.
healthcheckARead-onlyIdempotent
Audit the device's readiness/recovery, security posture, and firmware (#80).
Read-only. Returns per-check findings with a tiered severity; a CRITICAL
(e.g. no out-of-band reset path) is what should gate a subsequent destructive
op. The most valuable finding is recovery-path — whether a hung guest can
be reset at all when the KVM is remote. Served through the preflight cache
(#225): stable posture may come from the last assessment, and a firmware
change since then adds a firmware-delta finding of what cleared/regressed.
Inputs: profile.
infoARead-onlyIdempotent
Identify the device and the system behind it (read-only).
Returns host/driver plus the driver's info block: model, vendor,
firmware and hardware detail as the device reports them (a PiKVM/GLKVM
describes the appliance; a BMC describes itself and the managed system).
Use it to confirm what you are talking to. It says nothing about whether
the device is safe to act on (healthcheck), what it can do
(capabilities), or the host's power (power_state).
Inputs: profile.
list_virtual_mediaARead-onlyIdempotent
Inventory the KVM's virtual-media (MSD) storage (read-only).
Check this BEFORE asking the operator to download or upload an ISO — the
image may already be on the device (#127). Returns stored images, the
selected image, and attach state (online). host_visible_as (when
known, #78) is the device name the TARGET's boot menu shows for truly
presented media — match it to pick the right boot entry and to confirm the
medium is really inserted. Details: doctrine topic 'interfaces'.
Inputs: profile.
logsARead-onlyIdempotent
Return the device/host event log as text (read-only).
seek is seconds of lookback (0 = the whole buffer). This is the go-to
diagnostic when video/streamer/encoder or power behaviour looks wrong: the
text log names a fault (e.g. a stuck encoder behind a snapshot 503) that
a screenshot cannot. Tail-follow is intentionally not exposed — it blocks
over the server's synchronous transport.
Inputs: seek, profile.
mount_isoAIdempotent
Mount an ISO as virtual media on the host. GATED act (media effect gate); reversible.
source is a local path or an http(s):// URL; usb=true attaches as a
USB flash drive instead of a CD-ROM. Needs KVM_PILOT_MCP_ALLOW_MEDIA +
per-invocation approval. Mounting bumps the frame generation, so a mouse click
planned against the pre-mount screen is invalidated.
Inputs: source (required), usb, name, confirm, +1 more.
mouseADestructive
Move the mouse (and optionally click) on the host. DESTRUCTIVE (HID input).
A click must carry the observed_frame_ref it was planned against
(from a prior snapshot); it is refused — re-snapshot and retry — if
the host rebooted/swapped media since, the observation is older than
KVM_PILOT_MCP_FRAME_MAX_AGE (60s default, #141), or the ref wasn't
issued by this server. Move-only (button omitted) needs no ref.
coord_space: percent (0.0-1.0, default — survives resolution
changes), pixel, or raw kvmd. Gated by KVM_PILOT_MCP_ALLOW_HID
per-invocation approval.
Inputs: x (required), y (required), button, confirm, +3 more.
powerADestructive
Change host power state. DESTRUCTIVE.
Gated by the power effect gate + per-invocation approval (elicitation, or
confirm=true under standing policy); denials come back through the same
path with a typed outcome (#234). The result carries an honest effect
report (#168): verified is true/false when the driver has a trustworthy
power signal (Redfish PowerState, a wired ATX LED), and null — with the
reason and what to do instead — when it doesn't. A power action also
invalidates prior snapshot frame refs (generation bump), so a stale
mouse click can't land on the post-reboot screen.
Inputs: action (required), confirm, profile.
power_stateARead-onlyIdempotent
Report whether the managed host is powered on (read-only).
Returns powered_on (bool) plus, on PiKVM-family devices, atx (the
power/HDD LEDs and button states); BMC/AMT drivers answer from the
controller's power state. The cheap check after power/wake when
their verified came back null, and before deciding whether a dark
snapshot means off or asleep. Changes nothing: to change power use
power, to wake a sleeping host use wake.
Inputs: profile.
press_keyADestructive
Press and release one key on the managed host's console. DESTRUCTIVE (HID).
For a single non-text key: Enter to submit, Escape, F2/F12
at POST, arrows and Tab in firmware menus. For a chord use
send_shortcut; for words use type_text; for Ctrl+Alt+Del use
ctrl_alt_delete (power gate). Nothing echoes back — snapshot after.
Same gating as type_text: KVM_PILOT_MCP_ALLOW_HID + per-invocation
approval. Returns the typed act outcome (receipt, or the denial reason).
Inputs: key (required), confirm, profile.
send_shortcutADestructive
Send a key chord — comma-separated kvmd key codes, e.g.
ControlLeft,AltLeft,Delete or ControlLeft,AltLeft,F2. DESTRUCTIVE.
Gated by effect, not transport: a reboot/power chord (Ctrl+Alt+Del, Magic
SysRq) is classified power_soft/power_hard and needs
KVM_PILOT_MCP_ALLOW_POWER; an ordinary session chord is hid_control and
needs KVM_PILOT_MCP_ALLOW_HID — so a reboot can't slip through the HID gate.
Inputs: keys (required), confirm, profile.
sessionARead-onlyIdempotent
Report this server's current operating posture (read-only; offline, no device I/O — answers even when the device is down).
Call this after a context compaction, when resuming a long flow, or before
planning act calls: it names the target, dry-run/read-only state, which
effect gates are open (by class name only — opening one is operator-only,
out of band), the approval posture, any live standing approvals (#192) with
their scope and time left, the recent act journal, and the last
wait_for_state result for the target. All journal/wait state is
in-memory: a server restart empties it (and voids receipts and frame refs),
so an empty journal after a restart is expected, not evidence nothing
happened. Pair with healthcheck for device health and doctrine for
the operating playbooks.
Inputs: profile.
set_boot_deviceADestructive
Set the next-boot (or persistent) boot device via BootSourceOverride. CONFIG MUTATION.
Gated by the config effect gate + per-invocation approval; denials come
back through the same path with a typed outcome (#234). none clears
the override; once=false makes it persistent; uefi=false selects
legacy BIOS mode where the target exposes it. A target the BMC doesn't
advertise fails fast (call boot_options first to see allowable).
Inputs: device (required), once, uefi, confirm, +1 more.
snapshotARead-onlyIdempotent
Capture the current KVM screen (read-only).
Returns [json_text, image]: the JSON carries a frame_ref
(host:generation:hash) — pass it back to the mouse tool as
observed_frame_ref so an absolute click can be refused if the host rebooted
or swapped media since you looked.
It also carries the live signal state (online/resolution/fps/format,
#143) and unchanged_since_last_snapshot (#141): a byte-identical frame
when the screen should have changed means the pixels are stale/cached — do
NOT trust them as ground truth; check signal and logs instead.
Inputs: profile.
ssh_discoverARead-onlyIdempotent
Scan a CIDR for hosts with an open SSH port. RISKY — opt-in.
An active network scan: noisy, and only acceptable on networks the user owns or
is authorized to probe. Use it ONLY to help find a target whose address the user
doesn't know, after they confirm the range — never by default. confirm=true
is required to acknowledge the scan.
Inputs: cidr (required), port, confirm.
ssh_execADestructive
Run a command on the managed host's OS over SSH. DESTRUCTIVE / in-band.
Gated by its own SSH effect gate (never the HID gate) + per-invocation
approval, with typed same-path denials (#234). host overrides the
profile/env ssh_host at runtime (e.g. a discovered install-time DHCP
address).
Inputs: command (required), host, confirm, profile.
ssh_reachableARead-onlyIdempotent
Is the managed host's OS reachable over SSH? (read-only, in-band).
Targets the host behind the KVM (its own ssh_host / KVM_PILOT_SSH_HOST),
a different machine from the KVM appliance. Use this to prefer remote recovery
before asking a user to physically intervene.
host overrides the profile/env ssh_host at runtime — e.g. an install-time
DHCP address the profile can't know until the target boots.
Inputs: host, profile.
support_matrixARead-onlyIdempotent
What has actually been exercised on real hardware, per device+firmware+capability (read-only, offline — no device call).
Aggregated from the test-run ledger shipped in the package (the same data
behind the wiki Hardware-Compatibility page), with each combo's derived
maturity level (#98) joined from the shipped firmware registry. This is
EVIDENCE, not a guarantee: a capability listed in never_exercised (or a
combo with no row at all) is unverified on that hardware — treat it as
mock-only/alpha maturity and confirm destructive steps with the user.
status is "fail" when every recorded live attempt failed (e.g. RM1PE
V1.5.1 firmware_update, #94/#95). Filters are case-insensitive; product
matches as a substring.
Inputs: vendor, product, firmware_version.
type_textADestructive
Type a string on the managed host's console over the HID keyboard. DESTRUCTIVE.
For printable text (commands, installer fields, passwords); nothing echoes
back and no Enter is appended — press_key('Enter') to submit. Keys that
aren't text go through press_key; chords through send_shortcut.
Keystrokes land wherever the host's focus is: snapshot first to confirm
the screen, and after to see the effect. Needs KVM_PILOT_MCP_ALLOW_HID
per-invocation approval (elicitation, or
confirm=trueunder standing policy). Returns the typed act outcome (receipt, or the denial reason).
Inputs: text (required), confirm, profile.
wait_for_stateARead-only
Wait (bounded) until the screen reaches a boot/run phase (read-only).
Server-side twin of CLI watch: polls cheap power/signal/boot-progress
gates, then server-side vision, until phase (a classify_screen token;
unknown tokens fail fast with the valid list) is observed. timeout is
seconds, capped server-side at 300 — chain calls for longer waits. Success
returns phase/confidence plus a frame_ref to pass to mouse as
observed_frame_ref; a timeout returns reached=false with the last
observed state (never a hang, never a raised error). With no server-side
vision credentials only cheap-gate phases are waitable; others fail fast
pointing at classify_screen polling. Holds the driver open up to
timeout s. Details: doctrine topic 'interfaces'.
Inputs: phase (required), hint, profile, timeout.
wakeADestructive
Send a Wake-on-LAN magic packet to power the host on. POWER (soft).
Gated by the power effect gate + per-invocation approval (typed same-path
denials, #234). mac defaults to the profile's mac; broadcast to
its wol_broadcast. No KVM driver is contacted — WoL is a broadcast sent
from the server's own host onto the target's L2 segment.
Inputs: mac, count, confirm, profile, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 34 tools
Tools mostly occupy distinct resource/action slots: power vs wake vs ctrl_alt_delete vs appliance_reboot are clearly separated, and screen/log diagnostics are explained by purpose. Some read-only meta tools (healthcheck/support_matrix/capabilities/session) and logs/events require careful reading, but descriptions provide boundaries.
All names are snake_case, but the set mixes noun-only names (info, logs, snapshot, power, events) with verb_noun names (set_boot_device, mount_iso, wait_for_state). It remains readable and domain-predictable, though not a single consistent pattern.
34 tools is above the 25-tool threshold and a lot for an agent to navigate; while many are specialized safety/diagnostic operations, several meta/diagnostic tools could be consolidated. The scope is broad, but the surface feels heavy.
Covers identification, health/capabilities, power, boot override, screen/HID, virtual media, SSH, appliance recovery, logs/events, firmware currency, and external report filing. Minor gaps remain (e.g., no firmware update action, no AMT disable, limited appliance lifecycle), but core operational workflows are present.
Maintenance
Related MCP Connectors
MCP server for building and testing AI agents with multi-model experimentation and insights.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
Related MCP Servers
- AlicenseCqualityDmaintenanceThis MCP server connects AI agents to a PiKVM device, enabling full keyboard, mouse, and screen control of a physical machine without emulation.285GPL 3.0
- AlicenseNot gradedqualityCmaintenanceAn MCP server that gives AI agents direct control over QEMU virtual machines.31 npm1MIT
- AlicenseNot gradedqualityCmaintenanceMCP 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.21MIT
- FlicenseAqualityDmaintenanceMCP server for controlling Sipeed NanoKVM devices, enabling remote hardware control via keyboard, mouse, power, and screenshots. It allows AI assistants like Claude to manage headless machines at the BIOS level.20-