kubectl-mcp
by teresa-tran
README.md
# kubectl-mcp
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that lets
AI agents inspect Kubernetes clusters in plain English — ask *"which pods
restarted in the last hour?"* and get a real answer.
Built by [Teresa Tran](https://teresa-tran.github.io).
## Why
LLM assistants are great at explaining `kubectl` commands and terrible at
actually running them safely. **kubectl-mcp** exposes read-only cluster
inspection as a set of MCP tools an agent can call — turning "check my cluster"
from copy-paste-and-hope into a real conversation.
- **Read-only by design.** No `apply`, no `delete`, no `exec`. The server only
ever *inspects*.
- **Mock mode by default.** Ships with a seeded fake cluster so you can try it
in 30 seconds without a real cluster.
- **Real mode when you're ready.** Point it at your `KUBECONFIG` and it queries
a live cluster via the official Kubernetes Python client.
## Install
```bash
pip install kubectl-mcp # mock mode (default)
pip install "kubectl-mcp[real]" # + real-cluster support (kubernetes client)
```
Or from source:
```bash
git clone https://github.com/teresa-tran/kubectl-mcp.git
cd kubectl-mcp
pip install -e ".[real,dev]"
```
## Run it standalone (sanity check)
```bash
kubectl-mcp --help # show flags
kubectl-mcp --list-tools # print every MCP tool + its schema
kubectl-mcp --demo list_pods # run a tool once against the mock cluster
kubectl-mcp --demo find_restarted_pods --arg since_minutes=120
```
## Wire it into an MCP client
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (mac)
or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"kubectl": {
"command": "kubectl-mcp"
}
}
}
```
For real-cluster mode:
```json
{
"mcpServers": {
"kubectl": {
"command": "kubectl-mcp",
"env": {
"KUBECTL_MCP_MODE": "real",
"KUBECONFIG": "/Users/you/.kube/config"
}
}
}
}
```
Restart Claude Desktop. You should now be able to ask *"list pods in the
production namespace"* and get a real answer.
### Other MCP-compatible clients
Any client that speaks stdio MCP (Cursor, Cline, Continue, custom agents) works
the same way — point it at the `kubectl-mcp` binary.
## Tools exposed
| Tool | What it does |
|---|---|
| `list_namespaces` | All namespaces in the cluster |
| `list_pods` | Pods in a namespace, with phase + restart count |
| `get_pod` | Full detail for one pod (containers, statuses, events) |
| `list_deployments` | Deployments in a namespace, with ready/desired replicas |
| `get_deployment` | Full detail for one deployment |
| `list_services` | Services in a namespace, with type + endpoints |
| `list_recent_events` | Events in the last N minutes, most recent first |
| `get_pod_logs` | Last N lines of a pod's logs (read-only, no `exec`) |
| `find_restarted_pods` | Pods that restarted in the last N minutes (high-level query) |
Every tool has a JSON Schema — LLMs get proper argument validation for free.
## Configuration
Environment variables:
| Var | Values | Default | What |
|---|---|---|---|
| `KUBECTL_MCP_MODE` | `mock` \| `real` | `mock` | Cluster backend |
| `KUBECONFIG` | path | `~/.kube/config` | Real-mode kubeconfig path |
| `KUBECTL_MCP_MOCK_DATA` | path | (bundled) | Override the mock cluster JSON |
| `KUBECTL_MCP_LOG_LEVEL` | `debug` \| `info` \| `warn` | `info` | Log verbosity to stderr |
## The mock cluster
The default mock cluster ships in `src/kubectl_mcp/mock_data.json` and includes:
- 3 namespaces: `default`, `production`, `staging`
- ~15 pods spanning healthy, crashlooping, and recently-restarted states
- Deployments, services, and a stream of recent events
- Some pods have restart counts > 0 so `find_restarted_pods` returns real
results
You can override it by setting `KUBECTL_MCP_MOCK_DATA=/path/to/your.json` if
you want to demo a specific scenario.
## Design notes
- **Read-only by construction.** The `KubernetesBackend` protocol only defines
read methods. There's no code path that can mutate cluster state — even in
real mode.
- **Backend is swappable.** `MockBackend` and `RealBackend` implement the same
protocol. Adding a third (e.g., a cached snapshot) is one file.
- **Errors are exceptions, not silent nulls.** `ResourceNotFound`,
`NamespaceNotFound`, etc., propagate as `McpError` with helpful messages so
the agent can course-correct.
- **stdio transport.** All MCP tool calls are JSON-RPC over stdio, matching the
MCP spec exactly.
## Development
```bash
pip install -e ".[real,dev]"
pytest # run tests
ruff check src tests # lint
kubectl-mcp --demo list_pods --arg namespace=production # smoke test
```
## Roadmap
- [x] Mock backend with seeded data
- [x] Real backend via `kubernetes` python client
- [x] Read-only tool surface
- [x] Standalone `--demo` mode for CI/smoke tests
- [ ] Multi-cluster support (`--context` flag)
- [ ] Metrics tools (CPU/memory via `metrics.k8s.io`)
- [ ] Optional caching layer for high-frequency queries
## License
MIT © 2026 Teresa Tran
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues