Multi-Upstream Routing

A single proxy instance can aggregate tools from multiple backends — HTTP APIs, CLI commands, and JavaScript scripts — served through one MCP endpoint.

How it works

Each upstream declares a tool_prefix. Tool names follow the pattern {prefix}__{operation}, using a double-underscore separator. This ensures tools from different upstreams never collide.

upstreams:
  - name: kraken
    type: http
    tool_prefix: kraken            # → kraken__get_ticker, kraken__get_ohlc, ...
    base_url: https://api.kraken.com
    openapi:
      source: examples/kraken/spec.yaml

  - name: cluster
    type: command
    tool_prefix: k8s               # → k8s__get_pods, k8s__get_logs, ...
    tools:
      - name: get_pods
        command: kubectl get pods -n {{namespace}} -o json
        args:
          namespace:
            type: string
            required: true

  - name: ops
    type: script
    tool_prefix: ops               # → ops__health_check, ...
    tools:
      - name: health_check
        source: scripts/health_check.js
        args:
          service:
            type: string

Tool name collision handling

If two upstreams would produce identical tool names after prefixing, a numeric suffix (_2, _3) is appended to the later upstream's tools. Use distinct tool_prefix values or x-mcp-tool-name overlays to avoid this.

Upstream types

TypeDescription
httpREST API backed by an OpenAPI 3.0 spec
commandShell command with template argument interpolation
scriptJavaScript file running in a Sobek sandbox

Groups

Use Tool Groups to expose different subsets of upstreams at different MCP endpoints from the same proxy instance:

groups:
  - name: all
    endpoint: /mcp
    upstreams: [kraken, cluster, ops]

  - name: market-only
    endpoint: /mcp/market
    upstreams: [kraken]

Independent refresh cycles

Each HTTP upstream can have its own refresh_interval. When a spec is re-fetched and parsed, the upstream's tools are updated atomically without affecting other upstreams or dropping in-flight requests.

upstreams:
  - name: fast-api
    type: http
    openapi:
      source: https://api.example.com/openapi.yaml
      refresh_interval: 1m     # refresh every minute

  - name: stable-api
    type: http
    openapi:
      source: https://stable.example.com/openapi.yaml
      refresh_interval: 1h     # refresh hourly

See also