Hot-Reload & Spec Refresh

Config changes and OpenAPI spec updates are applied atomically at runtime without restarting the proxy or dropping in-flight requests.

Config hot-reload

The proxy watches the config file with fsnotify. When a change is detected:

  1. The new config is parsed and validated
  2. A new set of upstreams, tools, and groups is built
  3. The new routing table is swapped in atomically
  4. In-flight requests continue using the old routing table until they complete

If the new config is invalid, the proxy logs the error and continues running with the current config.

Kubernetes ConfigMap support

Kubernetes updates ConfigMaps by atomically swapping a symlink to a new data directory. fsnotify detects the symlink change and triggers a reload. No special configuration is required.

# Mount config, specs, and overlays as separate ConfigMaps
# for independent update cycles
volumes:
  - name: config
    configMap:
      name: mcp-anything-config
  - name: specs
    configMap:
      name: mcp-anything-specs
  - name: overlays
    configMap:
      name: mcp-anything-overlays

Background spec refresh

HTTP upstreams can re-fetch their OpenAPI spec on a configurable interval:

upstreams:
  - name: myapi
    type: http
    openapi:
      source: https://api.example.com/openapi.yaml
      refresh_interval: 5m     # re-fetch every 5 minutes

On each refresh:

  1. The proxy sends a conditional GET with the If-None-Match header (ETag from the previous response)
  2. If the server returns 304 Not Modified, no work is done
  3. If the spec has changed, it is parsed, overlays are applied, tools are regenerated
  4. The upstream's tool registry is swapped in atomically

Refresh intervals

Valid duration formats: 30s, 5m, 1h. If refresh_interval is not set, the spec is loaded once at startup and never re-fetched.

Refresh on startup

The proxy always loads specs on startup regardless of refresh_interval. If a spec fails to load at startup, the proxy refuses to start.

Reload failures

Config and spec reload failures are non-fatal — the proxy logs the error and continues with the previous valid state. This means a bad config push doesn't take down your MCP endpoint.

Health and readiness

The proxy exposes standard Kubernetes probes:

PathPurpose
GET /healthzLiveness — returns 200 if the server is running
GET /readyzReadiness — returns 200 when all upstreams are loaded and ready

See also