Skip to main content
Glama
teresa-tran

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