Skip to content

Repository files navigation

KubeVirt Console MCP

A read-only MCP server that gives AI agents direct evidence from a running KubeVirt guest's console — what a human would see over VNC or a serial terminal.

Kubernetes tells an agent a VM is running. This server lets the agent see what the guest is actually showing.

flowchart LR
    Agents["AI agents<br/>"]
    K8s["kubernetes-mcp-server<br/>control-plane view<br/>objects, status, events"]
    Console["kubevirt-console-mcp<br/>guest-console view<br/>screenshot, console log"]
    VM(["running KubeVirt VM"])

    Agents --> K8s --> VM
    Agents --> Console --> VM
Loading

It returns evidence only — a PNG image or console text. It performs no reasoning.

Demo

kubevirt-console-mcp-demo.mp4

Claude starts with Kubernetes-level troubleshooting — then uses the KubeVirt Console MCP to inspect the guest console and discover a kernel panic that the Kubernetes MCP alone cannot identify.

Tools

Tool What it does
console_screenshot Captures the guest's graphical console as a PNG image (VNC framebuffer).
console_log Reads persisted serial-console output from the guest-console-log sidecar.
console_capture Captures live serial-console output for a bounded duration (1—30s).

Quick start

Build:

go build -o kubevirt-console-mcp ./cmd/kubevirt-console-mcp

Run (requires a kubeconfig or in-cluster credentials):

./kubevirt-console-mcp

The binary speaks MCP over stdio. stdout is reserved for the protocol; logs go to stderr.

MCP client configuration

{
  "mcpServers": {
    "kubevirt-console-mcp": {
      "command": "/path/to/kubevirt-console-mcp"
    }
  }
}

Kubernetes configuration

Standard client-go conventions — no custom flags or credential formats:

  1. KUBECONFIG environment variable
  2. Default kubeconfig rules (~/.kube/config)
  3. In-cluster configuration (when running as a pod)

RBAC

Console access is security-sensitive and granted separately from ordinary VM read access. See deploy/rbac.yaml for a least-privilege example.

Required permissions:

Resource API group Verbs Why Used by
virtualmachineinstances kubevirt.io get Check VMI phase and device flags all tools
virtualmachineinstances/vnc/screenshot subresources.kubevirt.io get Graphical console screenshot console_screenshot
virtualmachineinstances/console subresources.kubevirt.io get Serial console access console_capture
pods core get, list Find the virt-launcher pod for a VMI console_log
pods/log core get Read the guest-console-log container console_log

No create, update, delete, or patch verbs are needed. If you only use a subset of the tools, you only need that subset of permissions (see the Used by column).

When you need it

Whether you apply deploy/rbac.yaml depends on the identity the server authenticates as, which follows the Kubernetes configuration resolution order:

  • In-cluster (running as a pod): required. The pod's ServiceAccount has no permissions by default, so without this Role/RoleBinding every call fails with PERMISSION_DENIED (HTTP 403). Apply the manifest and set the Deployment's serviceAccountName to kubevirt-console-mcp.
  • Out-of-cluster (kubeconfig), identity already has these verbs (e.g. a cluster-admin kubeconfig): not needed — it just works.
  • Out-of-cluster (kubeconfig), restricted identity: apply the Role from the manifest but change the RoleBinding subject from the ServiceAccount to your User or Group.

Note that being able to read VMI objects does not imply console access — the screenshot and serial console are separate subresources.kubevirt.io subresources with their own RBAC. An identity that can already get virtualmachineinstances will still be denied on the console until these subresource grants are added.

Scope

As written, deploy/rbac.yaml is namespaced (Role + RoleBinding in default) — apply one copy per namespace you observe. For multi-namespace or cluster-wide use, swap Role/RoleBinding for ClusterRole/ClusterRoleBinding.

Output bounds

Every tool response is bounded to prevent a guest from exhausting an agent's context:

Limit Value
Screenshot 4 MiB max
Console log 256 KiB max, 1—5000 tail lines (default 500)
Live capture 128 KiB max, 1—30s duration (default 5s)

Truncation is always explicit ([output truncated by kubevirt-console-mcp after N bytes]), never silent.

Security

  • Screenshots and serial output can contain credentials, IPs, hostnames, and application data. They are held in memory only for the duration of a tool call — never written to disk, never logged.
  • console_capture never sends keystrokes to the guest. It supplies a synthetic empty reader as the connection's input side.
  • wake_screen defaults to false — it causes a minor graphical interaction (cursor nudge) with the guest.
  • A live serial connection may contend with a human or another console client attached to the same VMI.

Known limitations

  • console_screenshot requires a running VMI with graphics enabled. Use serial tools when graphics are disabled or unavailable (early boot, autoattachGraphicsDevice: false).
  • Serial output depends on the guest emitting it. Some guests need console=ttyS0 or similar kernel arguments.
  • The guest-console-log sidecar can be disabled; console_log reports this clearly.
  • Pod logs are not permanent storage — if the virt-launcher pod is deleted, its log is gone.
  • A quiet console_capture (no output) is normal, not a failure — the guest was simply quiet.

Development

go test ./...
go test -race ./...
go vet ./...

Tests use Ginkgo / Gomega. The unit suites under internal/ do not require a cluster. Functional (end-to-end) tests live in tests/ and run with go test -tags=integration ./...; they require KUBEVIRT_CONSOLE_MCP_TEST_NAMESPACE and KUBEVIRT_CONSOLE_MCP_TEST_VMI pointing at a running VMI.

Project layout

cmd/kubevirt-console-mcp/  MCP server entry point (stdio transport, stderr logging)
internal/
  config/                  Kubernetes REST config loading
  kubevirt/                KubeVirt API access: screenshot, log, capture, pod selection
  mcp/                     MCP tool registration and handlers
tests/                     Functional (end-to-end) tests against a live cluster
deploy/rbac.yaml           Least-privilege Role/RoleBinding

License

Released under the Apache License 2.0.

About

MCP server for KubeVirt guest console

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages