mcpField
πŸ€–
πŸ€– AI-Powered Kubernetes Assistant with MCP

πŸ€– AI-Powered Kubernetes Assistant with MCP

Local
github.com/bikramjitchawlaAI & Agents0Updated 5d ago

About πŸ€– AI-Powered Kubernetes Assistant with MCP

Kubernetes Diagnostic MCP is a self-hosted, read-only incident triage platform for teams operating Kubernetes clusters. It combines deterministic diagnostics and evidence with optional AI interpretation, tenant isolation, and reviewed recovery workflows.

Key features

  1. 01Diagnose common cluster resource failures
  2. 02Trace pod traffic paths and related incidents
  3. 03Compare snapshots to identify changes
  4. 04Query incidents in natural language
  5. 05Review recovery changes and verify results

Use cases

  1. 01Triage unhealthy workloads
  2. 02Investigate changes preceding an incident
  3. 03Trace service routing and network policy issues
  4. 04Review a proposed deployment rollback

MCP support

The `/api/mcp` endpoint accepts diagnostic requests and provides a capability manifest. It exposes cluster diagnostics to MCP clients without writing to the cluster.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

No install method listed yet

We haven’t collected a package or remote endpoint for this server. Follow the instructions in the project README.

Repository

Tools

No tool list yet

Local servers expose tools only once running on your machine, and the maintainer has not provided a tool list.

Details

From the project README

Kubernetes Diagnostic MCP

A read-only Kubernetes incident triage platform built with Next.js. It collects live cluster state through the official Kubernetes JavaScript client, runs a deterministic rules engine to surface findings, and optionally generates an AI-powered incident narrative β€” all without ever writing to your cluster.

Install: Self-hosting, OIDC/Keycloak, tenant isolation and Helm.

This version requires explicit tenant configuration and authenticated access. It does not use ambient cluster credentials or automatically import legacy shared history.


Features

Investigation and recovery workflows
  • Pod traffic path β€” inspect configured Ingress β†’ Service β†’ EndpointSlice β†’ Pod routes, port mappings, backend conditions, and ingress/egress NetworkPolicy isolation. See Pod networking and permission setup. Packet-level flow telemetry is not collected.
  • Historical investigation β€” reconstruct an incident timeline from retained events and snapshots, bound the current failure episode, and rank low-confidence investigation leads with evidence links and confirmation checks. Optional tenant-authenticated Helm CronJobs collect before incidents occur. See Historical investigation.
  • What changed? β€” compare scoped snapshots for deployment revisions, images, resource settings, configuration fingerprints, service routing changes, and optional Prometheus CPU/memory evidence. Correlations are labeled as hypotheses.
  • Related incidents β€” group findings using owner references, service selectors, unhealthy node placement, and failing PVC dependencies, with evidence for each link.
  • Fix and verify β€” propose supported Deployment reversions to an observed healthy baseline, preview a pinned GitOps manifest change, create a reviewed GitHub PR, and verify sustained recovery after merge.
  • Persistent history β€” atomic disk storage, with baseline and verification evidence retained for fix workflows.

See Investigation workflow setup and limitations for GitHub targets, optional Prometheus, persistent storage, API examples, and the recovery contract.

Diagnostic coverage
ResourceFailure modes detected
PodsCrashLoopBackOff, ImagePullBackOff, OOMKilled, scheduling failures, probe failures
WorkloadsDeployments, StatefulSets, DaemonSets, ReplicaSets, Jobs not at desired state
ServicesSelectors that resolve to zero ready endpoints
NodesNotReady, MemoryPressure, DiskPressure, PIDPressure, cordoned
HPAsCannot scale (AbleToScale=False), maxed at max replicas
PVCsPending (provisioner failure), Lost (backing PV gone)
CronJobsSuspended jobs with missed schedules
EventsCorrelated warning events across all resource types
Structured risk and impact model

Every finding carries two structured assessments in addition to the plain-text description:

  • ImpactAssessment β€” scope (pod / workload / service / namespace / node / cluster), affected resource references, affected replica counts, whether the issue is user-facing, and a summary sentence
  • RiskAssessment β€” risk level, confidence, blast radius, risk if ignored, risk if remediated, and the reasons behind the assessment

This model powers the top-risks list in the summary and lets the UI show structured context without parsing markdown.

Natural language query mode

Engineers can describe an incident in plain English instead of filling in form fields:

"checkout pods keep crashing since the last deploy"

The LLM extracts diagnostic intent (namespace, workload, focus areas, symptoms) from the description, validates it against live cluster inventory, and resolves it to a concrete DiagnosticScope. The deterministic engine then runs unchanged β€” the LLM only translates input, never generates findings.

Key behaviours:

  • Disambiguation β€” when a workload exists in multiple namespaces, a clarification panel lets the engineer pick before running
  • Namespace inference β€” when a workload name uniquely identifies a namespace, it is inferred automatically (with a confirmation step)
  • Safety gate β€” the resolver validates extracted namespace and workload names against the actual cluster before any diagnostic call
  • Edit fallback β€” the "Edit" button pre-fills form mode with the resolved values so engineers can correct the interpretation
  • Graceful degradation β€” Query mode is disabled automatically when no LLM key is configured
AI incident narrative

When GROQ_API_KEY or OPENAI_API_KEY is set and AI summary is enabled, the deterministic findings and markdown report are passed to an LLM which produces:

  • Executive summary
  • Likely root cause with evidence citations
  • Next actions
  • Read-only automation commands

The deterministic report returns first; the dashboard requests the optional narrative separately so provider latency does not delay the evidence. The AI narrative is rendered as formatted markdown in the Report section. The LLM is instructed not to invent resources, commands, or causes β€” it can only explain and prioritise what the deterministic engine already found. The tool is fully functional without any LLM key.

LLM priority: Groq (llama-3.3-70b-versatile) is used when GROQ_API_KEY is set; OpenAI (gpt-4o-mini) is the fallback.

UI
  • Form / Query toggle β€” switch between structured form input and natural language query mode; preference is persisted in localStorage
  • Namespace dropdown β€” auto-populated from the live cluster; falls back to a text input when the cluster is unreachable
  • Workload dropdown β€” refreshes automatically when the namespace changes
  • Cluster context selector β€” switch between kubeconfig contexts without restarting
  • Diagnostic run history β€” recent persisted runs shown in the sidebar; click any entry to reload its full result
  • Metric tiles β€” pod count, unhealthy pods, warning events, node health, PVC health, AI status
  • Findings panel β€” top 6 findings with severity badge, evidence list, and read-only commands
  • Rendered markdown report β€” the AI narrative or deterministic report is rendered with headings, code blocks, tables, and lists
API
MethodPathDescription
POST/api/mcpRun a diagnostic
GET/api/mcpCapability manifest
POST/api/nlq/parseParse a natural language query into a DiagnosticScope
GET/api/nlq/parseCheck whether NLQ mode is available
GET/api/namespacesList cluster namespaces
GET/api/workloads?namespace=List workloads in a namespace
GET/api/contextsList kubeconfig contexts
GET/api/historyList recent diagnostic runs
GET/api/history/:idRetrieve a full run by ID
POST/api/history/:id/narrativeGenerate optional AI narrative for saved evidence
GET/api/healthHealth check (no cluster access, used by k8s probes)
Authentication and isolation
  • Generic OIDC sign-in with a Keycloak setup guide; authorization code, PKCE, state, nonce and signed ID-token validation.
  • Tenant workspaces with viewer/operator/admin roles, separate Kubernetes credentials and namespace allowlists.
  • Tenant-partitioned history, baselines, fix plans and integration configuration.
  • Tenant API keys for automation; no shared global key or anonymous access.
  • Per-identity and per-tenant rate limits, bounded concurrent collection, paginated Kubernetes reads and deadlines.
  • Non-root Helm deployment with a PVC, read-only credential mounts, ingress policy and separate readiness/liveness checks.

Install or develop

Follow the installation guide to provision tenant credentials, configure your OIDC provider, create Secrets, and install the bundled Helm chart. The source repository is the download; build an image in your own registry. No release or image is published automatically.

For local development, configure APP_URL=http://localhost:3000 and TENANTS_CONFIG_FILE in .env.local, with explicit tenant kubeconfigs and either OIDC or a tenant API key, then run:

npm ci
npm run dev

Validation

npm test
npm run typecheck
npm run build

Tests cover deterministic diagnostics, tenant isolation, authentication/CSRF/roles, signed OIDC token validation, workload ownership, bounded collection and reviewed recovery workflows. CI also checks the container build, production dependency audit and Helm chart.

Environment variables

VariablePurpose
APP_URLCanonical application origin; HTTPS required in production
TENANTS_CONFIG_FILERequired administrator-managed tenant JSON configuration
OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRETBrowser sign-in provider configuration
OIDC_GROUPS_CLAIMTop-level ID-token array claim; defaults to groups
OIDC_SCOPESDefaults to openid profile email
DIAGNOSTICS_DATA_DIRPersistent tenant records and server-side sessions; defaults to .data
DIAGNOSTICS_HISTORY_LIMITUnpinned history retention per tenant; default 200, maximum 2,000
GROQ_API_KEY, GROQ_MODELOptional AI provider; requires tenant allowAi
OPENAI_API_KEY, OPENAI_MODELOptional fallback AI provider; requires tenant allowAi
APP_VERSION, BUILD_IDHealth endpoint metadata

GitHub and Prometheus credentials/targets are configured per tenant. See integration configuration.


API reference

POST /api/mcp
curl -X POST https://mcp-diagnostics.127.0.0.1.nip.io/api/mcp \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "agent": "kubernetes-diagnoser",
    "goal": "Find why checkout is failing",
    "input_context": {
      "namespace": "team-a",
      "workload": "checkout",
      "context": "team-a",
      "includeLogs": true,
      "includeNodes": false,
      "includeHpa": true,
      "enableAiSummary": false,
      "tailLines": 120,
      "maxPods": 60
    }
  }'

input_context fields

FieldTypeDefaultDescription
namespacestringdefaultNamespace to inspect
contextstringtenant contextMust match the configured tenant cluster
workloadstringβ€”Filter by workload name
labelSelectorstringβ€”Standard label selector e.g. app=checkout
includeLogsbooleantrueCollect logs from unhealthy pods
includeNodesbooleanfalseCollect node conditions (requires ClusterRole)
includeHpabooleantrueCollect HPA status
enableAiSummarybooleanfalseGenerate AI narrative
tailLinesnumber120Log lines per container (20–500)
maxPodsnumber60Max pods to collect (1–200)

Response shape

{
  "requestId": "uuid",
  "status": "ok | partial | failed",
  "generatedAt": "ISO-8601",
  "summary": {
    "health": "healthy | degraded | critical",
    "totalPods": 12,
    "unhealthyPods": 2,
    "notReadyNodes": 0,
    "pendingPvcs": 1,
    "warningEvents": 5,
    "criticalFindings": 0,
    "highFindings": 2,
    "topRisks": ["[HIGH] checkout is crash-looping: pod will not recover without a fix"]
  },
  "findings": [
    {
      "id": "pod-production-checkout-0-crashloop",
      "severity": "critical",
      "category": "runtime",
      "title": "Container app is in CrashLoopBackOff",
      "resource": { "kind": "Pod", "namespace": "team-a", "name": "checkout-0" },
      "signal": "CrashLoopBackOff",
      "evidence": ["Restart count: 10", "Last exit code: 1"],
      "impact": "Pod is not serving traffic.",
      "recommendedActions": ["Check logs for the root cause", "..."],
      "automation": [{ "command": "kubectl logs ...", "destructive": false, "requiresApproval": false }],
      "impactAssessment": { "scope": "workload", "userFacing": true, "summary": "..." },
      "riskAssessment": { "level": "critical", "confidence": "high", "riskIfIgnored": "...", "blastRadius": "workload", "reasons": ["..."] }
    }
  ],
  "runbook": ["Step 1...", "Step 2..."],
  "output": "# Kubernetes Diagnostic Report\n...",
  "snapshot": { /* full raw cluster state */ },
  "metadata": { "aiStatus": "success | skipped | disabled | failed", "model": "llama-3.3-70b-versatile" }
}
POST /api/nlq/parse

Parses a natural language incident description into a validated DiagnosticScope.

curl -X POST https://mcp-diagnostics.127.0.0.1.nip.io/api/nlq/parse \
  -H "Content-Type: application/json" \
  -d '{ "query": "checkout pods keep crashing since last deploy", "context": "kind-test-cluster" }'

Response (resolved)

{
  "intent": { "namespace": "team-a", "workload": "checkout", "focus": ["pods", "logs"], "confidence": "high", ... },
  "resolvedContext": { "namespace": "team-a", "workload": "checkout", "includeLogs": true, ... },
  "requiresConfirmation": false,
  "confirmationPrompt": null
}

Response (ambiguous)

{
  "intent": { ... },
  "resolvedContext": null,
  "requiresConfirmation": true,
  "confirmationPrompt": "Found 'checkout' in 2 namespaces: production, staging.",
  "clarificationOptions": {
    "field": "namespace",
    "prompt": "Choose a namespace for \"checkout\".",
    "options": [
      { "label": "production", "value": "production", "resolvedContext": { ... } },
      { "label": "staging", "value": "staging", "resolvedContext": { ... } }
    ]
  }
}

Returns 503 when no LLM key is configured. Call GET /api/nlq/parse first to check availability.


Project structure

β”œβ”€β”€ agents/
β”‚   └── mcpAgentRunner.ts           # Orchestrates collection β†’ analysis β†’ AI β†’ history
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ mcp/route.ts            # POST /api/mcp
β”‚   β”‚   β”œβ”€β”€ nlq/parse/route.ts      # POST /api/nlq/parse, GET /api/nlq/parse
β”‚   β”‚   β”œβ”€β”€ namespaces/route.ts     # GET  /api/namespaces
β”‚   β”‚   β”œβ”€β”€ workloads/route.ts      # GET  /api/workloads
β”‚   β”‚   β”œβ”€β”€ history/route.ts        # GET  /api/history
β”‚   β”‚   β”œβ”€β”€ history/[id]/route.ts   # GET  /api/history/:id
β”‚   β”‚   β”œβ”€β”€ contexts/route.ts       # GET  /api/contexts
β”‚   β”‚   └── health/route.ts         # GET  /api/health
β”‚   └── page.tsx                    # Dashboard UI (form + query modes)
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ diagnostics/
β”‚   β”‚   β”œβ”€β”€ analyzer.ts             # Deterministic Kubernetes rules engine
β”‚   β”‚   β”œβ”€β”€ formatter.ts            # Markdown report and summary builder
β”‚   β”‚   └── __tests__/
β”‚   β”‚       └── analyzer.test.ts    # 27 unit tests, no kubeconfig needed
β”‚   β”œβ”€β”€ nlq/
β”‚   β”‚   β”œβ”€β”€ types.ts                # ExtractedIntent, NLQParseResponse, ClusterInventory
β”‚   β”‚   β”œβ”€β”€ parser.ts               # LLM call + Zod schema validation
β”‚   β”‚   β”œβ”€β”€ resolver.ts             # Deterministic parameter validation
β”‚   β”‚   β”œβ”€β”€ prompt.ts               # Prompt construction
β”‚   β”‚   β”œβ”€β”€ inventory.ts            # Cluster namespace + workload fetcher
β”‚   β”‚   └── __tests__/
β”‚   β”‚       β”œβ”€β”€ parser.test.ts      # JSON parsing and schema validation
β”‚   β”‚       └── resolver.test.ts    # Resolution logic, no LLM needed
β”‚   β”œβ”€β”€ llm/
β”‚   β”‚   └── client.ts               # Groq β†’ OpenAI client builder
β”‚   β”œβ”€β”€ kubernetes/
β”‚   β”‚   └── collector.ts            # Kubernetes API client and snapshot builder
β”‚   β”œβ”€β”€ store/
β”‚   β”‚   └── history.ts              # Persistent run history and baseline selection
β”‚   β”œβ”€β”€ ratelimit.ts                # Bounded fixed-window rate limiter
β”‚   └── validation.ts               # Zod request schema and normalisation
β”œβ”€β”€ lib/auth/                       # OIDC, server sessions and route authorization
β”œβ”€β”€ lib/tenancy/                    # Identity bindings, roles and scope authorization
β”œβ”€β”€ deploy/helm/                    # Supported self-hosted installation
β”œβ”€β”€ types/
β”‚   └── mcp.ts                      # Full TypeScript type contract
β”œβ”€β”€ k8s/                            # Kubernetes manifests
β”‚   β”œβ”€β”€ namespace.yaml
β”‚   β”œβ”€β”€ rbac.yaml
β”‚   β”œβ”€β”€ deployment.yaml
β”‚   β”œβ”€β”€ ingress.yaml
β”‚   └── secret.example.yaml
β”œβ”€β”€ vitest.config.ts                # Test configuration
└── Dockerfile                      # Multi-stage production build

RBAC requirements

Each tenant uses a dedicated read-only credential restricted to its configured namespaces. Start from the namespace Role/RoleBinding example. The application service account has no cluster-wide permissions and no automatically mounted token. Node access requires an explicit tenant capability and additional cluster-level permission.

See the self-hosting guide for credential rotation, isolation checks, storage limits, migration from shared history, and the shared-hosted roadmap.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.