MCP Server Discovery
Auto-discover MCP servers from Docker, Kubernetes, filesystem, or Python entrypoints.
Configuration
discovery:
enabled: true
refresh_interval_s: 30
auto_register: true
sources:
- type: docker
mode: additive
Sources
Docker/Podman
sources:
- type: docker
mode: additive
socket_path: /var/run/docker.sock # optional
Container labels:
# docker-compose.yml
services:
my-mcp-server:
image: my-mcp-server:latest
labels:
mcp.hangar.enabled: "true"
mcp.hangar.name: "my-mcp-server"
mcp.hangar.mode: "http"
mcp.hangar.port: "8080"
| Label | Required | Default |
|---|---|---|
mcp.hangar.enabled | yes | - |
mcp.hangar.name | no | container name |
mcp.hangar.mode | no | http |
mcp.hangar.port | no | 8080 |
mcp.hangar.group | no | - |
Kubernetes
sources:
- type: kubernetes
mode: authoritative
namespaces: [mcp-servers]
label_selector: "app.kubernetes.io/component=mcp-server"
in_cluster: true
Pod annotations:
apiVersion: v1
kind: Pod
metadata:
annotations:
mcp-hangar.io/enabled: "true"
mcp-hangar.io/name: "data-processor"
mcp-hangar.io/mode: "http"
mcp-hangar.io/port: "8080"
Filesystem
sources:
- type: filesystem
mode: additive
path: /etc/mcp-hangar/mcp_servers.d/
pattern: "*.yaml"
watch: true
MCP Server file:
# /etc/mcp-hangar/mcp_servers.d/custom.yaml
name: custom-tool
enabled: true
mode: subprocess
connection:
command: python
args: [-m, my_mcp_server]
Python Entrypoints
sources:
- type: entrypoint
mode: additive
group: mcp.mcp_servers
# pyproject.toml
[project.entry-points."mcp.mcp_servers"]
my_mcp_server = "my_package.server:create_server"
def create_server():
return {
"name": "my-tools",
"mode": "subprocess",
"command": ["python", "-m", "my_package.server"]
}
Discovery Modes
| Mode | Behavior |
|---|---|
additive | Only adds MCP servers, never removes |
authoritative | Adds and removes (for dynamic environments) |
Security
discovery:
security:
max_mcp_servers_per_source: 100
max_registration_rate: 10 # per minute
require_health_check: true
quarantine_on_failure: true
allowed_namespaces: [mcp-servers]
denied_namespaces: [kube-system, default]
Tools
| Tool | Description |
|---|---|
hangar_discover | Trigger discovery cycle |
hangar_sources | List sources with status |
hangar_quarantine | List quarantined MCP servers |
hangar_approve | Approve quarantined MCP server |
Conflict Resolution
- Static config wins — Manual config always takes precedence
- Higher priority source wins — K8s (1) > Docker (2) > Filesystem (3) > Entrypoints (4)
- TTL expiration — Authoritative sources deregister after TTL
Prometheus Metrics
| Metric | Description |
|---|---|
mcp_hangar_discovery_mcp_servers | MCP servers per source (Gauge) |
mcp_hangar_discovery_registrations_total | New registrations |
mcp_hangar_discovery_errors_total | Errors by source |
mcp_hangar_discovery_cycle_duration_seconds | Cycle duration (Histogram) |