add forward_headers passthrough to remote::model-context-protocol#5257
Draft
skamenan7 wants to merge 4 commits intollamastack:mainfrom
Draft
add forward_headers passthrough to remote::model-context-protocol#5257skamenan7 wants to merge 4 commits intollamastack:mainfrom
skamenan7 wants to merge 4 commits intollamastack:mainfrom
Conversation
…nd extra_blocked_headers
…nd extra_blocked_headers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
forward_headersandextra_blocked_headerstoMCPProviderConfig, wiring per-request header forwarding intolist_runtime_toolsandinvoke_tool. This lets deployers map keys fromX-LlamaStack-Provider-Datato outbound HTTP headers so request-scoped auth tokens (MaaS API keys, tenant IDs, etc.) reach the downstream MCP server without the caller passing them viaauthorization=on every tool call.Follows the same
forward_headerspattern introduced for inference and safety passthrough in #5134. Authorization-mapped values are split out and passed via theauthorization=param —prepare_mcp_headers()rejectsAuthorizationin the headers dict directly, so it flows through the dedicated param instead.What changed
MCPProviderConfig: addedforward_headers: dict[str, str] | Noneandextra_blocked_headers: list[str]with config-time validation viavalidate_forward_headers_config()fromproviders/utils/forward_headers.pyMCPProviderDataValidator: addedmodel_config = ConfigDict(extra="allow")so deployer-defined keys survive Pydantic parsing (key names are operator-configured at deploy time and can't be declared as typed fields)ModelContextProtocolImpl: new_get_forwarded_headers_and_auth()reads the allowlist from provider data, splits Authorization for theauthorization=param, returns non-auth headers separately. Bothlist_runtime_toolsandinvoke_toolmerge forwarded headers with the legacymcp_headersURI-keyed path (kept for backward compat). Explicitauthorization=from the caller wins over forwarded auth.Config example:
Test plan
Unit/integration tests — tests covering config validation, header forwarding, auth splitting, default-deny enforcement, missing-key soft-skip, and wiring through
list_runtime_toolsandinvoke_tool:Local testing with mock MCP server — ran a mock MCP server that captures all inbound headers and exposes them at
/debug/last-headers. Started llama-stack with theforward_headersconfig above, then verified via the agent API that:maas_api_tokenfromX-LlamaStack-Provider-Dataarrived asAuthorization: Bearer <token>on the downstream servertenant_idarrived asX-Tenant-IDsecret_internal) did not appear in any downstream header (default-deny confirmed)Note:
invoke_toolandlist_runtime_toolsare internal methods called by the agents layer and not exposed as HTTP endpoints (changed in upstream PRs #4997 and #5246), so full e2e requires a model server via the agent API.Checklist
forward_headers/extra_blocked_headersoptional with backward-compatible defaults — configs without them parse correctlyNone, empty dict, populated dictMCPProviderDataValidatorusesextra="allow"(intentional — deployer key names can't be pre-declared)MCPProviderConfigusesextra="forbid"build_forwarded_headers()andvalidate_forward_headers_config()fromproviders/utils/forward_headers.py— no duplicationmcp_headersURI-keyed path preserved for backward compatSummary by Sourcery
Add configurable per-request header forwarding support to remote passthrough providers, including MCP tool runtime, inference, and safety, using a shared forward_headers utility with stricter validation and default-deny behavior.
New Features:
Enhancements:
Tests: