Skip to main content
Glama
ziyuyu23

k8s-readonly-mcp

by ziyuyu23

k8s-readonly-mcp

A read-only Model Context Protocol (MCP) server that lets an LLM inspect a Kubernetes cluster — list pods, read logs, describe resources — but never mutate it.

Why I built it

I spend a lot of time embedded in customer Kubernetes environments. The most common thing I want from an LLM is "help me understand what's happening in this cluster" — without ever giving it the ability to change anything. So I built the safety in structurally rather than trusting the model to behave.

Every tool call routes through a single function that checks the kubectl verb against an allow-list of read-only verbs (get, describe, logs, top, …). There is no code path that can apply, delete, scale, or exec. If the model asks for a mutation, the server refuses. This is the same least-privilege, human-in-the-loop instinct that any production agent needs.

Related MCP server: kubernetes-mcp

What it does

Tool

Description

list_namespaces

List all namespaces

list_pods

List pods in a namespace (or all namespaces)

describe_pod

Full status, events, and config for one pod

get_pod_logs

Last N lines of a pod's logs

list_deployments

Deployments and their ready/up-to-date status

Quick start

# 1. Install (using uv — https://docs.astral.sh/uv/)
uv sync

# 2. Make sure kubectl points at a cluster.
#    A local cluster is perfect for trying this safely:
#    kind create cluster   (or: minikube start)
kubectl get nodes

# 3. Run the server
uv run k8s-readonly-mcp

Connect it to Claude Desktop

Add this to your Claude Desktop MCP config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "k8s-readonly": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/k8s-readonly-mcp", "run", "k8s-readonly-mcp"]
    }
  }
}

Then ask Claude things like "What pods are failing in the default namespace, and why?" — it will call list_pods and describe_pod, reason over the output, and explain — but it physically cannot change your cluster.

Design decisions

  • Allow-list, not block-list. I enumerate what's permitted rather than trying to block bad verbs. A block-list is one forgotten verb away from a mutation; an allow-list fails closed.

  • One chokepoint. All kubectl execution goes through _run_kubectl. The security boundary is one function you can audit in 30 seconds.

  • Timeouts and clear errors. Calls time out and surface kubectl's stderr instead of hanging or failing silently — the model gets actionable feedback.

What I'd do next

  • Add resource-level scoping (restrict to specific namespaces per connection).

  • Stream large log outputs instead of buffering.

  • Add a small eval that checks the server refuses every mutating verb.

License

MIT

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ziyuyu23/k8s-readonly-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server