kubernetools MCP Server

oficial

Help 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ámetroVariable de entornoDescripción
Versiones de KubernetesK8S_VERSIONSLista separada por comas de versiones a precargar (ej. v1.33,v1.34). Por defecto v1.33.
Token de GitHubGITHUB_TOKENToken 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 clavesKEY_STORE_PATHRuta 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 permitidosALLOWED_HOSTSLista 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 navegadorBROWSER_REDIRECT_URLURL 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 registroRUST_LOGFiltro de nivel de registro (ej. info, debug, mcp=debug).
Puerto--publishEl 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

NivelLímite
free10 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 HTTPCausa
307 Temporary RedirectGET de navegador cuando BROWSER_REDIRECT_URL está configurado
400 Bad RequestGET de navegador cuando BROWSER_REDIRECT_URL no está configurado, o el parámetro version nombra una versión no cargada al inicio
401 UnauthorizedCabecera Authorization: Bearer <key> faltante o inválida
429 Too Many RequestsLí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.