Skip to main content
Glama
Krishna1704M

mcp-k8s-context-server

by Krishna1704M

MCP K8s Context Server

A FastMCP server that exposes Kubernetes as a set of read-only tools consumable by LLMs, plus an analytics layer for pod-health analysis and resource-trend tracking.


Features

Tool

Description

list_pods(namespace)

List pods in a namespace with phase and restart info

get_pod_status(pod_name, namespace)

Detailed pod status, conditions, and container states

get_pod_logs(pod_name, namespace, tail_lines)

Tail recent pod logs

get_deployment_manifest(deployment_name, namespace)

Full deployment spec as JSON

analyze_pod_health(namespace, hours)

Analytics: scan logs, detect error patterns, rank unhealthy pods

get_resource_trends(deployment_name, namespace)

Analytics: CPU/memory from Metrics API with historical SQLite persistence


Related MCP server: Kube MCP

Project Structure

mcp-k8s-context-server/
├── k8s_mcp_server.py        # FastMCP server (all tools)
├── requirements.txt         # Python dependencies
├── Dockerfile               # Container image definition
├── k8s/
│   ├── serviceaccount.yaml  # ServiceAccount + Namespace
│   ├── role.yaml            # Least-privilege ClusterRole (read-only)
│   ├── rolebinding.yaml     # ClusterRoleBinding
│   └── deployment.yaml      # Deployment + Service
└── .github/
    └── workflows/
        └── ci.yml           # Build + kubeconform validation

Local Development

# Create and activate a virtual environment
python -m venv .venv && source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Run with local kubeconfig (falls back automatically from in-cluster config)
python k8s_mcp_server.py

In-Cluster Deployment (minikube)

Prerequisites

# Install minikube, kubectl, docker
minikube version   # >= 1.32
kubectl version    # >= 1.28
docker version     # >= 24

Step 1 — Start minikube

minikube start --cpus=2 --memory=4096

Step 2 — Enable metrics-server (required for get_resource_trends)

minikube addons enable metrics-server

Step 3 — Build and load the image into minikube

# Build locally
docker build -t mcp-k8s-server:latest .

# Load into minikube's image registry (no registry push needed)
minikube image load mcp-k8s-server:latest

# Verify the image is available
minikube image ls | grep mcp-k8s-server

Step 4 — Apply Kubernetes manifests

# Apply in dependency order: SA → Role → Binding → Deployment
kubectl apply -f k8s/serviceaccount.yaml
kubectl apply -f k8s/role.yaml
kubectl apply -f k8s/rolebinding.yaml
kubectl apply -f k8s/deployment.yaml

Step 5 — Verify the Pod is Running

kubectl get pods -n mcp-system
# Expected:
# NAME                              READY   STATUS    RESTARTS   AGE
# mcp-k8s-server-xxxxxxxxx-xxxxx   1/1     Running   0          30s

kubectl logs -n mcp-system deploy/mcp-k8s-server
# Expected: "Using in-cluster Kubernetes config (ServiceAccount token)"

Step 6 — Test read-only tools in-cluster

# Port-forward to access the server from your laptop
kubectl port-forward -n mcp-system svc/mcp-k8s-server 8000:8000 &

# Create a test pod to query
kubectl run nginx-test --image=nginx --restart=Never

# Test list_pods
curl -s http://localhost:8000/tools/list_pods \
  -H 'Content-Type: application/json' \
  -d '{"namespace":"default"}' | jq .

# Test get_pod_logs
curl -s http://localhost:8000/tools/get_pod_logs \
  -H 'Content-Type: application/json' \
  -d '{"pod_name":"nginx-test","namespace":"default","tail_lines":20}' | jq .

# Test analyze_pod_health
curl -s http://localhost:8000/tools/analyze_pod_health \
  -H 'Content-Type: application/json' \
  -d '{"namespace":"default","hours":1}' | jq .

Step 7 — Prove RBAC blocks write operations

The ServiceAccount has no write verbs. To confirm this:

# Exec into the pod and try to delete another pod using the SA token
MCP_POD=$(kubectl get pod -n mcp-system -l app=mcp-k8s-server -o jsonpath='{.items[0].metadata.name}')

kubectl exec -n mcp-system $MCP_POD -- \
  kubectl delete pod nginx-test --namespace=default \
  --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) \
  --server=https://kubernetes.default.svc \
  --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Expected output:

Error from server (Forbidden): pods "nginx-test" is forbidden:
  User "system:serviceaccount:mcp-system:mcp-server-sa" cannot delete
  resource "pods" in API group "" in the namespace "default"

This 403 Forbidden response from the API server is the live proof that the RBAC scoping works — the ServiceAccount can read but cannot modify any resource.


RBAC Least-Privilege Design

Philosophy

Grant only what is needed, explicitly deny everything else.

The MCP server is an observability tool — it reads cluster state to help operators and AI systems understand what's happening. It has no legitimate reason to create, modify, or delete any resource.

What is granted

Resource

Verbs

Reason

pods

get, list, watch

list_pods, get_pod_status, analyze_pod_health

pods/log

get, list, watch

get_pod_logs, analyze_pod_health

deployments

get, list, watch

get_deployment_manifest, get_resource_trends

metrics.k8s.io/pods

get, list

get_resource_trends (Metrics API)

What is explicitly NOT granted

Verb

Reason for exclusion

create

No tool creates any resource

update / patch

No tool modifies any resource

delete / deletecollection

Catastrophic if misused; no read tool needs it

escalate / bind

Prevents privilege escalation

This means a compromised MCP server cannot delete pods, scale deployments down to zero, modify secrets, or affect any running workload. The blast radius of a compromised MCP server is limited to reading information — not disrupting it.


Analytics Layer

analyze_pod_health

  1. Lists all pods in the namespace.

  2. Fetches up to 500 log lines per pod.

  3. Pattern-matches against a catalogue of known failure indicators:

    • OOMKilled, CrashLoopBackOff

    • Python/Java exceptions (Traceback, RuntimeError, etc.)

    • Panic, SIGSEGV/SIGKILL, Connection errors, Permission denied

    • Liveness/Readiness probe failures

  4. Computes a health score per pod (lower = worse).

  5. Returns pods ranked worst-first with error frequency counts.

  6. Persists results to SQLite for historical analysis.

  1. Resolves pod selector from the Deployment spec.

  2. Reads resource limits from pod specs.

  3. Queries the Kubernetes Metrics API (metrics.k8s.io/v1beta1) for live CPU/memory.

  4. Computes: average, peak, and % of limit for both CPU and memory.

  5. Persists each snapshot to mcp_analytics.db so trends build up across calls.

Requires metrics-server addon: minikube addons enable metrics-server


CI / Continuous Integration

The GitHub Actions workflow (.github/workflows/ci.yml) runs on every push and PR:

  1. Docker Build — builds the image without pushing (validates Dockerfile + dependencies).

  2. kubeconform — validates all k8s/*.yaml manifests against the Kubernetes 1.29 schema in strict mode.

  3. ruff — lints k8s_mcp_server.py for Python errors and style.


Environment Variables

Variable

Default

Description

MCP_DB_PATH

mcp_analytics.db

Path to the SQLite analytics database


License

MIT

F
license - not found
-
quality - not tested
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.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Read-only bank access for your AI agent. Connects Claude, ChatGPT, Cursor, Gemini, Codex.

  • Read-only access to Auralogs production logs: search logs, inspect errors, review AI analyses.

  • Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.

View all MCP Connectors

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/Krishna1704M/mcp-k8s-context-server'

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