KubeAssist · @k8s

Steer the cluster
by hand.

Write @k8s on the reMarkable. The helmsman reads the order, runs the tools inside the cluster, and draws the answer back as ink.

model gpt-5.5 21 k8s tools read + write A2A · MCP GitOps kagent
@k8s helm order
The order travels

From pen stroke to running command

One line on the page becomes a real set of Kubernetes API calls. Every hop is a small, testable service — the tablet only writes the order and draws the reply.

Pen tablet

You write @k8s table: pods not running and pause. The takeover diary snapshots the page.

Read gpt-5.5

Vision OCR through agentgateway transcribes the ink and normalizes the tag to exactly @k8s — even if you wrote “@ kube”.

Route agent-desk

The diary sees the @k8s prefix and POSTs the line to the agent-desk router at /ask.

Steer A2A

agent-desk calls the k8s-agent over A2A. KubeAssist decides which k8s_* tools the order needs.

Act MCP

The kagent tool server runs those tools against the live cluster using its own ServiceAccount.

Report render-spec

gpt-5.5 folds the reply into a compact spec; the tablet draws a table, stats tiles, or prose.

The helmsman

KubeAssist, wired to your cluster

The same Kubernetes expert agent kagent ships — a gpt-5.5 operator that follows a read-first, least-privilege method — connected to a tool server that speaks the Kubernetes API. It holds 21 tools, split by blast radius.

◐ Look — read-only
  • get_resources
  • describe_resource
  • get_pod_logs
  • get_events
  • get_resource_yaml
  • get_cluster_configuration
  • get_available_api_resources
  • check_service_connectivity
◑ Steer — changes state
  • scale
  • rollout
  • patch_resource
  • apply_manifest
  • create_resource
  • delete_resource
  • label_resource
  • annotate_resource
  • execute_command
  • generate_resource

The tool server

kagent-tools · ghcr.io/kagent-dev/kagent/tools:0.2.1

kagent's official tool binary, run as a Deployment with --tools=k8s. It exposes the k8s_* tools over MCP (streamable HTTP, :8084/mcp) and is registered as a RemoteMCPServer the agent discovers automatically.

The router

agent-desk · NodePort 30260 · /ask

A thin FastAPI service that parses the @forti / @f5 / @k8s prefix, calls the matching agent over A2A, and coerces the reply into the render-spec the tablet draws. The tablet stays dumb on purpose.

The bridge

How the parts connect

Two namespaces, one gateway. The tablet talks only to agent-desk; agent-desk fans out to the agents; the agents reach their tools in-cluster.

  reMarkable 2 (takeover diary)@k8s table: pods not runningagent-desk  ns remarkable-diary · NodePort 30260 /ask
        │  A2A (message/send)
        ▼
  k8s-agent  ns kagent · KubeAssist · gpt-5.5
        │  MCP  http://kagent-tools.kagent:8084/mcp
        ▼
  kagent-tools  ──▶  Kubernetes API  (own ServiceAccount)
        ▲
        │  the LLM hops (OCR + coerce) run through
  agentgateway  — traced, keyed, rate-limited
Rules of the helm

This helm has no wheel-lock

⚠ Full KubeAssist is armed for write

The agent holds the state-changing tools, and the tablet path is fire-and-forget — there is no on-device “are you sure?”. A handwritten @k8s delete deployment web will execute. The tool server carries a cluster-admin ClusterRole, so its reach is the whole cluster. This is deliberate: it's a single-operator homelab helm, not a shared console.

Want a read-only helm? Swap one file — point kagent-tools-rbac.yaml at the chart's rbac.readOnly rule set (get / list / watch + pod logs only) and re-sync. Nothing else changes; the write tools simply return “forbidden”.
Give an order

What to write on the page

Lead with @k8s. Add table:, stats:, map:, or text: to force a shape — or leave it off and the reporter picks the best fit for the answer.

@k8s table: pods in kagent
draws → table

A bordered grid: pod, ready, status, restarts, age, node.

@k8s how healthy is the cluster
draws → stats

KPI tiles: nodes ready, deployments up-to-date, restarts, warnings.

@k8s why is web-7d crashlooping
draws → text

A short diagnosis from logs and events, with the likely cause.

@k8s scale web to 3 replicas
changes state

Runs k8s_scale, then confirms the new replica count.

@k8s map: the kagent namespace
draws → mind map

KubeAssist walks the namespace; the answer comes back as a left→right markmap grouped by resource type. A heavier query — give it ~a minute.

Under the hood

Three files, one GitOps app

Everything on the cluster side lives in config/kagent-models/ and is synced by the ArgoCD kagent-models app — the same folder as the FortiGate and F5 agents.

kagent-tools-server.yamlthe tool server + Service + RemoteMCPServer
kagent-tools-rbac.yamlServiceAccount + ClusterRole/Binding — the blast radius, in one place
k8s-agent.yamlthe Agent: KubeAssist prompt, model gpt-5-5, the k8s_* tool list
# the agent points at the tool server and lists exactly what it may call
tools:
  - type: McpServer
    mcpServer:
      kind: RemoteMCPServer
      name: kagent-tool-server
      toolNames: [ k8s_get_resources, k8s_scale, k8s_delete_resource, … ]

Verified end to end: the agent answers reads and writes over A2A, and /ask @k8s returns a real pod table. The one step only a human can run is writing the order on the glass.