A Model Context Protocol (MCP) server that provides tools for interacting with Kubernetes clusters.
- Resource Management: Get, list, describe, create, apply, delete, and patch Kubernetes resources
- Pod Operations: Get logs, execute commands, and set up port forwarding
- Context Management: List, get, and switch between Kubernetes contexts
- Cluster Information: Get API resources and cluster health status
- Multiple Authentication Modes: Support for kubeconfig, in-cluster, OAuth 2.1, and federated multi-cluster authentication
- Multi-Cluster Support: Federation with Cluster API (CAPI) for managing workload clusters from a management cluster
- Multiple Transport Types: Support for stdio and streamable HTTP
- Safety Features: Non-destructive mode, dry-run capability, and operation restrictions
- OAuth 2.1 Support: Secure token-based authentication with Dex OIDC (default) and Google OAuth providers
- Production-Grade Observability: OpenTelemetry instrumentation with Prometheus metrics and distributed tracing
go install github.com/giantswarm/mcp-kubernetes@latest# Start the MCP server with default settings (stdio transport, kubeconfig authentication)
mcp-kubernetes serve
# Start with debug logging
mcp-kubernetes serve --debug
# Start with in-cluster authentication (when running as a pod in Kubernetes)
mcp-kubernetes serve --in-clusterThe server supports multiple authentication modes:
Uses standard kubeconfig file authentication. The server will look for kubeconfig in the default locations (~/.kube/config) or use the KUBECONFIG environment variable.
# Use default kubeconfig
mcp-kubernetes serve
# Use specific kubeconfig (via environment variable)
KUBECONFIG=/path/to/kubeconfig mcp-kubernetes serveUses service account token when running inside a Kubernetes pod. This mode automatically uses the mounted service account credentials.
# Enable in-cluster authentication
mcp-kubernetes serve --in-clusterRequirements for in-cluster mode:
- Must be running inside a Kubernetes pod
- Service account token must be mounted at
/var/run/secrets/kubernetes.io/serviceaccount/token - CA certificate must be available at
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt - Namespace must be available at
/var/run/secrets/kubernetes.io/serviceaccount/namespace
Uses OAuth 2.1 with Dex OIDC (default) or Google OAuth provider for secure, token-based authentication (available for HTTP transports only).
# Start with Dex OAuth authentication (default provider)
mcp-kubernetes serve \
--transport=streamable-http \
--enable-oauth \
--oauth-base-url=https://mcp.example.com \
--dex-issuer-url=https://dex.example.com \
--dex-client-id=mcp-kubernetes \
--dex-client-secret=YOUR_DEX_SECRET \
--dex-connector-id=github \
--registration-token=YOUR_SECURE_TOKEN
# Or use Google OAuth provider
mcp-kubernetes serve \
--transport=streamable-http \
--enable-oauth \
--oauth-provider=google \
--oauth-base-url=https://mcp.example.com \
--google-client-id=YOUR_CLIENT_ID \
--google-client-secret=YOUR_CLIENT_SECRET \
--registration-token=YOUR_SECURE_TOKENSee docs/oauth.md for detailed OAuth setup and configuration.
Enables access to multiple workload clusters through a management cluster using Cluster API (CAPI). The server discovers workload clusters dynamically and uses user impersonation for RBAC enforcement on each cluster.
# Enable federation mode with OAuth
mcp-kubernetes serve \
--transport=streamable-http \
--in-cluster \
--enable-oauth \
--downstream-oauth \
--enable-capi \
--oauth-base-url=https://mcp.example.com \
--dex-issuer-url=https://dex.example.com \
--dex-client-id=mcp-kubernetes \
--dex-client-secret=YOUR_DEX_SECRETSecurity model:
- Management Cluster RBAC: Users must have permission to list CAPI Cluster resources and read kubeconfig secrets
- Workload Cluster RBAC: Operations use impersonation headers, delegating authorization to each cluster's RBAC policies
- User Isolation: Cached clients are keyed by (cluster, user) pairs to prevent cross-user access
Impersonation headers added to workload cluster requests:
Impersonate-User: User's email from OAuthImpersonate-Group: User's groups from OAuthImpersonate-Extra-agent:mcp-kubernetes(for audit trail)
SSO Token Passthrough Mode (Alternative):
For organizations where workload cluster API servers are configured with OIDC authentication, an alternative authentication mode forwards the user's SSO token directly to workload clusters instead of using impersonation:
# Helm values for SSO passthrough mode
capiMode:
enabled: true
workloadClusterAuth:
mode: "sso-passthrough" # Instead of default "impersonation"
caSecretSuffix: "-ca" # CA-only secrets (no admin credentials needed)| Aspect | Impersonation (default) | SSO Passthrough |
|---|---|---|
| ServiceAccount privileges | High (kubeconfig secrets) | Low (CA secrets only) |
| Kubeconfig secret access | Required | Not required |
| WC API server requirements | None | OIDC configuration required |
| Audit trail | Shows impersonated user | Shows direct OIDC user |
| Fallback behavior | N/A | None (by design) |
Important: There is no automatic fallback between modes. If SSO passthrough fails (e.g., WC API server rejects the token), the operation fails. This is intentional - mixing modes would require maintaining access to admin credentials, defeating the security benefit.
See docs/sso-passthrough-wc.md for detailed configuration and requirements.
The server includes comprehensive OpenTelemetry instrumentation for production monitoring:
- Metrics: Prometheus-compatible metrics for HTTP requests, Kubernetes operations, and sessions
- Distributed Tracing: OpenTelemetry traces for request flows and K8s API calls
- Metrics Endpoint:
/metricsendpoint for Prometheus scraping
# Enable instrumentation (enabled by default)
INSTRUMENTATION_ENABLED=true
# Configure metrics exporter (prometheus, otlp, stdout)
METRICS_EXPORTER=prometheus
# Configure tracing exporter (otlp, stdout, none)
TRACING_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# Set trace sampling rate (0.0 to 1.0)
OTEL_TRACES_SAMPLER_ARG=0.1Available Metrics:
http_requests_total- HTTP request counterhttp_request_duration_seconds- HTTP request duration histogrammcp_kubernetes_operations_total- Kubernetes operation counter (management + workload scopes)mcp_kubernetes_operation_duration_seconds- K8s operation duration histogramkubernetes_pod_operations_total- Pod operation counteroauth_downstream_auth_total- OAuth authentication counteractive_port_forward_sessions- Active port-forward sessions gauge
See docs/observability.md for detailed metrics documentation, Prometheus queries, and alerting examples.
For local development and direct integration with MCP clients:
mcp-kubernetes serve --transport stdioFor network-accessible deployments with OAuth support:
mcp-kubernetes serve --transport streamable-http --http-addr :8080# Safety and operation modes
--non-destructive # Enable non-destructive mode (default: true)
--dry-run # Enable dry run mode (default: false)
# Performance tuning
--qps-limit 20.0 # QPS limit for Kubernetes API calls
--burst-limit 30 # Burst limit for Kubernetes API calls
# Authentication
--in-cluster # Use in-cluster authentication instead of kubeconfig
--enable-oauth # Enable OAuth 2.1 authentication (for HTTP transports)
--oauth-base-url string # OAuth base URL (e.g., https://mcp.example.com)
--google-client-id string # Google OAuth Client ID
--google-client-secret string # Google OAuth Client Secret
--registration-token string # OAuth client registration access token
--allow-public-registration # Allow unauthenticated OAuth client registration
# Debugging
--debug # Enable debug logging
# Transport-specific options
--transport string # Transport type: stdio or streamable-http
--http-addr :8080 # HTTP server address (for streamable-http)
--http-endpoint /mcp # HTTP endpoint path (default: /mcp)
--disable-streaming # Disable streaming for streamable-http transportThe recommended way to deploy mcp-kubernetes in a Kubernetes cluster is using the Helm chart, which handles RBAC, Ingress, TLS, and OAuth configuration.
# Add the Giant Swarm app catalog
helm repo add giantswarm https://giantswarm.github.io/giantswarm-catalog/
# Install with default configuration
helm install mcp-kubernetes giantswarm/mcp-kubernetes
# Install with Ingress and TLS enabled
helm install mcp-kubernetes giantswarm/mcp-kubernetes \
--set ingress.enabled=true \
--set ingress.hosts[0].host=mcp.example.com \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=Prefix \
--set ingress.tls[0].secretName=mcp-kubernetes-tls \
--set ingress.tls[0].hosts[0]=mcp.example.com
# Install with OAuth enabled
helm install mcp-kubernetes giantswarm/mcp-kubernetes \
--set mcpKubernetes.oauth.enabled=true \
--set mcpKubernetes.oauth.baseURL=https://mcp.example.com \
--set mcpKubernetes.oauth.dex.issuerURL=https://dex.example.com \
--set mcpKubernetes.oauth.dex.clientID=mcp-kubernetes \
--set mcpKubernetes.oauth.existingSecret=mcp-kubernetes-oauthSee helm/mcp-kubernetes/values.yaml for all configuration options, including:
- Ingress: TLS termination, custom annotations, multiple hosts
- OAuth 2.1: Dex or Google providers, client registration, downstream OAuth
- CAPI Mode: Multi-cluster federation via Cluster API
- Observability: Prometheus ServiceMonitor, OpenTelemetry tracing
Once deployed with Ingress enabled, MCP clients connect to the /mcp endpoint:
{
"mcpServers": {
"kubernetes": {
"url": "https://mcp.example.com/mcp"
}
}
}The endpoint path is configurable via mcpKubernetes.httpEndpoint in the Helm values (default: /mcp).
The MCP server provides the following tools:
k8s_get_resource- Get a specific resourcek8s_list_resources- List resources with paginationk8s_describe_resource- Get detailed resource informationk8s_create_resource- Create a new resourcek8s_apply_resource- Apply resource configurationk8s_delete_resource- Delete a resourcek8s_patch_resource- Patch a resourcek8s_scale_resource- Scale deployments, replicasets, statefulsets
k8s_get_pod_logs- Get logs from pod containersk8s_exec_pod- Execute commands in pod containersk8s_port_forward_pod- Set up port forwarding to podsk8s_port_forward_service- Set up port forwarding to services
k8s_list_contexts- List available Kubernetes contextsk8s_get_current_context- Get the current contextk8s_switch_context- Switch to a different context
k8s_get_api_resources- Get available API resourcesk8s_get_cluster_health- Get cluster health information
make buildmake testmake lint- The server runs in non-destructive mode by default
- Supports dry-run mode for safe operation testing
- Allows restriction of operations and namespaces
- Follows Kubernetes RBAC when using in-cluster authentication
- OAuth 2.1 support with PKCE enforcement for HTTP transports
- Downstream OAuth authentication for per-user RBAC enforcement
Recommended Solutions:
- HashiCorp Vault
- AWS Secrets Manager
- Google Cloud Secret Manager
- Azure Key Vault
- Kubernetes External Secrets Operator
NEVER use environment variables for secrets in production because they:
- Are visible in process listings (
ps aux,docker inspect) - Get leaked in logs and error messages
- Have no audit trail or rotation support
- Are not encrypted at rest
- Cannot be securely deleted
For detailed setup and examples, see:
Development:
- Use environment variables only for local development
- Never commit secrets to Git
- Use pre-commit hooks (gitleaks, git-secrets)
- Generate secrets securely (avoid shell history)
Production:
- Store secrets in a secret manager (required)
- Enable encryption at rest for Kubernetes Secrets
- Rotate encryption keys every 90 days
- Enable audit logging and monitoring
- Use HTTPS with valid TLS certificates
- Follow the comprehensive production checklist
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.