11 -- Discovery: Kubernetes

Prerequisite: 01 -- HTTP Gateway You will need: Running Hangar, Kubernetes cluster with the MCP-Hangar Operator Time: 15 minutes Adds: Auto-discover MCP servers from Kubernetes annotations

Prerequisites

This recipe requires the MCP-Hangar Operator running in your cluster. The operator ships from a separate repository: https://github.com/mcp-hangar/hangar-operator.

Install via Helm (from the helm-charts repo):

helm repo add mcp-hangar https://mcp-hangar.github.io/helm-charts
helm repo update
helm install mcp-hangar-operator mcp-hangar/mcp-hangar-operator \
  --namespace mcp-system \
  --create-namespace

Verify the CRDs are installed:

kubectl get crd | grep mcp-hangar.io
# Expected:
#   mcpservers.mcp-hangar.io
#   mcpservergroups.mcp-hangar.io
#   mcpdiscoverysources.mcp-hangar.io

The Problem

You run MCP servers as Kubernetes services. Teams deploy and scale MCP servers independently. You need Hangar to discover them from annotations without manual config updates.

The Config

# config.yaml -- Recipe 11: Kubernetes Discovery
discovery:
  enabled: true
  refresh_interval_s: 30
  auto_register: true                    # NEW: trust K8s annotations

  sources:
    - type: kubernetes                   # NEW: Kubernetes source
      mode: authoritative                # NEW: add AND remove on pod changes
      config:                            # NEW: K8s-specific config
        namespace: "mcp-servers"       # NEW: watch this namespace
        label_selector: "app.kubernetes.io/part-of=mcp"  # NEW: filter pods

Try It

  1. Deploy an MCP server with annotations:

    kubectl apply -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: math-mcp-server
      namespace: mcp-servers
      labels:
        app.kubernetes.io/part-of: mcp
      annotations:
        mcp-hangar.io/enabled: "true"
        mcp-hangar.io/name: "k8s-math"
        mcp-hangar.io/port: "8080"
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: math-mcp-server
      template:
        metadata:
          labels:
            app: math-mcp-server
        spec:
          containers:
            - name: math
              image: my-registry/math-server:latest
              ports:
                - containerPort: 8080
    EOF
  2. Expose the deployment:

    kubectl expose deployment math-mcp-server -n mcp-servers --port=8080
  3. Verify Hangar discovers it:

    curl http://localhost:8000/api/discovery/sources
  4. Check registered MCP servers:

    mcp-hangar status
    k8s-math    remote    cold    source=kubernetes:auto-discovery
    
  5. Scale up and watch Hangar adapt:

    kubectl scale deployment math-mcp-server -n mcp-servers --replicas=3

What Just Happened

The Kubernetes discovery source watches pods in the configured namespace matching the label selector. Pods with mcp-hangar.io/enabled: "true" annotations are registered as remote MCP servers. In authoritative mode, when a pod is deleted, the corresponding MCP server is deregistered.

For declarative management, use the MCP-Hangar Operator CRDs instead. See the Kubernetes guide.

Key Config Reference

KeyTypeDefaultDescription
discovery.sources[].typestring--Set to kubernetes
discovery.sources[].modestring--additive or authoritative
discovery.sources[].config.namespacestringdefaultKubernetes namespace to watch
discovery.sources[].config.label_selectorstring--Pod label selector

Kubernetes Annotations

AnnotationRequiredDefaultDescription
mcp-hangar.io/enabledYes--Must be "true"
mcp-hangar.io/nameNoPod nameMCP Server name
mcp-hangar.io/portNo8080MCP Server port
mcp-hangar.io/groupNo--Auto-add to group

What's Next

You have discovery working. Now add authentication to control who can access your MCP servers.

--> 12 -- Auth & RBAC