mcp-k8s-context-server
by Krishna1704M
README.md
# 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 |
---
## 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
```bash
# 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
```bash
# Install minikube, kubectl, docker
minikube version # >= 1.32
kubectl version # >= 1.28
docker version # >= 24
```
### Step 1 — Start minikube
```bash
minikube start --cpus=2 --memory=4096
```
### Step 2 — Enable metrics-server (required for `get_resource_trends`)
```bash
minikube addons enable metrics-server
```
### Step 3 — Build and load the image into minikube
```bash
# 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
```bash
# 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
```bash
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
```bash
# 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:
```bash
# 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.
### `get_resource_trends`
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
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues