Skip to main content
Glama
bansikah22

kube-observer-mcp

by bansikah22

kube-observer-mcp

An open-source MCP server providing concise, read-only Kubernetes inventory tools for AI agents.

The first release exposes two typed tools:

  • list_nodes: node name, Ready condition, Kubernetes version, OS, architecture.

  • list_pods(namespace): pod name, namespace, phase, ready container count, restart count.

It deliberately does not expose arbitrary kubectl, shell execution, Secrets, container environment, or mutation operations. The default Kubernetes RBAC only grants get and list on Nodes and Pods.

The multi-stage, lockfile-driven container is about 57 MB, uses the slim Debian Python runtime, runs as UID 10001, drops Linux capabilities, uses a read-only root filesystem with a bounded /tmp, and exposes a /health endpoint for container and Kubernetes probes. The base remains Debian slim because the Kubernetes and cryptography dependencies have well-tested wheels there; Alpine could introduce native-build complexity for little practical size gain. GHCR releases include BuildKit provenance and an SBOM attestation.

Architecture

flowchart LR
	Kagent[Kagent Agent] --> Remote[MCP Streamable HTTP]
	Remote --> Server[kube-observer-mcp]
	Server --> KubeAPI[Kubernetes API]
	Server --> Tools[Read-only tool group]
	Server --> Prompts[Reusable MCP prompts]
	Server --> Resources[Capability resource]

Tool groups are registered explicitly in src/kube_observer_mcp/tools/registry.py. Only read_only is registered by default. Future write-capable groups should be separate modules, require explicit enablement, and ship with distinct least-privilege RBAC and tests. MCP prompts provide reusable workflows; they do not grant permissions.

Related MCP server: mcp-k8s-context-server

Requirements

  • Python 3.11+

  • uv

  • Docker for image builds

  • A Kubernetes cluster for deployment

Local Development

Install dependencies and run tests:

uv sync --extra dev
uv run pytest

Run locally against an explicit kubeconfig:

KUBECONFIG=/path/to/kubeconfig uv run kube-observer-mcp

The Streamable HTTP endpoint listens on 0.0.0.0:8000/mcp. Use the official MCP Inspector or another MCP client to list and call list_nodes and list_pods. For the homelab, the private repo's K3d kubeconfig can be supplied without copying it into this repo:

KUBECONFIG=/absolute/path/to/homelab/.kube/noel-lab.yaml uv run kube-observer-mcp

For a local tool check from Python:

uv run python - <<'PY'
import asyncio
from mcp import Client

async def main():
	async with Client("http://127.0.0.1:8000/mcp") as client:
		print(await client.list_tools())
		print(await client.call_tool("list_nodes", {}))
		print(await client.call_tool("list_pods", {"namespace": "kagent"}))

asyncio.run(main())
PY

The repository's unit tests use mock Kubernetes objects and require no cluster. The K3d homelab integration check also confirmed that the tools return only the requested summary fields for Nodes and Pods.

Kubernetes Deployment

Images are published to GitHub Container Registry when a version tag is pushed. The workflow runs tests first and publishes multi-platform linux/amd64 and linux/arm64 images. From the repository root:

git tag v0.1.0
git push origin v0.1.0

The image will be tagged as 0.1.0, 0.1, the commit SHA, and latest. On first publication, open the package's GitHub settings and set its visibility to Public if this repository's deployment is meant to be public. Check the image name in deploy/kubernetes/deployment.yaml before changing it for a fork.

Apply the server namespace, ServiceAccount, and read-only RBAC:

kubectl apply -f deploy/kubernetes/rbac.yaml
kubectl apply -f deploy/kubernetes/deployment.yaml
kubectl rollout status deployment/kube-observer-mcp -n kube-observer-mcp
  1. Register the server and example Agent with Kagent:

kubectl apply -f deploy/kagent/remote-mcp-server.yaml
kubectl apply -f deploy/kagent/agent-homelab-inventory.yaml

The MCP endpoint is a ClusterIP service, not exposed publicly. Keep network access restricted to trusted in-cluster clients. Review the RBAC manifest and cluster boundary before deploying into production.

The Kagent integration manifests live separately in deploy/kagent/. They register a RemoteMCPServer in Kagent's namespace and provide an example Agent that selects only list_nodes and list_pods.

Extending The Server

Add new read-only tools in a focused module under src/kube_observer_mcp/tools/, then explicitly register that module in the tool-group registry. The create_server(tool_groups=...) factory takes an explicit group list; main() uses only read_only. Unknown groups fail closed. Add unit tests for response shape and error handling.

Reusable workflows belong in src/kube_observer_mcp/prompts.py; MCP resources belong beside server construction and should expose only intentionally public metadata. Prompts are guidance, not authorization. Kubernetes RBAC remains the enforcement boundary. Never add a generic command-execution tool. A future mutation feature must be an explicit separate tool group with separate RBAC, human approval, tests, and documentation.

The server currently exposes MCP prompt templates as reusable workflows; these are not the same as a model-vendor-specific “Agent Skills” package. A future skills adapter can be added separately without coupling tool authorization to prompt content.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides a read-only interface to Kubernetes clusters, enabling LLMs to list pods, get pod status and logs, fetch deployment manifests, and perform pod health analysis with resource trend tracking.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Lets AI agents inspect Kubernetes clusters in plain English, exposing read-only tools for pods, deployments, services, events, and logs, with mock and real backend support.
    MIT