mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-25 01:02:15 +00:00
fix(mcp): handle passthrough OAuth metadata and startup auth errors
- discoverable_endpoints: For pass-through MCP servers, when upstream oauth-protected-resource returns a non-200/non-dict response, raise HTTP 502 instead of falling through to default gateway metadata. Falling through would direct MCP clients at the gateway, which is not the authorization server for pass-through configs. - mcp_server_manager: Wrap _get_tools_from_server in startup tool name mapping with try/except. Since _get_tools_from_server now re-raises MCPUpstreamAuthError, an upstream 401 from a pass-through server at startup (when no user token is present) would otherwise abort the loop and leave subsequent servers unmapped. Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
parent
d1d9ff0121
commit
719adfd043
2 changed files with 33 additions and 1 deletions
|
|
@ -893,6 +893,22 @@ async def _build_oauth_protected_resource_response(
|
|||
response = {**upstream_metadata, "resource": resource_url}
|
||||
return response
|
||||
|
||||
# Upstream responded but with non-200 or non-dict payload. For
|
||||
# pass-through servers the gateway is NOT the authorization server,
|
||||
# so we must not fall through to the default gateway metadata —
|
||||
# that would point clients at the wrong IdP.
|
||||
verbose_logger.warning(
|
||||
"Upstream oauth-protected-resource metadata unavailable for "
|
||||
f"pass-through MCP server {mcp_server.name!r}"
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=502,
|
||||
detail=(
|
||||
"Upstream oauth-protected-resource metadata unavailable "
|
||||
f"for MCP server {mcp_server.name!r}"
|
||||
),
|
||||
)
|
||||
|
||||
return {
|
||||
"authorization_servers": [
|
||||
(
|
||||
|
|
|
|||
|
|
@ -3060,7 +3060,23 @@ class MCPServerManager:
|
|||
if server.needs_user_oauth_token:
|
||||
# Skip OAuth2 servers that rely on user-provided tokens
|
||||
continue
|
||||
tools = await self._get_tools_from_server(server)
|
||||
try:
|
||||
tools = await self._get_tools_from_server(server)
|
||||
except MCPUpstreamAuthError as e:
|
||||
# Pass-through servers expect a user-supplied bearer token;
|
||||
# at startup we have none, so an upstream 401 is normal.
|
||||
# Swallow it so we keep mapping the remaining servers.
|
||||
verbose_logger.debug(
|
||||
f"Skipping tool name mapping for server {server.name} "
|
||||
f"due to upstream auth error: {str(e)}"
|
||||
)
|
||||
continue
|
||||
except Exception as e:
|
||||
verbose_logger.warning(
|
||||
f"Failed to get tools from server {server.name} during "
|
||||
f"tool name mapping initialization: {str(e)}"
|
||||
)
|
||||
continue
|
||||
for tool in tools:
|
||||
# The tool.name here is already prefixed from _get_tools_from_server
|
||||
# Extract original name for mapping
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue