Deep Dive: Testing Radar UI for Kubernetes using MCP, a Go GUI, and an Autonomous Agent Radar, a Kubernetes dashboard from radarhq.io, integrates a Model Context Protocol (MCP) server to expose cluster state for external clients and AI agents. A developer tested the system on macOS using Minikube with Podman and CRI-O, deploying a Go workload and running a Fyne-based GUI client and an autonomous ReAct agent that performed cluster diagnostics over MCP. Hand-on test of radarhq.io https://radarhq.io/ K8S UI and dashboard on a macOS with Minikube and Podman Kubernetes dashboards are often either overloaded with unnecessary complexity or too minimalist to provide deep operational context during an outage. Radar radarhq.io https://radarhq.io/ takes a refreshingly modern approach. It not only delivers a clean visual cluster dashboard but also natively integrates a Model Context Protocol MCP server. By exposing cluster state — deployments, pods, topology, live operational issues, and logs — via MCP, Radar allows external clients, CLI tools, and AI agents to programmatically query and analyze Kubernetes workloads without direct, high-privilege access to the raw Kubernetes API. In this blog post, I explore an end-to-end testing environment for Radar. I tested the overall system architecture, set up a sample Go workload hello-k8s , inspect a Fyne-based GUI desktop client, and run an autonomous 7-step ReAct agent that performs cluster diagnostics over MCP. I used IBM Bob SDLC for the implementation. To test Radar locally on macOS without Docker Desktop, I leveraged Minikube powered by the Podman driver and CRI-O runtime. Because Minikube’s Podman driver places the VM inside an AppleHV VM whose internal IP 192.168.49.x is not directly routed to the host machine, I implemented background kubectl port-forward tunnels to bridge the local host to the internal cluster services: localhost:30928 → Radar Pod :9280 localhost:30800 → hello-k8s Pod :8080 hello-k8s To give Radar and our MCP clients a realistic workload to inspect, a a lightweight HTTP application written in Go is deploye. The application tracks request counts, renders pod metadata obtained via the Kubernetes Downward API, and exposes health probes at /healthz . k8s/hello-k8s.yaml A 2-replica deployment is set-up, so that Radar can construct a multi-pod service topology graph: apiVersion: apps/v1 kind: Deployment metadata: name: hello-k8s namespace: hello-k8s labels: app: hello-k8s spec: replicas: 2 selector: matchLabels: app: hello-k8s template: metadata: labels: app: hello-k8s spec: containers: - name: hello-k8s image: hello-k8s:latest imagePullPolicy: Never ports: - name: http containerPort: 8080 env: - name: PORT value: "8080" - name: POD NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 3 periodSeconds: 5 resources: requests: cpu: 10m memory: 16Mi limits: cpu: 100m memory: 64Mi --- apiVersion: v1 kind: Service metadata: name: hello-k8s namespace: hello-k8s spec: type: NodePort selector: app: hello-k8s ports: - name: http port: 8080 targetPort: 8080 nodePort: 30800 Rather than accessing raw Kubernetes endpoints directly, the custom GUI client communicates purely over HTTP JSON-RPC using the Model Context Protocol MCP endpoint provided by Radar at /mcp . The client uses the official @modelcontextprotocol/go-sdk to establish stateless HTTP transport sessions and execute tools like get dashboard and issues. gui-client/main.go func c MCPClient callTool ctx context.Context, toolName string, args map string any byte, error { client := mcp.NewClient &mcp.Implementation{ Name: "radar-mcp-gui", Version: "1.0.0", }, nil ​ transport := &mcp.StreamableClientTransport{ Endpoint: c.endpointURL, } ​ session, err := client.Connect ctx, transport, nil if err = nil { return nil, fmt.Errorf "connect to %s: %w", c.endpointURL, err } defer session.Close ​ result, err := session.CallTool ctx, &mcp.CallToolParams{ Name: toolName, Arguments: args, } if err = nil { return nil, fmt.Errorf "call %q: %w", toolName, err } ​ var combined byte for , content := range result.Content { if tc, ok := content. mcp.TextContent ; ok { combined = append combined, byte tc.Text ... } } return combined, nil } To keep the UI responsive, a background goroutine fetches data snapshots on every poll interval e.g., 10s and passes updates over a buffered channel to the main thread: // Background fetch loop snapCh := make chan ClusterSnapshot, 1 ​ go func { ctx := context.Background for { snap := fetchSnapshot ctx, mcpClient select { case snapCh <- snap: default: // Drop if UI thread is busy } time.Sleep cfg.PollInterval } } To automate workload inspection, a Go CLI agent radar-agent that acts as an autonomous operator is implemented. It runs a deterministic 7-step ReAct Reason + Act loop using Radar's MCP tool set. agent/main.go Here is an excerpt showing how the agent executes the observation phase and lists resources: func run error { flag.Parse client := newMCPClient ctx := context.Background ​ // Step 1: OBSERVE cluster health step 1, "OBSERVE", "cluster overview via get dashboard" dash, err := stepObserve ctx, client, flagNamespace if err = nil { return fmt.Errorf "observe: %w", err } ​ // Step 2: FOCUS on targeted pods step 2, "FOCUS", fmt.Sprintf "list pods in namespace %q", flagNamespace pods, err := stepListPods ctx, client, flagNamespace if err = nil { fmt.Printf " Warning: %v\n", err } ​ // Step 3: INSPECT Deployment spec/status step 3, "INSPECT", fmt.Sprintf "get resource deployment/%s", flagWorkload dep, := stepInspectDeployment ctx, client, flagNamespace, flagWorkload ​ // Step 4: TOPOLOGY graph analysis step 4, "TOPOLOGY", fmt.Sprintf "get topology namespace=%q", flagNamespace topo, := stepTopology ctx, client, flagNamespace ​ // Step 5: Live operational ISSUES step 5, "ISSUES", fmt.Sprintf "issues namespace=%q", flagNamespace issues, := stepIssues ctx, client, flagNamespace ​ // Step 6: Sample LOGS step 6, "LOGS", fmt.Sprintf "get workload logs deployment/%s", flagWorkload logs, := stepLogs ctx, client, flagNamespace, flagWorkload ​ // Step 7: Print Final Summary step 7, "REPORT", "structured summary" // ... renders formatted report to stdout ... return nil } To test the full stack on your local machine, follow these steps: Run the setup script to initialize Minikube, deploy Radar via Helm, build hello-k8s , apply RBAC patches, and start port-forwarding: chmod +x scripts/ .sh ./scripts/deploy.sh ./scripts/run-agent.sh --namespace hello-k8s --workload hello-k8s ════════════════════════════════════════════════════════════ RADAR AGENT REPORT Goal : Investigate the hello-k8s workload and summarise its health Namespace : hello-k8s Workload : hello-k8s ════════════════════════════════════════════════════════════ ​ CLUSTER OVERVIEW Health: healthy cluster: minikube v1.28.0 Pods: healthy=4 warning=0 error=0 Nodes: total=1 ready=1 notReady=0 Total problems: 0 ​ PODS IN NAMESPACE "hello-k8s" hello-k8s-74b884988f-2k9ll Running ready=1/1 node=minikube hello-k8s-74b884988f-b98x7 Running ready=1/1 node=minikube ​ DEPLOYMENT: hello-k8s Replicas: 2 desired / 2 ready / 2 available Container: hello-k8s → hello-k8s:latest ​ TOPOLOGY namespace "hello-k8s" 3 nodes, 2 edges ​ LIVE ISSUES No issues found — workload looks healthy. ════════════════════════════════════════════════════════════ ./scripts/start.sh | Technical Decision | Rationale | | ------------------------------------ | ------------------------------------------------------------ | | Podman Driver + CRI-O | Enables containerized Kubernetes testing on macOS without relying on Docker Desktop. MD | | kubectl port-forward Tunneling | Solves AppleHV VM network isolation by routing localhost:30928 directly to Radar's container port. MD | | Chart Tag Pinning 1.7.0 | Prevents version mismatch crashes with Helm flags present in newer chart versions. MD | | RBAC Supplemental Patch | Adds missing rbac.authorization.k8s.io read permissions required for Radar's permission inspection panels to function properly. MD | | Model Context Protocol MCP | Decouples direct Kubernetes API access from monitoring tools, allowing lightweight agents and GUIs to consume structured cluster context safely. MD+ 1 | By exposing cluster telemetry and operational controls through the Model Context Protocol, Radar transforms Kubernetes monitoring from a manual dashboard-checking task into a programmatic foundation for automation. Whether powering custom desktop GUIs like Fyne or enabling autonomous ReAct agents to run multi-step diagnostic workflows, MCP bridges the gap between raw cluster metrics and intelligent operational tools. As container environments continue to grow in complexity, decoupling cluster context from high-privilege API access via MCP offers a cleaner, safer, and far more extensible approach to Kubernetes management. Thanks for reading 🍇