K8s MCP Symfony — Diagnose Kubernetes with ChatGPT, safely
Modern Kubernetes clusters expose a lot of useful information.
But let’s be honest:
- Troubleshooting often requires many
kubectlcommands - Pod status, events and logs are spread across different resources
- Giving an AI assistant unrestricted access to a cluster is dangerous
- Copying logs and manifests manually quickly becomes painful
So I built K8s MCP Symfony.
It is a read-only Model Context Protocol server that lets ChatGPT and other MCP clients inspect and diagnose Kubernetes clusters.
The project is built with Symfony and secured with OAuth 2.1.
What does it provide?
The first release exposes a focused set of Kubernetes tools:
k8s_get_cluster_infok8s_list_namespacesk8s_list_nodesk8s_list_podsk8s_get_podk8s_get_pod_logsk8s_list_eventsk8s_diagnose_pod
For example, you can ask your assistant:
Diagnose the pod checkout-api-7d9c8f8f56-k2m4p
in the production namespace.
The server can correlate:
- Pod status
- Container states
- Kubernetes events
- Current or previous logs
- Restart information
Instead of manually executing several commands, the assistant receives structured evidence through MCP.
Architecture: simple by design
ChatGPT or MCP client
↓
OAuth 2.1 access token
↓
K8s MCP Symfony
↓
Read-only Kubernetes API
The Symfony application implements the MCP JSON-RPC endpoint and translates tool calls into controlled Kubernetes API requests.
It does not execute kubectl.
It communicates directly with the Kubernetes API using a dedicated service account.
Security first
Connecting an AI assistant to Kubernetes requires strict boundaries.
K8s MCP Symfony is read-only by design.
Kubernetes API restrictions
Only HTTP GET requests are allowed.
Resources must be present in an explicit allowlist.
Dangerous subresources are rejected, including:
execattachportforwardproxyephemeralcontainers- Service-account token creation
The service account only receives Kubernetes permissions such as:
verbs:
- get
- list
- watch
There is no permission to create, update, patch or delete resources.
Namespace restrictions
The server can also be restricted to selected namespaces:
K8S_ALLOWED_NAMESPACES=production,staging
This prevents the MCP client from exploring unrelated namespaces.
OAuth scopes
Calling Kubernetes tools requires an OAuth access token.
The default scopes are:
openid
k8s.read
Tools that expose logs also require:
k8s.logs
This makes it possible to authorize cluster inspection without automatically granting access to application logs.
Automatic redaction
Every Kubernetes response is sanitized before being returned.
The sanitizer removes or hides:
- Secret values
- Service-account tokens
- Passwords
- API keys
- Private keys
- Authorization headers
- Database URLs
- Sensitive environment variables
- Managed fields
- Last-applied configurations
Secret objects can expose their metadata, but never their data or stringData content.
Logs and responses are also bounded to avoid sending unlimited amounts of cluster data to the MCP client.
Quick start
Clone the repository:
git clone https://git.small-project.dev/pub/apps/k8s-mcp-symfony.git
cd k8s-mcp-symfony
Create your local configuration:
cp .env .env.local
composer install
Configure the MCP endpoint and OAuth provider:
MCP_PUBLIC_URL=https://k8s-mcp.example.com/mcp
MCP_OAUTH_RESOURCE=https://k8s-mcp.example.com/mcp
MCP_OAUTH_ISSUER=https://sso.example.com/realms/mcp
MCP_OAUTH_JWKS_URI=https://sso.example.com/realms/mcp/protocol/openid-connect/certs
MCP_OAUTH_READ_SCOPE=k8s.read
MCP_OAUTH_LOGS_SCOPE=k8s.logs
Then configure Kubernetes access:
K8S_API_URL=https://kubernetes.default.svc
K8S_API_TOKEN=
K8S_ALLOWED_NAMESPACES=production,staging
K8S_LOGS_ENABLED=true
Start the application:
docker compose up --build
The local MCP endpoint is available at:
http://localhost:8080/mcp
Kubernetes deployment
The repository contains Kubernetes templates for:
- Service account
- Read-only ClusterRole
- ClusterRoleBinding
- Deployment
- Service
- Ingress
The application can therefore run directly inside the cluster and use its mounted service-account token.
Release pipelines validate the PHP project, run PHPStan and PHPUnit, build the container image and deploy tagged versions to Kubernetes.
A release can be created with:
bin/release --patch
Why Symfony?
Symfony provides everything needed for a small remote MCP service:
- HTTP routing
- Dependency injection
- HTTP client
- Environment configuration
- Testable services
- Structured JSON responses
The MCP implementation remains small while the Kubernetes and security layers stay isolated and testable.
Current limits
The project intentionally does not modify the cluster.
You cannot use it to:
- Restart a Deployment
- Delete a Pod
- Scale a workload
- Apply a manifest
- Execute a command inside a container
These operations should remain behind a separate and much stricter approval process.
The goal of this server is diagnosis, not autonomous cluster administration.
Links
Git repository:
https://git.small-project.dev/pub/apps/k8s-mcp-symfony
License:
GNU GPL v3.
Feedback welcome
The first release focuses on safe pod and cluster diagnostics.
Which Kubernetes diagnostic tool should be added next?
- Deployment rollout analysis?
- Service and endpoint diagnostics?
- PVC and storage inspection?
- Resource usage and capacity reports?
- Ingress and certificate diagnostics?
Top comments (0)