kubernetools MCP Server
oficialHelp AI agents write accurate, up-to-date Kubernetes manifests by giving them the official Kubernetes API reference, so they can look up kinds, fields, and nested types with current specs across the latest and three previous Kubernetes versions
Documentación
kubernetools/mcp-server
Imagen de contenedor para el servidor MCP kubernetools.
Registro: ghcr.io/kubernetools/mcp-server
Inicio rápido
Modo anónimo (uso local)
No se requiere autenticación; todas las conexiones están limitadas por tasa por IP de origen según el límite del nivel gratuito.
podman run -d \
-p 3000:3000 \
-e K8S_VERSIONS=v1.33 \
ghcr.io/kubernetools/mcp-server:latest
Con autenticación por clave API
# 1. Create a key store file
echo '[{"key":"mykey","tier":"free"}]' > keys.json
# 2. Start the server
podman run -d \
-p 3000:3000 \
-v "$(pwd)/keys.json:/keys.json:ro" \
-e K8S_VERSIONS=v1.33,v1.34,v1.35,v1.36 \
-e KEY_STORE_PATH=/keys.json \
ghcr.io/kubernetools/mcp-server:latest
Configuración
| Parámetro | Variable de entorno | Descripción |
|---|---|---|
| Versiones de Kubernetes | K8S_VERSIONS | Lista separada por comas de versiones a precargar (ej. v1.33,v1.34). Por defecto v1.33. |
| Token de GitHub | GITHUB_TOKEN | Token de acceso personal (sin permisos adicionales necesarios). Opcional; aumenta el límite de tasa de la API de GitHub de 60 a 5 000 req/h — recomendado al cargar múltiples versiones. |
| Almacén de claves | KEY_STORE_PATH | Ruta al archivo JSON de claves API (montarlo en el contenedor). Si se omite, el servidor se ejecuta en modo anónimo: no se requiere autenticación y todas las conexiones están limitadas por tasa por IP de origen según el límite del nivel gratuito. |
| Hosts permitidos | ALLOWED_HOSTS | Lista separada por comas de valores de cabecera Host a aceptar (ej. mcp.example.com,mcp.example.com:443). Si se omite, la validación de host está deshabilitada — adecuado solo para desarrollo local. Configurar siempre en producción para prevenir ataques de reenlace DNS. |
| Redirección de navegador | BROWSER_REDIRECT_URL | URL a la que redirigir las solicitudes GET simples de navegador. Los clientes MCP se detectan mediante Accept: text/event-stream; los navegadores reciben 307 a esta URL en su lugar. Si se omite, los GET de navegador devuelven 400. |
| Nivel de registro | RUST_LOG | Filtro de nivel de registro (ej. info, debug, mcp=debug). |
| Puerto | --publish | El servidor escucha en el puerto 3000. |
Autenticación
Almacén de claves API
El almacén de claves es un arreglo JSON plano cargado una vez al inicio:
[
{ "key": "free-key-abc", "tier": "free" },
{ "key": "paid-key-xyz", "tier": "paid" }
]
Cada solicitud debe incluir la clave en la cabecera Authorization:
Authorization: Bearer free-key-abc
Las solicitudes sin una clave válida reciben 401 Unauthorized.
Modo anónimo
Cuando KEY_STORE_PATH no está configurado, el servidor se ejecuta sin autenticación. Todas las conexiones son aceptadas y limitadas por tasa por IP de origen según el límite del nivel gratuito. Conveniente para uso local; no exponer públicamente.
Niveles y límites de tasa
| Nivel | Límite |
|---|---|
free | 10 solicitudes / minuto, ráfaga 10 |
paid | ~1 000 solicitudes / segundo, ráfaga 1 000 (efectivamente ilimitado) |
Las solicitudes que exceden el límite reciben 429 Too Many Requests. Los límites se rastrean por clave API, no por IP.
Conexión de un cliente MCP
El servidor implementa el transporte HTTP transmitible MCP. El endpoint es:
http://<host>:<port>/[?version=<k8s-version>]
El parámetro de consulta version selecciona qué versión de Kubernetes usar para la sesión. Si se omite, se usa la primera versión cargada. Una versión desconocida devuelve 400 Bad Request.
Claude Desktop
Agregar lo siguiente a claude_desktop_config.json:
{
"mcpServers": {
"kubernetools": {
"url": "http://localhost:3000/?version=v1.36",
"headers": {
"Authorization": "Bearer mykey"
}
}
}
}
Herramientas disponibles
list_resources
Descubrimiento ligero — devuelve una entrada por recurso, ordenado por (group, kind, api_version). Usar primero para encontrar nombres de tipo.
Filtros opcionales: group (ej. "apps", "core"), api_version (ej. "v1").
get_resource
Detalle completo del recurso — campos, spec, status y campos de lista — suficiente para escribir un manifiesto en una llamada. Requerido: kind. Opcional: group, api_version (por defecto la más reciente).
Los campos con un type_ref no nulo y sub_fields vacío deben ser explorados con get_type.
get_type
Explorar un único tipo compuesto referenciado mediante type_ref en la salida de get_resource. Requerido: type_name (ej. "Container", "PodFailurePolicy").
Flujo de consulta típico
list_resources → discover kind names and groups
└─ get_resource(kind="Deployment") → see all top-level fields + spec/status
└─ get_type(type_name="...") → drill into any complex type_ref
Verificación de estado
GET /healthz en el puerto 3000.
- Devuelve
503 Service Unavailable(cuerpo:loading) mientras se cargan los documentos de la API de Kubernetes. - Devuelve
200 OK(cuerpo:ok) una vez que el servidor está listo.
Este endpoint omite la autenticación y la limitación de tasa.
Usarlo para sondas de inicio, disponibilidad y actividad:
startupProbe:
httpGet:
path: /healthz
port: 3000
failureThreshold: 30 # allow up to 5 min for version loading
periodSeconds: 10
readinessProbe:
httpGet:
path: /healthz
port: 3000
livenessProbe:
httpGet:
path: /healthz
port: 3000
initialDelaySeconds: 10
Respuestas de error
| Estado HTTP | Causa |
|---|---|
307 Temporary Redirect | GET de navegador cuando BROWSER_REDIRECT_URL está configurado |
400 Bad Request | GET de navegador cuando BROWSER_REDIRECT_URL no está configurado, o el parámetro version nombra una versión no cargada al inicio |
401 Unauthorized | Cabecera Authorization: Bearer <key> faltante o inválida |
429 Too Many Requests | Límite de tasa excedido para el nivel de la clave |
Los errores a nivel MCP (nombre de herramienta desconocido, argumento requerido faltante, tipo no encontrado) se devuelven como contenido de error MCP dentro de una respuesta 200 normal.
Ejemplos
Múltiples versiones de Kubernetes
podman run -d \
-p 3000:3000 \
-v "$(pwd)/keys.json:/keys.json:ro" \
-e K8S_VERSIONS=v1.33,v1.34,v1.35,v1.36 \
-e GITHUB_TOKEN=ghp_... \
-e KEY_STORE_PATH=/keys.json \
ghcr.io/kubernetools/mcp-server:latest
Configuración de producción con validación de host
podman run -d \
-p 3000:3000 \
-v "$(pwd)/keys.json:/keys.json:ro" \
-e K8S_VERSIONS=v1.36 \
-e KEY_STORE_PATH=/keys.json \
-e ALLOWED_HOSTS=mcp.example.com,mcp.example.com:443 \
-e BROWSER_REDIRECT_URL=https://example.com/docs \
ghcr.io/kubernetools/mcp-server:latest
Registro de depuración
podman run -d \
-p 3000:3000 \
-e K8S_VERSIONS=v1.33 \
-e RUST_LOG=debug \
ghcr.io/kubernetools/mcp-server:latest
Fijar a una versión específica
podman run -d \
-p 3000:3000 \
-e K8S_VERSIONS=v1.33 \
ghcr.io/kubernetools/mcp-server:0.1.0
Imagen
Construida sobre registry.access.redhat.com/hi/core-runtime:2.42-openssl — un runtime mínimo, sin distribución, con glibc + OpenSSL. Sin shell ni gestor de paquetes.