Skip to content

feat: dynamic MCP proxy config with backend overrides (Host/Path/Auth)#2345

Open
pbonuboinasnow wants to merge 8 commits into
envoyproxy:mainfrom
pbonuboinasnow:feature/dynamic-mcp-proxy-dfp
Open

feat: dynamic MCP proxy config with backend overrides (Host/Path/Auth)#2345
pbonuboinasnow wants to merge 8 commits into
envoyproxy:mainfrom
pbonuboinasnow:feature/dynamic-mcp-proxy-dfp

Conversation

@pbonuboinasnow

@pbonuboinasnow pbonuboinasnow commented Jul 10, 2026

Copy link
Copy Markdown

Description

Adds dynamic MCP route and backend configuration without relying solely on the static filter-config.yaml, enabling flexible multi-tenant MCP deployments.

Use Case: Multi-Tenant MCP Deployments

This feature supports multi-tenant deployments with thousands of MCP routes, where each tenant or deployment has different MCP backend configurations and rules. Instead of managing static routes for every tenant:

  • A trusted Envoy ext_proc filter (or ext_authz) dynamically injects route and backend configuration per request
  • Backend configurations include host, path, and auth overrides for each tenant
  • Headers are injected by the Envoy data plane, not external clients, ensuring secure multi-tenant isolation

Technical Details

1. Dynamic Route Config via Header

The MCP proxy checks for the x-ai-eg-mcp-dynamic-route-config header on every incoming request. If present, its value is interpreted as a base64-encoded JSON representation of an MCPRoute object, which takes precedence over the statically loaded route. Falls back to static config if the header is missing or malformed. This header is expected to be set by a trusted upstream filter (e.g. an ext_proc filter in the Envoy filter chain) before reaching the MCP proxy, not by external clients directly.

2. Backend Overrides (Host / Path / Auth)

Three new optional fields on MCPBackend:

  • host — Sets :authority/Host header for Envoy DFP DNS + TLS
  • backendPath — Rewrites URL path
  • auth — Injects Authorization header

All are optional. Overrides are applied in all 3 backend request paths: invokeJSONRPCRequest, sendRequestPerBackend, and session.Close().

Files changed:

  • internal/internalapi/internalapi.go — MCPDynamicRouteConfigHeader constant
  • internal/filterapi/mcpconfig.go — Host, BackendPath, Auth fields on MCPBackend
  • internal/mcpproxy/config.go — parseDynamicRouteConfig() and buildConfigRoute()
  • internal/mcpproxy/mcpproxy.go — routeConfig(), applyBackendOverrides()
  • internal/mcpproxy/handlers.go — replaced static lookups with routeConfig()
  • internal/mcpproxy/session.go — applied overrides in sendRequestPerBackend and Close()
  • Unit tests for applyBackendOverrides and dynamic route config parsing
  • Add examples/dynamic-mcp-config/ with architecture documentation and configuration examples

Related Issues/PRs (if applicable)

Special notes for reviewers (if applicable)

This enables supporting 1000s of MCP routes in multi-tenant deployments where each tenant has dynamic configuration rules.

@pbonuboinasnow
pbonuboinasnow force-pushed the feature/dynamic-mcp-proxy-dfp branch 3 times, most recently from 75c0805 to f4addab Compare July 10, 2026 12:44
@pbonuboinasnow

pbonuboinasnow commented Jul 11, 2026

Copy link
Copy Markdown
Author

@mathetake @nacx what's your opinion on this? we need a way to support 1000s (yes) of MCP routes as we are a multi tenant deployment with dynamic rules.

@pbonuboinasnow
pbonuboinasnow force-pushed the feature/dynamic-mcp-proxy-dfp branch from f4addab to 4a117cf Compare July 13, 2026 04:45
@pbonuboinasnow
pbonuboinasnow marked this pull request as ready for review July 13, 2026 04:46
@pbonuboinasnow
pbonuboinasnow requested a review from a team as a code owner July 13, 2026 04:46
@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Jul 13, 2026
@pbonuboinasnow
pbonuboinasnow force-pushed the feature/dynamic-mcp-proxy-dfp branch from 4a117cf to 59cfa1f Compare July 13, 2026 04:51
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Jul 13, 2026
@pbonuboinasnow
pbonuboinasnow force-pushed the feature/dynamic-mcp-proxy-dfp branch from 5f75a41 to 4242e88 Compare July 13, 2026 07:05
- Add dynamic route config via x-ai-eg-mcp-dynamic-route-config header
  (base64-encoded JSON MCPRoute overrides static filter-config.yaml)
- Add Host, BackendPath, Auth fields to MCPBackend for DFP support
- Apply backend overrides in all 3 request paths:
  invokeJSONRPCRequest, sendRequestPerBackend, session.Close()
- Add unit tests for applyBackendOverrides and dynamic route config
- Add DYNAMIC_MCP_CONFIG.md with usage examples

Signed-off-by: prasad.bonuboina <prasad.bonuboina@servicenow.com>
… shadow

Signed-off-by: prasad.bonuboina <prasad.bonuboina@servicenow.com>
Signed-off-by: prasad.bonuboina <prasad.bonuboina@servicenow.com>
…adow, remove sync script

Signed-off-by: prasad.bonuboina <prasad.bonuboina@servicenow.com>
…ion header

Prevents a route/backend forwardHeaders config from clobbering a
configured MCPBackend.Auth outbound credential when the client's
request carries its own Authorization header of the same name.

Signed-off-by: prasad.bonuboina <prasad.bonuboina@servicenow.com>
Create examples/dynamic-mcp-config/ directory with:
- README.md — Overview, architecture, header format, implementation details
- filter-config.yaml — Static backend configuration example

Provides clear documentation for per-request MCP backend configuration
overrides via x-ai-eg-mcp-dynamic-route-config header.

Signed-off-by: prasad.bonuboina <prasad.bonuboina@servicenow.com>
@pbonuboinasnow
pbonuboinasnow force-pushed the feature/dynamic-mcp-proxy-dfp branch from 4242e88 to 0547dfa Compare July 13, 2026 13:24
@missBerg missBerg added the area/mcp MCP proxy, MCPRoute, and MCP spec conformance label Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/mcp MCP proxy, MCPRoute, and MCP spec conformance size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants