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
-
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 -
Expose the deployment:
kubectl expose deployment math-mcp-server -n mcp-servers --port=8080 -
Verify Hangar discovers it:
curl http://localhost:8000/api/discovery/sources -
Check registered MCP servers:
mcp-hangar statusk8s-math remote cold source=kubernetes:auto-discovery -
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
| Key | Type | Default | Description |
|---|---|---|---|
discovery.sources[].type | string | -- | Set to kubernetes |
discovery.sources[].mode | string | -- | additive or authoritative |
discovery.sources[].config.namespace | string | default | Kubernetes namespace to watch |
discovery.sources[].config.label_selector | string | -- | Pod label selector |
Kubernetes Annotations
| Annotation | Required | Default | Description |
|---|---|---|---|
mcp-hangar.io/enabled | Yes | -- | Must be "true" |
mcp-hangar.io/name | No | Pod name | MCP Server name |
mcp-hangar.io/port | No | 8080 | MCP Server port |
mcp-hangar.io/group | No | -- | Auto-add to group |
What's Next
You have discovery working. Now add authentication to control who can access your MCP servers.