fix(mcp): annotate read-only header mappings in catalog list path

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
joshua 2026-09-21 20:09:00 +00:00
parent 35def1641f
commit f8a6ab7c1f
3 changed files with 17 additions and 11 deletions

View file

@ -321,7 +321,9 @@ _OAuthDiscoveryOutcome: TypeAlias = _OAuthDiscoveryResolved | _OAuthDiscoveryFai
@dataclass(frozen=True, slots=True)
class _ListHeaders:
upstream: dict[str, str] | None
upstream: (
dict[str, str] | None
) # mutable-ok: relayed into MCPClient.extra_headers (dict[str, str]); built fresh per request, never mutated after hand-off
signed_for_user: bool
minted: frozenset[str] = frozenset()
@ -4506,9 +4508,9 @@ class MCPServerManager:
server: MCPServer,
*,
user_api_key_auth: UserAPIKeyAuth | None,
mcp_auth_header: str | dict[str, str] | None,
extra_headers: dict[str, str] | None,
raw_headers: dict[str, str] | None,
mcp_auth_header: str | Mapping[str, str] | None,
extra_headers: Mapping[str, str] | None,
raw_headers: Mapping[str, str] | None,
) -> _ListHeaders:
"""Listing stays best-effort on missing per-user env vars, and the JWT signer never overrides an
Authorization already supplied by static headers, a per-user auth header, or extra_headers."""

View file

@ -226,7 +226,7 @@ if MCP_AVAILABLE:
component gets a name distinct from the prompt-management ``Prompt`` request model."""
class ListMCPPromptsRestAPIResponse(BaseModel):
prompts: list[MCPCatalogPrompt]
prompts: Sequence[MCPCatalogPrompt]
@classmethod
def from_prompts(cls, prompts: Sequence[Prompt]) -> "ListMCPPromptsRestAPIResponse":
@ -238,16 +238,20 @@ if MCP_AVAILABLE:
)
class ListMCPResourcesRestAPIResponse(BaseModel):
resources: list[Resource]
resource_templates: list[ResourceTemplate]
resources: Sequence[Resource]
resource_templates: Sequence[ResourceTemplate]
@dataclass(frozen=True, slots=True)
class _CatalogServerContext:
server: MCPServer
user_api_key_dict: UserAPIKeyAuth
mcp_auth_header: dict[str, str] | str | None
extra_headers: dict[str, str] | None
raw_headers: dict[str, str]
mcp_auth_header: (
dict[str, str] | str | None
) # mutable-ok: relayed verbatim into dict-typed auth-resolution params on the manager
extra_headers: (
dict[str, str] | None
) # mutable-ok: relayed to dict-typed manager params; read-only on this object
raw_headers: dict[str, str] # mutable-ok: relayed to dict-typed manager params; read-only on this object
########################################################
############ MCP Server REST API Routes #################

View file

@ -911,7 +911,7 @@ class MCPJWTSigner(CustomGuardrail):
async def inject_mcp_jwt_headers_for_upstream(
user_api_key_dict: UserAPIKeyAuth | None,
extra_headers: dict[str, str] | None = None,
raw_headers: dict[str, str] | None = None,
raw_headers: Mapping[str, str] | None = None,
*,
for_list_tools: bool = False,
mcp_tool_name: str = "",