kvmctl is a Go CLI and MCP server for KVMD-compatible KVM devices such as GLKVM. It provides a verified KVMD REST client plus safe, agent-friendly workflows for device status, screenshots, HID control, target selection, recovery, OCR-assisted actions, and immutable workflows.
Status: live-verified against KVMD 4.82. Read-only API and capability checks were exercised against a real device. Mutating hardware actions remain explicitly gated and were not used during acceptance.
Configure authentication
KVMD credentials are supplied through the environment or the CLI's private credential store. Never commit credentials or put them in a shell history.
export KVMCTL_KVMD_TOKEN="<your-kvmd-token>"
kvmctl-pp-cli doctor --json
The persisted form is private to the local user:
printf '%s\n' "$KVMCTL_KVMD_TOKEN" | kvmctl-pp-cli auth set-token
kvmctl-pp-cli doctor --json
The token is stored in credentials.toml under the resolved data directory, not in config.toml.
Quick start
Start with read-only checks:
kvmctl-pp-cli doctor --json
kvmctl-pp-cli capabilities --json
kvmctl-pp-cli info --json
kvmctl-pp-cli hid get-state --json
Use agent mode when invoking from an automation tool:
kvmctl-pp-cli info --agent
kvmctl-pp-cli semantic capabilities --agent
The live acceptance probe confirmed an authenticated KVMD device, its capabilities, and online keyboard/mouse HID state. The probe did not send keyboard or mouse input.
Safety model
- Read-only status, capability, screenshot, and inspection commands can run normally.
- Commands that can affect a KVM, host, target, or workflow require explicit confirmation and/or write policy.
--agent selects machine-readable output; it does not imply --yes.
- Use
--dry-run --agent before an unfamiliar mutating command.
- Do not use reboot, target switching, OTG, HID input, or workflow execution against production hardware without identifying the target and reviewing the command's help.
- OCR commands require real image bytes. The CLI never invents screenshots, OCR text, coordinates, or hardware results.
Example dry run:
kvmctl-pp-cli semantic send-key --key Enter --dry-run --agent
Core capabilities
KVMD API and device state
kvmctl-pp-cli capabilities --json
kvmctl-pp-cli info --json
kvmctl-pp-cli status --json
kvmctl-pp-cli screenshot --output ./screen.jpg
kvmctl-pp-cli hid get-state --json
Keyboard and mouse
kvmctl-pp-cli keyboard --help
kvmctl-pp-cli mouse --help
kvmctl-pp-cli hid send-key --help
These commands are write operations. Review the help, identify the target, and pass --yes only when the input is intentional.
Semantic operations
The semantic surface exposes the Python oracle's operation catalog through stable evidence envelopes. Discover the available operations and their read/write policy at runtime:
kvmctl-pp-cli semantic capabilities --agent
kvmctl-pp-cli semantic snapshot --agent
kvmctl-pp-cli semantic verify --agent
kvmctl-pp-cli semantic host-identity --agent
The MCP server exposes the same structured semantic_dispatch surface for agents.
Immutable workflows
Workflows are loaded from JSON, listed deterministically, inspected with action values redacted, authorized once, and then executed only against the resolved target and revision.
kvmctl-pp-cli workflow-list --repository ./workflows.json --agent
kvmctl-pp-cli workflow-inspect --repository ./workflows.json --name safe-check --agent
kvmctl-pp-cli workflow-authorize --repository ./workflows.json --name safe-check --target <target> --agent
kvmctl-pp-cli workflow-execute --repository ./workflows.json --name safe-check --target <target> --yes --agent
Keep workflow files free of passwords, tokens, private URLs, and machine-specific secrets.
Machine selection and recovery
kvmctl-pp-cli machines --help
kvmctl-pp-cli target-switch --help
kvmctl-pp-cli sequence --help
kvmctl-pp-cli workflow --help
The implementation includes bounded verification, session-integrity checks, target locking, cancellation-safe recovery, and checkpointed host reboot support. Hardware-changing paths remain opt-in.
Output and agent use
Every command supports the generated CLI's machine-output flags where applicable:
kvmctl-pp-cli info --json
kvmctl-pp-cli info --agent
kvmctl-pp-cli info --json --select ok,result
kvmctl-pp-cli info --dry-run --agent
- JSON goes to stdout; errors go to stderr.
--agent expands to JSON, compact output, no prompts, and no color.
--select limits returned fields.
--dry-run previews a request without sending it.
- Exit codes distinguish usage, missing resources, authentication, API, rate-limit, and configuration failures.
Run kvmctl-pp-cli --help and kvmctl-pp-cli <command> --help for the current command tree rather than relying on a copied list.
Paths and environment
The CLI separates configuration, durable data, runtime state, and cache files:
| Kind | Contents |
|---|
config | settings, profiles, and config.toml |
data | credentials.toml, SQLite data, cookies, and auth sidecars |
state | persisted queries, jobs, journals, and learning state |
cache | regenerable HTTP/cache files |
Resolution order is the per-kind variable, --home, KVMCTL_HOME, XDG variables, then platform defaults.
export KVMCTL_HOME=/srv/kvmctl
kvmctl-pp-cli doctor --json
Supported environment variables include:
| Variable | Purpose |
|---|
KVMCTL_KVMD_TOKEN | KVMD API credential |
KVMCTL_HOME | relocate all local data kinds under one root |
KVMCTL_CONFIG_DIR | override configuration directory |
KVMCTL_DATA_DIR | override durable data directory |
KVMCTL_STATE_DIR | override runtime state directory |
KVMCTL_CACHE_DIR | override cache directory |
KVMCTL_NO_LEARN | disable the local learning loop |
KVMCTL_LOCK_DIR | shared directory used to serialize physical device actions (default /tmp/kvmctl-locks) |
For MCP, put these variables in the host's MCP server environment. The MCP binary does not receive CLI flags.
MCP server
Install and run the MCP server:
go install github.com/mvanhorn/printing-press-library/library/devices/kvmctl/cmd/kvmctl-pp-mcp@latest
kvmctl-pp-mcp
Example Claude Desktop configuration:
{
"mcpServers": {
"kvmctl": {
"command": "kvmctl-pp-mcp",
"env": {
"KVMCTL_KVMD_TOKEN": "<your-kvmd-token>"
}
}
}
}
The MCP server never receives secrets through committed configuration. Use the host environment or the CLI's private credential store.
Development and verification
Requirements: Go 1.26.6 or newer.
make test
make build-all
go vet ./...
git diff --check
The release acceptance path additionally runs the official Printing Press validation and live dogfood checks. The live acceptance record is stored under .manuscripts/ and contains only redacted metadata and source fingerprints.
The original Python implementation used for parity comparison is maintained outside this repository and is not required at runtime.
Related documentation
Generated by CLI Printing Press.