Skip to content

Configuration Reference

All MCP Hangar behavior is controlled through a YAML configuration file and environment variables. The config file defaults to config.yaml in the working directory, overridden by the MCP_CONFIG environment variable. Environment variables take precedence over YAML settings where both exist.

providers

Provider definitions. Each key is a unique provider ID.

yaml
providers:
  math:
    mode: subprocess
    command: [python, -m, math_server]
    idle_ttl_s: 300
    health_check_interval_s: 60

  my-api:
    mode: remote
    endpoint: https://api.example.com/mcp
    idle_ttl_s: 600

  my-container:
    mode: docker
    image: my-mcp:latest
    volumes:
      - ./data:/data:ro
    resources:
      memory: "512m"
      cpu: "1.0"
KeyTypeDefaultRangeDescription
modestr"subprocess"subprocess, docker, remoteProvider mode. container and podman normalize to docker.
commandlist[str]----Command for subprocess mode (required for subprocess)
imagestr----Docker image for docker mode (required for docker)
endpointstr----HTTP endpoint for remote mode (required for remote)
envdict[str, str]{}--Environment variables passed to the provider process
idle_ttl_sint3001--86400Seconds of inactivity before the provider is auto-stopped
health_check_interval_sint605--3600Interval between health checks in seconds
max_consecutive_failuresint31--100Consecutive health check failures before marking degraded
volumeslist[str][]--Docker volume mounts (docker mode only)
builddict----Docker build configuration (docker mode only)
resourcesdict{memory: "512m", cpu: "1.0"}--Container resource limits (docker mode only)
network / network_modestr"none"--Container network mode (docker mode only)
read_onlybooltrue--Read-only filesystem (docker mode only)
userstr----Container user. "current" maps to host uid:gid
argslist[str]----Container CMD override (docker mode only)
descriptionstr----Human-readable provider description
toolslist or dict----Predefined tool schemas (list) or access policy (dict). See below.
authdict----HTTP auth configuration (remote mode only)
tlsdict----TLS configuration (remote mode only)
httpdict----HTTP transport configuration (remote mode only)
max_concurrencyint----Per-provider concurrency limit

tools dual format

The tools key accepts two formats depending on intent.

List format -- predefined tool schemas. The provider is not started to discover tools; schemas are served directly.

yaml
providers:
  static-math:
    mode: subprocess
    command: [python, -m, math_server]
    tools:
      - name: add
        description: Add two numbers
        inputSchema:
          type: object
          properties:
            a: { type: number }
            b: { type: number }

Dict format -- tool access policy using fnmatch glob patterns.

yaml
providers:
  restricted:
    mode: subprocess
    command: [python, -m, full_server]
    tools:
      allow_list:
        - "safe_*"
        - "read_*"
      deny_list:
        - "internal_*"

When allow_list is set, only matching tools are exposed. When only deny_list is set, all tools except matches are exposed.

execution

System-wide concurrency limits.

yaml
execution:
  max_concurrency: 50
  default_provider_concurrency: 10
KeyTypeDefaultRangeDescription
max_concurrencyint500 = unlimitedSystem-wide maximum concurrent tool invocations
default_provider_concurrencyint10--Default per-provider concurrency limit

discovery

Auto-discovery of MCP providers from external sources.

yaml
discovery:
  enabled: true
  refresh_interval_s: 60
  auto_register: false
  sources:
    - type: docker
      mode: additive
    - type: filesystem
      mode: additive
      path: /etc/mcp/providers
      watch: true
KeyTypeDefaultRangeDescription
enabledbool----Enable or disable discovery
refresh_interval_sint----Interval between discovery scans in seconds
auto_registerbool----Automatically register discovered providers
sourceslist[dict][]--Discovery source configurations (see below)
securitydict----Security constraints for discovery
lifecycledict----Lifecycle management for discovered providers

sources[] entry

KeyTypeDescription
typestrSource type: kubernetes, docker, filesystem, entrypoint
modestradditive (only adds) or authoritative (adds and removes)
path / patternstrFile path or glob pattern (filesystem source)
watchboolEnable file watching (filesystem source)
namespaceslist[str]Kubernetes namespaces to scan
label_selectorstrKubernetes label selector
in_clusterboolUse in-cluster Kubernetes config
groupstrTarget group for discovered providers

security sub-section

KeyTypeDefaultDescription
allowed_namespaceslist[str]--Kubernetes namespace allowlist
denied_namespaceslist[str]--Kubernetes namespace denylist
require_health_checkbool--Require health check before registration
require_mcp_schemabool--Require valid MCP schema
max_providers_per_sourceint--Maximum providers per source
max_registration_rateint--Registration rate limit
health_check_timeout_sfloat--Health check timeout in seconds
quarantine_on_failurebool--Quarantine providers that fail health checks

lifecycle sub-section

KeyTypeDefaultDescription
default_ttl_sint--Default TTL for discovered providers
check_interval_sint--Lifecycle check interval in seconds
drain_timeout_sint--Drain timeout before removal

retry

Retry policy for failed operations.

yaml
retry:
  default_policy:
    max_attempts: 3
    backoff: exponential
    initial_delay: 1.0
    max_delay: 30.0
    retry_on:
      - ConnectionError
      - TimeoutError
KeyTypeDefaultDescription
default_policy.max_attemptsint--Maximum retry attempts
default_policy.backoffstr--Backoff strategy (e.g., exponential)
default_policy.initial_delayfloat--Initial delay in seconds
default_policy.max_delayfloat--Maximum delay in seconds
default_policy.retry_onlist[str]--Exception types to retry on

event_store

Persist domain events for audit and replay.

yaml
event_store:
  enabled: true
  driver: sqlite
  path: data/events.db
KeyTypeDefaultDescription
enabledbool--Enable event persistence
driverstr--Storage driver: sqlite or memory
pathstr--SQLite database path (sqlite driver only)

knowledge_base

Knowledge base storage backend.

yaml
knowledge_base:
  enabled: true
  dsn: sqlite:///data/kb.db
  pool_size: 5
  cache_ttl_s: 300
KeyTypeDefaultDescription
enabledbool--Enable knowledge base
dsnstr--Database connection string
pool_sizeint--Connection pool size
cache_ttl_sint--Cache TTL in seconds

logging

Log output configuration.

yaml
logging:
  level: INFO
  json_format: false
  file: /var/log/mcp-hangar.log
KeyTypeDefaultDescription
levelstr"INFO"Log level: DEBUG, INFO, WARNING, ERROR
json_formatboolfalseEnable structured JSON logging
filestr--Log file path

health

Global health check settings.

yaml
health:
  enabled: true
  interval_s: 30
KeyTypeDefaultDescription
enabledbool--Enable health checks
interval_sint--Global health check interval in seconds

observability

Tracing and LLM observability integrations.

tracing sub-section

yaml
observability:
  tracing:
    enabled: true
    otlp_endpoint: http://localhost:4317
    service_name: mcp-hangar
    console_export: false
KeyTypeDefaultDescription
enabledbool--Enable OpenTelemetry tracing
otlp_endpointstr"http://localhost:4317"OTLP exporter endpoint
service_namestr"mcp-hangar"Service name for traces
jaeger_hoststr--Jaeger agent host
jaeger_portint6831Jaeger agent port
console_exportbool--Export traces to console (development)

langfuse sub-section

yaml
observability:
  langfuse:
    enabled: true
    public_key: pk-lf-...
    secret_key: ${LANGFUSE_SECRET_KEY}
    host: https://cloud.langfuse.com
    sample_rate: 1.0
    scrub_inputs: false
    scrub_outputs: false
KeyTypeDefaultDescription
enabledboolfalseEnable Langfuse LLM observability
public_keystr--Langfuse public API key
secret_keystr--Langfuse secret key. Supports env var interpolation: ${LANGFUSE_SECRET_KEY}
hoststr"https://cloud.langfuse.com"Langfuse API host
sample_ratefloat1.0Trace sampling rate (0.0--1.0)
scrub_inputsboolfalseRedact sensitive data from tool inputs
scrub_outputsboolfalseRedact sensitive data from tool outputs

auth

Authentication and authorization.

yaml
auth:
  enabled: true
  allow_anonymous: false
  api_key:
    enabled: true
    header_name: X-API-Key
  oidc:
    enabled: false
    issuer: https://auth.example.com
    audience: mcp-hangar
  rate_limit:
    rps: 10
    burst: 20
KeyTypeDefaultDescription
enabledbool--Enable authentication
allow_anonymousbool--Allow unauthenticated requests
api_key.enabledbool--Enable API key authentication
api_key.header_namestr--HTTP header name for API key
oidc.enabledbool--Enable OpenID Connect authentication
oidc.issuerstr--OIDC issuer URL
oidc.audiencestr--Expected token audience
oidc.subject_claimstr--JWT subject claim field
oidc.groups_claimstr--JWT groups claim field
oidc.email_claimstr--JWT email claim field
oidc.tenant_claimstr--JWT tenant claim field
opa.enabledbool--Enable Open Policy Agent authorization
opa.urlstr--OPA server URL
opa.policy_pathstr--OPA policy path
opa.timeoutfloat--OPA request timeout in seconds
storagedict--Auth storage configuration (driver, path, host, etc.)
rate_limitdict--Auth-specific rate limiting
role_assignmentslist[dict]--Role assignment rules

config_reload

Hot-reload configuration. See the Hot-Reload Reference for full details.

yaml
config_reload:
  enabled: true
  use_watchdog: true
  interval_s: 5
KeyTypeDefaultDescription
enabledbool--Enable automatic config file watching
use_watchdogbool--Use watchdog library for file system events
interval_sint--Polling interval in seconds (fallback when watchdog unavailable)

batch

Limits for batch tool invocations via hangar_call.

yaml
batch:
  max_calls: 100
  max_concurrency: 50
  default_timeout: 60
  max_timeout: 300
  max_response_size_bytes: 10485760      # 10 MB
  max_total_response_size_bytes: 52428800 # 50 MB
KeyTypeDefaultRangeDescription
max_callsint100--Maximum calls per batch
max_concurrencyint50--Maximum parallel workers per batch
default_timeoutfloat60--Default batch timeout in seconds
max_timeoutfloat300--Maximum allowed batch timeout
max_response_size_bytesint10485760 (10 MB)--Maximum single response size before truncation
max_total_response_size_bytesint52428800 (50 MB)--Maximum total batch response size

groups

Provider groups are configured inside the providers section with mode: group. A group load-balances requests across multiple member providers.

yaml
providers:
  llm-group:
    mode: group
    strategy: round_robin
    min_healthy: 1
    auto_start: true
    description: LLM provider pool
    health:
      unhealthy_threshold: 2
      healthy_threshold: 1
    circuit_breaker:
      failure_threshold: 10
      reset_timeout_s: 60.0
    tools:
      allow_list: ["generate_*"]
    members:
      - id: llm-1
        mode: subprocess
        command: [python, -m, llm_server]
        weight: 70
        priority: 1
      - id: llm-2
        mode: subprocess
        command: [python, -m, llm_server]
        weight: 30
        priority: 2
KeyTypeDefaultRangeDescription
modestr--"group"Must be "group"
strategystr"round_robin"round_robin, weighted_round_robin, least_connections, random, priorityLoad balancing strategy
min_healthyint1>= 1Minimum healthy members for group HEALTHY state
auto_startbooltrue--Auto-start members when the group is created
descriptionstr----Group description
health.unhealthy_thresholdint2>= 1Consecutive failures before removing member from rotation
health.healthy_thresholdint1>= 1Consecutive successes before re-adding member to rotation
circuit_breaker.failure_thresholdint10>= 1Total group failures before the circuit opens
circuit_breaker.reset_timeout_sfloat60.0>= 1.0Seconds before the circuit auto-resets
toolsdict----Group-level tool access policy (allow_list, deny_list)
memberslist[dict][]--Member provider configurations

Member configuration

Each member entry supports all standard provider keys (mode, command, image, endpoint, env, etc.) plus:

KeyTypeDefaultRangeDescription
idstr----Unique member ID (required)
weightint--1--100Weight for weighted_round_robin and random strategies
priorityint--1--100Priority for priority strategy (lower number = higher priority)

Environment Variables

Environment variables override corresponding YAML settings. Variables follow the MCP_ prefix convention. Third-party integrations (OpenTelemetry, Langfuse, Jaeger) use their standard prefixes.

Server / CLI

VariableDefaultDescription
MCP_CONFIG"config.yaml"Path to YAML configuration file
MCP_MODE"stdio"Server mode: stdio or http
MCP_HTTP_HOST"0.0.0.0"HTTP bind host
MCP_HTTP_PORT8000HTTP bind port
MCP_LOG_LEVEL"INFO"Logging level (DEBUG, INFO, WARNING, ERROR)
MCP_JSON_LOGS"false"Enable structured JSON logging

Security / Runtime

VariableDefaultDescription
MCP_RATE_LIMIT_RPS"10"Rate limit: requests per second
MCP_RATE_LIMIT_BURST"20"Rate limit: burst size
MCP_ALLOW_ABSOLUTE_PATHS"false"Allow absolute paths in input validation

Persistence

VariableDefaultDescription
MCP_PERSISTENCE_ENABLED"false"Enable state persistence
MCP_DATABASE_PATH"data/mcp_hangar.db"SQLite database file path
MCP_DATABASE_WAL"true"Enable WAL mode for SQLite
MCP_AUTO_RECOVER"true"Auto-recover persisted state on startup

Observability / Tracing

VariableDefaultDescription
MCP_TRACING_ENABLED"true"Enable OpenTelemetry tracing
MCP_TRACING_CONSOLEfrom configEnable console trace export
MCP_ENVIRONMENT"development"Deployment environment label
OTEL_EXPORTER_OTLP_ENDPOINT"http://localhost:4317"OTLP exporter endpoint
OTEL_SERVICE_NAME"mcp-hangar"OpenTelemetry service name
JAEGER_HOST--Jaeger agent host
JAEGER_PORT6831Jaeger agent port

Langfuse

VariableDefaultDescription
MCP_LANGFUSE_ENABLED"false"Enable Langfuse LLM observability
LANGFUSE_PUBLIC_KEY--Langfuse public API key
LANGFUSE_SECRET_KEY--Langfuse secret key (sensitive)
LANGFUSE_HOST"https://cloud.langfuse.com"Langfuse API host
MCP_LANGFUSE_SAMPLE_RATE"1.0"Trace sampling rate (0.0--1.0)
MCP_LANGFUSE_SCRUB_INPUTS"false"Redact sensitive tool inputs
MCP_LANGFUSE_SCRUB_OUTPUTS"false"Redact sensitive tool outputs

!!! note "Legacy HANGAR_* prefix" The following legacy variables are supported for backward compatibility but MCP_* is the canonical prefix: HANGAR_LANGFUSE_ENABLED maps to MCP_LANGFUSE_ENABLED, HANGAR_LANGFUSE_SAMPLE_RATE maps to MCP_LANGFUSE_SAMPLE_RATE, HANGAR_LANGFUSE_SCRUB_INPUTS maps to MCP_LANGFUSE_SCRUB_INPUTS, HANGAR_LANGFUSE_SCRUB_OUTPUTS maps to MCP_LANGFUSE_SCRUB_OUTPUTS.

Container Runtime

VariableDefaultDescription
MCP_CONTAINER_RUNTIME--Force container runtime (docker or podman)
MCP_CI_RELAX_VOLUME_PERMS--Relax volume permission checks in CI environments
MCP_CONTAINER_INHERIT_STDERR--Inherit stderr from container processes

Auth

VariableDefaultDescription
MCP_JWT_MAX_TOKEN_LIFETIME--Maximum JWT token lifetime

Released under the MIT License.