I Vibe Coded a Kubernetes Interface in an Hour (So My Team Doesn't Have To)
I’ve been writing Go for a long time. I know how to set up a client-go
informer, I know the difference between a Clientset and a DynamicClient, and I
definitely know how to write the 500 lines of boilerplate required to expose a
REST API.
I also know that I absolutely do not want to do any of that on a Tuesday afternoon.
But I wanted to explore a way to bridge the gap between our team’s AI assistants and our Kubernetes clusters. There are existing MCP servers out there, sure. But I wanted something specific, something lightweight, and honestly? I just wanted to see if it could be “vibe coded”.
Spoiler: It can. And I barely touched my keyboard.
Curious, but Busy
Let me be clear upfront: I could have written this code myself. That’s precisely why I didn’t.
The experiment was about leverage, not capability. Could I use my Go expertise to validate AI-generated code rather than write it? Could I be the architect instead of the bricklayer?
(By the way, if you want to see the result, the repo is here: github.com/philippdrebes/kube-mcp)
Here’s the thing about Claude Code’s “Planning Mode” that clicked for me: you don’t micromanage the implementation. You describe the outcome, review the plan, and then get out of the way.
I let it plan, approved the plan, and then I literally tabbed away to answer emails, review PRs, and drink coffee.
An hour later, I came back to 17 MCP tools, a multi-stage Docker build, RBAC configurations for both reader and admin roles, and comprehensive deployment manifests. The whole thing. Working.
I was skeptical the entire time. I kept expecting to come back to a half-finished skeleton with TODO comments everywhere. Instead, I got a production-ready project structure with error handling I would have never bothered to implement myself.
The Code Review: Actually Not Bad
Healthy skepticism is part of the job, and I’m especially skeptical of code written by a probabilistic token generator. Before I could trust this thing, I needed to read it.
Authentication handling? Solid. The code properly detects whether it’s running in-cluster (service account) or locally (kubeconfig), with clean fallback logic:
1func DetectAuthMethod() (AuthType, error) {
2 if _, err := os.Stat(InClusterTokenPath); err == nil {
3 return AuthTypeInCluster, nil
4 }
5 return AuthTypeKubeconfig, nil
6}
Client architecture? Smart. It uses a hybrid approach Typed clients for core resources (compile-time safety) and dynamic clients for CRDs and unknown types:
1type Client struct {
2 clientset *kubernetes.Clientset // Typed client
3 dynamic dynamic.Interface // Dynamic client for CRDs
4 discovery discovery.DiscoveryInterface
5 // ...
6}
Error handling? Custom error types with proper unwrapping, meaningful error messages, and suggestions for common issues:
1func NewNotFoundError(resourceType, resourceName string) *MCPError {
2 return &MCPError{
3 Code: ErrCodeNotFound,
4 Message: fmt.Sprintf("%s '%s' not found", resourceType, resourceName),
5 Suggestions: []string{
6 "Check if the resource name is correct",
7 "Verify you're using the correct namespace",
8 "Use list command to see available resources",
9 },
10 }
11}
I’m not even mad. I’m impressed.
Then I checked internal/mcp/server.go. It had registered 17 different tools.
k8s_list_resources? Check.k8s_get_logs? Check.k8s_scale_resource? Check.
I didn’t write the JSON schema definitions for any of those. The AI just did it. That alone saved me three hours of reading MCP docs and debugging struct tags.
The “It Actually Works” Moment
I spun up a fresh kind cluster (I’m brave, but not “run untested AI code against production” crazy). I connected Claude Code to the binary.
1{
2 "mcpServers": {
3 "kube-mcp": {
4 "command": "/path/to/kube-mcp/bin/kube-mcp",
5 "args": [],
6 "env": {
7 "LOG_LEVEL": "info",
8 "DEFAULT_NAMESPACE": "default"
9 }
10 }
11 }
12}
“What’s running right now?”
Instead of typing kubectl get all -A and parsing ASCII tables in my head, I
got a structured response: namespaces, deployments, pods, services. Formatted.
Readable. With actual context about what’s healthy and what isn’t.
“Why is the backend pod crashing?”
This is where it got interesting. The AI didn’t just run kubectl logs. It
fetched the pod logs, checked events, looked at the container restart count,
and synthesized an actual explanation: “The pod is in CrashLoopBackOff because
the startup probe is failing. The container is exiting with code 1 after 3
attempts. Here are the last 50 lines of logs…”
No gymnastics. No memorizing which flags go where.
“Deploy podinfo and scale it to 5 replicas.”
It applied the manifest, confirmed the deployment, and reported back the pod
status. I didn’t touch kubectl once.
A Tool for the “K8s-Curious”
This isn’t about me showing off a tool I built. It’s about “Lazy Leverage”.
Kubernetes can be intimidating. kubectl is a power tool with a steep learning
curve. Even with great TUI tools like k9s (which I
absolutely love), there is still friction. We run a “Dev does Ops” model, but
specific Kubernetes experience is often still being acquired. The specialized
lingo acts as a barrier. Engineers often get blocked, waiting for validation
because the concepts aren’t accessible enough.
With this MCP server, the interface isn’t CLI arguments; it’s natural language.
- The Problem: “I don’t know the command to find why my pod crashed.”
- The Solution: You ask the AI, “Why is the backend crashing?”
- The Mechanism: The AI uses
k8s_get_eventsandk8s_get_logs, analyzes the output, and tells you: “It looks like aSystem.NullReferenceExceptioninProgram.cs:42.”
It acts as a Translator. It democratizes access to infrastructure state without requiring everyone to be a Certified Kubernetes Administrator.
It’s also a time-saver for experienced engineers. You can fire off a request like “find out why the Dragonfly instance is degraded” while you tab away to finish a PR review. Later, you can review the structured findings without breaking your flow state to manually grep through logs.
Please Don’t Put This in Prod
Let’s be real for a second. This is a “Vibe Coded” tool.
LLMs are non-deterministic. “Vibe coding” is fast, but it relies on the AI understanding context perfectly every time.
I am perfectly happy using this for read-only access, debugging in dev environments, and exploring cluster state.
But I remain highly cautious about giving an LLM write-access to a production cluster. You do not want a hallucination to turn “please clean up the old pods” into “delete the kube-system namespace.”
Use this for:
- Local development (Kind, Minikube, Docker Desktop).
- Read-only access in staging.
- Debugging sessions where you need an assistant to grep through logs.
Do not use this for:
- Deploying your bank’s core ledger.
Conclusion
The barrier to building custom infrastructure tooling has collapsed.
In the past, building a custom CLI or a GUI for our teams to interact with K8s would have been a week-long undertaking. It likely would have gone into the backlog and died there.
Via “Vibe Coding,” I built it in an hour while reviewing some PRs. That is Lazy Leverage. It allows us to build bespoke, helpful tools that unblock our teams without drowning ourselves in maintenance and boilerplate.
Now, if you’ll excuse me, I have a coffee to finish.