Skip to main content

User guide: AI agents over MCP (Hermes Agent)

kaironctl mcp serve is a Model Context Protocol server on stdin/stdout. An MCP client such as Hermes Agent starts it as a subprocess and can then list and inspect Machines, read VM-edge network data and, if you allow it, change power state, take snapshots and run packet captures.

FluxVM has a matching server, fluxctl mcp serve, for the VMs on one host (see FluxVM's docs/mcp.md). Use both to give an agent the cluster view and the host view. For end-to-end setup of both, scoped credentials, other MCP clients and example workflows, see AI agent integration. This page is the kaironctl mcp serve reference.

Tools​

Read tools are always offered:

ToolWhat it returnsBackend
list_machinesMachines with phase, power state, node, guest IP, CPU and memory; all namespaces unless namespace is setKubernetes API
get_machineOne Machine's metadata, spec and statusKubernetes API
list_network_policiesMachineNetworkPoliciesKubernetes API
machine_networkkind = network-effective, network-stats, network-flows, network-drops, network-drop-reasons or network-capture (capture sessions); limit for flows and dropskairon-ui
machine_edge_identityThe stable VM-edge identitycomputed locally
machine_volumesEach spec.volumes entry: source (pvc, atlas-pvc, atlas-rbd), claim, size, Atlas phase, backend id, errorKubernetes API
get_machine_snapshotA MachineSnapshot's phase and per-volume snapshots (CSI VolumeSnapshot or Atlas snapshot id)Kubernetes API
list_machine_poolsMachinePools with warm size, ready and claimed countsKubernetes API
list_backupsMachineBackups and MachineBackupRestores with phase, node, size, quiesce result and Atlas backup idsKubernetes API

Write tools are offered only with --allow-write:

ToolEffect
set_power_stateSets spec.powerState to Running, Stopped, Paused or Halted.
create_snapshotCreates a MachineSnapshot (name generated unless snapshotName is set).
snapshot_volumeSnapshots one named volume (MachineSnapshot with spec.volumeNames); Atlas volumes use Atlas snapshots.
network_captureRuns a 1-30 s tcpdump capture on the Machine's VM edge. With output, waits and writes the pcap to that path on the machine running kaironctl; otherwise returns the token.
claim_machineCreates a MachineClaim against pool and waits up to waitSeconds (default 30) for it to bind; returns the Machine name and bind time. Optional labels, retain, ttlSeconds, and egress (an allowlist enforced for the claim's lifetime).
release_claimDeletes a MachineClaim; its Machine is deleted too unless the claim was made with retain.
fork_machineForks a Running flux-vm Machine into count live children on the same node and waits up to waitSeconds (default 60) for them to run. See machine-fork.md.
machine_diskAdds (attach, with claim) or removes (detach) a spec.disks entry; kairon-node hot-attaches or unplugs the PVC disk.
machine_nicAdds (add, with bridge) or removes (remove) a spec.network.extraInterfaces entry; kairon-node hot-adds or unplugs the NIC.
machine_backupCreates a MachineBackup (create), a MachineBackupRestore into the halted Machine (restore, with backup), or deletes a backup (delete).
delete_machineDeletes a Machine. Refuses MachineSet replicas (the set would recreate them).

Migrate, exec, and edge or policy changes are not exposed.

Every tool takes namespace (default: --namespace, else default) and name where it acts on one Machine. Unknown arguments are rejected, so a mistyped field comes back as an error instead of being ignored.

Configure Hermes​

Add the server to ~/.hermes/config.yaml (or run hermes mcp add):

mcp_servers:
kairon:
command: kaironctl
args: ["mcp", "serve"] # add "--allow-write" for power, snapshot, capture
env:
KAIRON_KUBE_URL: "https://127.0.0.1:6443"
KAIRON_KUBE_TOKEN: "..."
KAIRON_KUBE_INSECURE: "true" # lab only; prefer KAIRON_KUBE_CA
KAIRON_UI_URL: "http://127.0.0.1:22000"
KAIRON_UI_TOKEN: "..."
timeout: 120

Then /reload-mcp in a running Hermes session. The tools appear as mcp_kairon_list_machines and so on. A copy of this config is in .hermes/config.example.yaml.

To keep an agent read-only even if someone adds --allow-write, filter the tools on the Hermes side as well:

tools:
exclude: [set_power_state, create_snapshot, snapshot_volume, network_capture, claim_machine, release_claim, delete_machine]

Credentials​

VariableNeeded for
KAIRON_KUBE_URL, KAIRON_KUBE_TOKEN, KAIRON_KUBE_CA / KAIRON_KUBE_INSECUREMachine, policy, power and snapshot tools. In a Pod, the service account is used instead.
KAIRON_UI_URL, KAIRON_UI_TOKENmachine_network and network_capture. kairon-ui needs diagnostics enabled (KAIRON_NODE_CONSOLE_TOKEN on kairon-ui and kairon-node).

The agent can do whatever these credentials allow. Give it a Kubernetes token bound to a Role that only has the verbs you want (for example get and list on machines, plus patch only if power changes are allowed). Tokens are read from the environment and never appear in tool results.

Limits​

  • Tool output is capped at 64 KB; longer results are cut with a note to narrow the request (for example with limit).
  • Each call times out after 30 s; a capture after its length plus 45 s.
  • Only the tools capability is implemented (no MCP resources or prompts).

Testing without Hermes​

The server speaks newline-delimited JSON-RPC, so a pipe is enough:

printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
'{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_machines","arguments":{}}}' \
| kaironctl mcp serve

Logs go to stderr; stdout carries only protocol messages.

Troubleshooting​

SymptomFix
kubernetes endpoint not configuredSet KAIRON_KUBE_URL and KAIRON_KUBE_TOKEN in the server's env.
set KAIRON_UI_URL to reach uiapi …Set KAIRON_UI_URL (and KAIRON_UI_TOKEN).
HTTP 501: diagnostics are not enabledSet KAIRON_NODE_CONSOLE_TOKEN on kairon-node and kairon-ui.
A write tool says to start with --allow-writeAdd --allow-write to args, then /reload-mcp.
Hermes shows no mcp_kairon_* toolsCheck that kaironctl is on Hermes' PATH (or use an absolute command), and run the pipe test above.