kubeaid-mcp
by 1Shubham7
README.md
# kubeaid-mcp
An MCP (Model Context Protocol) server that exposes a Kubernetes cluster to any
MCP-compatible AI client (Claude Code, Claude Desktop, Cursor, ...). The client
launches the server as a subprocess and talks to it over stdio (JSON-RPC 2.0);
the server translates tool calls into Kubernetes API calls via
[`@kubernetes/client-node`](https://github.com/kubernetes-client/javascript).
Built in TypeScript on the [NitroStack](https://nitrostack.ai) MCP framework.
See [design.md](./design.md) for the architecture.
## Demo
[](https://www.youtube.com/watch?v=QFLlo8RDWf8)
## Tools
| Tool | Description |
|------|-------------|
| `list_contexts` | List the kubeconfig contexts (clusters) the server can target. |
| `list_namespaces` | List namespaces in a cluster, with status. |
| `list_pods` | List pods in a namespace (or all namespaces), with derived status, ready count, restarts and age. |
| `describe_pod` | Pod status, per-container state (waiting/termination reasons, last restart), and recent events. |
| `get_pod_logs` | Tail a container's logs; `previous: true` reads a crashed instance's prior logs. |
| `list_deployments` | List deployments with ready/up-to-date/available replica counts and age. |
| `list_nodes` | List cluster nodes with Ready status, roles, version and internal IP. |
| `get_events` | Recent events in a namespace (or all), sorted oldest to newest. |
| `describe_resource` | Fetch any resource kind (incl. CRDs) by kind/plural/short-name and name. |
Every tool accepts an optional `context` argument to target a specific
kubeconfig context. Omit it to use the server's default context.
### Write tools (opt-in)
These are registered only when `KUBEAID_ALLOW_WRITES=true`. Each accepts an
optional `dry_run` to simulate the change server-side without persisting it.
| Tool | Description |
|------|-------------|
| `apply_manifest` | Create or update resources from a YAML/JSON manifest (server-side apply). |
| `patch_resource` | Patch an existing resource (strategic / merge / json). |
| `delete_resource` | Delete a resource by kind and name. |
| `scale_deployment` | Set a deployment's replica count. |
| `rollout_restart` | Rolling-restart a deployment/statefulset/daemonset. |
| `exec_command` | Run a command inside a container (only with `KUBEAID_ALLOW_EXEC=true`). |
## Prompts
Prompts are user-invoked workflow templates (surfaced as slash commands / menu
items in the client). Unlike tools, a prompt does not touch the cluster — it
returns a message that guides the model through a task using the tools above.
| Prompt | Arguments | What it does |
|--------|-----------|--------------|
| `diagnose_pod` | `namespace`, `pod_name`, `context?` | Walk through describe → logs to find why a pod is unhealthy and suggest a fix. |
| `triage_namespace` | `namespace`, `context?` | Find every unhealthy workload in a namespace and investigate each. |
| `cluster_health_check` | `context?` | High-level health sweep: nodes, pods across all namespaces, recent warnings. |
| `review_warnings` | `namespace?`, `context?` | Review recent Warning events and explain what they mean. |
## Installation
Requires **Node.js 20+**. Build the server once, then register it with your AI
client(s).
### 1. Build the server
```bash
git clone https://github.com/1shubham7/kubeaid-mcp-ts.git
cd kubeaid-mcp-ts
npm install
npm run build # compiles TypeScript to dist/ (entry: dist/index.js)
```
Note the absolute path to the entry point — the AI clients need it:
```bash
echo "$(pwd)/dist/index.js"
```
For local iteration you can also run `npm run dev` (NitroStack's dev server with
hot reload), which is handy with [NitroStudio](https://nitrostack.ai/studio) as a
visual MCP client.
### 2. Register with Claude Code
```bash
claude mcp add kubeaid -- node "$(pwd)/dist/index.js"
```
With no `KUBEAID_CONTEXT` set, the server follows your kubeconfig's
current-context live, so `kubectl config use-context <name>` switches the target
cluster without re-registering. Pin a fixed default by adding
`-e KUBEAID_CONTEXT=kind-kubeaid` if you'd rather it never move.
Read tools only are exposed by default. To enable the mutating tools
(apply/patch/delete/scale/rollout), pass `-e KUBEAID_ALLOW_WRITES=true`, and list
any production contexts as protected so they can never be written to:
```bash
claude mcp add kubeaid \
-e KUBEAID_ALLOW_WRITES=true \
-e KUBEAID_PROTECTED_CONTEXTS=prod-cluster,another-prod-cluster \
-- node "$(pwd)/dist/index.js"
```
### 3. Register with Claude Desktop
Recent Claude Desktop builds gate local MCP servers behind a setting, so order
matters:
1. **Enable local MCP:** Settings → Developer → **Local MCP servers**. Local
stdio servers are off by default; opening/enabling this is required.
2. **Edit the config:** on that page click **Edit Config** — it opens the file
the app actually reads (`~/.config/Claude/claude_desktop_config.json` on
Linux; macOS `~/Library/Application Support/Claude/`; Windows
`%APPDATA%\Claude\`). Add a top-level `mcpServers` key, using the absolute
path from step 1:
```json
{
"mcpServers": {
"kubeaid": {
"command": "node",
"args": ["/home/you/kubeaid-mcp-ts/dist/index.js"]
}
}
}
```
If the file already has other keys (e.g. `preferences`), keep them and add
`mcpServers` alongside — don't overwrite the file.
3. **Fully quit and reopen** Claude Desktop. Closing the window is not enough on
Linux — the process must actually exit. The server then appears under
Settings → Developer → Local MCP servers.
**Enabling writes:** add the options via an `env` block — e.g. make the local
cluster writable while protecting production:
```json
{
"mcpServers": {
"kubeaid": {
"command": "node",
"args": ["/home/you/kubeaid-mcp-ts/dist/index.js"],
"env": {
"KUBEAID_CONTEXT": "kind-kubeaid",
"KUBEAID_ALLOW_WRITES": "true",
"KUBEAID_PROTECTED_CONTEXTS": "prod-cluster,another-prod-cluster"
}
}
}
}
```
Add `"KUBEAID_ALLOW_EXEC": "true"` for the `exec_command` tool, and re-run
step 3 after changing the config.
**Notes:**
- `command`/`args` must use absolute paths; GUI apps don't inherit your shell
`PATH`, and Node needs the absolute path to `dist/index.js`.
- Destructive tools carry a `destructiveHint`, so Desktop still prompts you per
action — the env vars control what's *possible*; the prompt is your confirmation.
- If your account is enterprise-managed, an admin policy can disable local MCP
entirely, in which case no local config will load.
## Safety
The server is **read-only by default** — the read tools only call non-mutating
verbs (get, list, watch, log). Mutating tools exist but are gated:
- `KUBEAID_ALLOW_WRITES=true` must be set for `apply_manifest`, `patch_resource`,
`delete_resource`, `scale_deployment`, and `rollout_restart` to be exposed at
all.
- `KUBEAID_ALLOW_EXEC=true` (in addition) is required for `exec_command`.
- `KUBEAID_PROTECTED_CONTEXTS` lists contexts that may **never** be written to or
exec'd into, even with the flags above — put your production contexts here.
- Tools are annotated (`readOnlyHint` / `destructiveHint`) so clients can prompt
before risky actions.
The server authenticates with your kubeconfig credentials, so it can only do
what your account is already permitted to do.
## Configuration
All configuration is read from the environment at startup. An MCP client passes
these via the server entry's `env` block (Claude Desktop) or `-e` flags (Claude
Code). A local `.env` file also works for development — see
[`.env.example`](./.env.example).
| Variable | Default | Meaning |
|----------|---------|---------|
| `KUBECONFIG` | `~/.kube/config` | Path to the kubeconfig file. |
| `KUBEAID_CONTEXT` | follows kubeconfig current-context (live) | Pin a fixed default context. Omit it to track current-context live, so `kubectl config use-context` switches the cluster mid-session. Individual tool calls can always override it. |
| `KUBEAID_REQUEST_TIMEOUT` | `30s` | Per-request timeout for Kubernetes API calls (e.g. `30s`, `1m`, or milliseconds). |
| `KUBEAID_ALLOW_WRITES` | `false` | Expose the mutating tools (apply/patch/delete/scale/rollout). |
| `KUBEAID_ALLOW_EXEC` | `false` | Expose `exec_command` (run commands in containers). |
| `KUBEAID_PROTECTED_CONTEXTS` | none | Comma-separated contexts that may never be written to or exec'd into. |
## Development
Drive the server by hand (no AI client needed) to inspect the raw protocol and
confirm which tools are registered:
```bash
npm run build
KUBECONFIG=~/.kube/config node scripts/drive.mjs # initialize + tools/list + prompts/list
```
TDQS
A4.2/5.0
Scored across 9 tools
Disambiguation5/5
Every tool targets a distinct Kubernetes resource or action (e.g., describe_pod vs describe_resource, list_pods vs list_deployments), with no overlapping purposes.
Naming Consistency5/5
All tools follow a consistent verb_noun pattern with lowercase and underscores (e.g., list_pods, get_events, describe_resource), making them predictable and easy to differentiate.
Tool Count5/5
With 9 tools, the surface is lean yet comprehensive for a diagnostic Kubernetes MCP server, covering essential inspection operations without unnecessary bloat.
Completeness4/5
The tool set covers core diagnostic workflows—listing, describing, logs, events—but misses operational actions like exec, port-forward, or resource creation. Minor gap given the diagnostic focus.
Maintenance
ActivityInactive
ResponsivenessNo issues