kubernetools MCP Server

officiel

Aider les agents IA à rédiger des manifestes Kubernetes précis et à jour en leur fournissant la référence officielle de l'API Kubernetes, afin qu'ils puissent consulter les types, champs et types imbriqués avec les spécifications actuelles pour la dernière version de Kubernetes et les trois précédentes.

Documentation

kubernetools/mcp-server

Image conteneur pour le serveur MCP kubernetools.

Registre : ghcr.io/kubernetools/mcp-server

Démarrage rapide

Mode anonyme (usage local)

Aucune authentification requise ; toutes les connexions sont limitées en débit par IP source selon la limite du niveau gratuit.

podman run -d \
  -p 3000:3000 \
  -e K8S_VERSIONS=v1.33 \
  ghcr.io/kubernetools/mcp-server:latest

Avec authentification par clé 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

Configuration

ParamètreVariable d'env.Description
Versions KubernetesK8S_VERSIONSListe de versions séparées par des virgules à précharger (ex. v1.33,v1.34). Par défaut v1.33.
Jeton GitHubGITHUB_TOKENJeton d'accès personnel (aucune portée supplémentaire nécessaire). Optionnel ; augmente la limite de débit de l'API GitHub de 60 à 5 000 req/h — recommandé lors du chargement de plusieurs versions.
Stockage des clésKEY_STORE_PATHChemin vers le fichier JSON de clés API (montez-le dans le conteneur). Si omis, le serveur fonctionne en mode anonyme : aucune authentification n'est requise et toutes les connexions sont limitées en débit par IP source selon la limite du niveau gratuit.
Hôtes autorisésALLOWED_HOSTSValeurs d'en-tête Host à accepter, séparées par des virgules (ex. mcp.example.com,mcp.example.com:443). Si omis, la validation d'hôte est désactivée — adapté uniquement au développement local. Toujours le définir en production pour prévenir les attaques par rebinding DNS.
Redirection navigateurBROWSER_REDIRECT_URLURL vers laquelle rediriger les requêtes GET simples des navigateurs. Les clients MCP sont détectés par Accept: text/event-stream ; les navigateurs reçoivent une 307 vers cette URL à la place. Si omis, les GET navigateur retournent 400.
Niveau de journalisationRUST_LOGFiltre de niveau de journalisation (ex. info, debug, mcp=debug).
Port--publishLe serveur écoute sur le port 3000.

Authentification

Stockage des clés API

Le stockage des clés est un tableau JSON plat chargé une fois au démarrage :

[
  { "key": "free-key-abc", "tier": "free" },
  { "key": "paid-key-xyz", "tier": "paid" }
]

Chaque requête doit inclure la clé dans l'en-tête Authorization :

Authorization: Bearer free-key-abc

Les requêtes sans clé valide reçoivent 401 Unauthorized.

Mode anonyme

Lorsque KEY_STORE_PATH n'est pas défini, le serveur fonctionne sans authentification. Toutes les connexions sont acceptées et limitées en débit par IP source selon la limite du niveau gratuit. Pratique pour un usage local ; ne pas exposer publiquement.

Niveaux et limites de débit

NiveauLimite
free10 requêtes / minute, rafale 10
paid~1 000 requêtes / seconde, rafale 1 000 (effectivement illimité)

Les requêtes dépassant la limite reçoivent 429 Too Many Requests. Les limites sont suivies par clé API, non par IP.

Connexion d'un client MCP

Le serveur implémente le transport MCP Streamable HTTP. Le point de terminaison est :

http://<host>:<port>/[?version=<k8s-version>]

Le paramètre de requête version sélectionne la version Kubernetes à utiliser pour la session. Si omis, la première version chargée est utilisée. Une version inconnue retourne 400 Bad Request.

Claude Desktop

Ajoutez ce qui suit à claude_desktop_config.json :

{
  "mcpServers": {
    "kubernetools": {
      "url": "http://localhost:3000/?version=v1.36",
      "headers": {
        "Authorization": "Bearer mykey"
      }
    }
  }
}

Outils disponibles

list_resources

Découverte légère — retourne une entrée par ressource, triée par (group, kind, api_version). Utilisez ceci en premier pour trouver les noms de type (kind).

Filtres optionnels : group (ex. "apps", "core"), api_version (ex. "v1").

get_resource

Détail complet de la ressource — champs, spec, statut et champs de liste — suffisant pour écrire un manifeste en un seul appel. Requis : kind. Optionnel : group, api_version (par défaut la plus récente).

Les champs avec un type_ref non nul et un sub_fields vide doivent être explorés avec get_type.

get_type

Explore un type composite unique référencé via type_ref dans la sortie de get_resource. Requis : type_name (ex. "Container", "PodFailurePolicy").

Flux de requête typique

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

Vérification de santé

GET /healthz sur le port 3000.

  • Retourne 503 Service Unavailable (corps : loading) pendant le chargement de la documentation de l'API Kubernetes.
  • Retourne 200 OK (corps : ok) une fois le serveur prêt.

Ce point de terminaison contourne l'authentification et la limitation de débit.

Utilisez-le pour les sondes de démarrage, de disponibilité et de vivacité :

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

Réponses d'erreur

Statut HTTPCause
307 Temporary RedirectGET navigateur lorsque BROWSER_REDIRECT_URL est défini
400 Bad RequestGET navigateur lorsque BROWSER_REDIRECT_URL n'est pas défini, ou le paramètre version nomme une version non chargée au démarrage
401 UnauthorizedEn-tête Authorization: Bearer <key> manquant ou invalide
429 Too Many RequestsLimite de débit dépassée pour le niveau de la clé

Les erreurs de niveau MCP (nom d'outil inconnu, argument requis manquant, type non trouvé) sont retournées sous forme de contenu d'erreur MCP dans une réponse 200 normale.

Exemples

Versions Kubernetes multiples

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

Configuration de production avec validation d'hôte

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

Journalisation de débogage

podman run -d \
  -p 3000:3000 \
  -e K8S_VERSIONS=v1.33 \
  -e RUST_LOG=debug \
  ghcr.io/kubernetools/mcp-server:latest

Épingler à une version spécifique

podman run -d \
  -p 3000:3000 \
  -e K8S_VERSIONS=v1.33 \
  ghcr.io/kubernetools/mcp-server:0.1.0

Image

Construite sur registry.access.redhat.com/hi/core-runtime:2.42-openssl — un runtime minimal, sans distribution, glibc + OpenSSL. Pas de shell ni de gestionnaire de paquets.