mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(mcp): re-raise HTTPException in handle_sse_mcp so 401 propagates
This commit is contained in:
parent
57e8c6f59d
commit
26b60234fc
2 changed files with 67 additions and 0 deletions
|
|
@ -2965,6 +2965,11 @@ if MCP_AVAILABLE:
|
|||
_sse_client_ip,
|
||||
):
|
||||
await sse_session_manager.handle_request(scope, receive, send)
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions to preserve status codes and details
|
||||
# (e.g. the 401 + WWW-Authenticate challenge raised by
|
||||
# _maybe_raise_oauth_bootstrap_challenge for OAuth cold-starts).
|
||||
raise
|
||||
except Exception as e:
|
||||
verbose_logger.exception(f"Error handling MCP request: {e}")
|
||||
# Instead of re-raising, try to send a graceful error response
|
||||
|
|
|
|||
|
|
@ -819,3 +819,65 @@ async def test_oauth_bootstrap_skips_for_non_oauth_server():
|
|||
global_mcp_server_manager.registry.clear()
|
||||
|
||||
assert sentinel_extract.await_count == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_oauth_bootstrap_returns_401_via_sse_handler():
|
||||
"""
|
||||
Regression: the SSE handler must propagate the 401 raised by the pre-check
|
||||
helper instead of swallowing it via its bare `except Exception`. Mirror
|
||||
of the StreamableHTTP test against handle_sse_mcp.
|
||||
"""
|
||||
try:
|
||||
from litellm.proxy._experimental.mcp_server.server import handle_sse_mcp
|
||||
from litellm.proxy._experimental.mcp_server.mcp_server_manager import (
|
||||
global_mcp_server_manager,
|
||||
)
|
||||
from litellm.proxy._types import MCPTransport
|
||||
from litellm.types.mcp_server.mcp_server_manager import MCPServer
|
||||
except ImportError:
|
||||
pytest.skip("MCP server not available")
|
||||
|
||||
global_mcp_server_manager.registry.clear()
|
||||
public_server = MCPServer(
|
||||
server_id="bootstrap_sse_server",
|
||||
name="bootstrap_sse_server",
|
||||
server_name="bootstrap_sse_server",
|
||||
alias="bootstrap_sse_server",
|
||||
transport=MCPTransport.http,
|
||||
auth_type=MCPAuth.oauth2,
|
||||
client_id="real-client-id",
|
||||
client_secret=None,
|
||||
authorization_url="https://idp.example/authorize",
|
||||
token_url="https://idp.example/token",
|
||||
)
|
||||
global_mcp_server_manager.registry[public_server.server_id] = public_server
|
||||
|
||||
scope = {
|
||||
"type": "http",
|
||||
"method": "POST",
|
||||
"path": "/mcp/bootstrap_sse_server",
|
||||
"headers": [
|
||||
(b"content-type", b"application/json"),
|
||||
],
|
||||
}
|
||||
receive = AsyncMock()
|
||||
send = AsyncMock()
|
||||
|
||||
try:
|
||||
with patch(
|
||||
"litellm.proxy._experimental.mcp_server.server.IPAddressUtils.get_mcp_client_ip",
|
||||
return_value=None,
|
||||
):
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
await handle_sse_mcp(scope, receive, send)
|
||||
finally:
|
||||
global_mcp_server_manager.registry.clear()
|
||||
|
||||
exc = exc_info.value
|
||||
assert exc.status_code == 401
|
||||
assert "www-authenticate" in exc.headers
|
||||
assert (
|
||||
"/.well-known/oauth-authorization-server/bootstrap_sse_server"
|
||||
in exc.headers["www-authenticate"]
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue