From b9a2589124b04022df8688dc9b5e6e60639977ca Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Thu, 25 Jun 2026 18:23:11 -0700 Subject: [PATCH] fix(mcp): emit the canonical WWW-Authenticate header name in the OAuth challenge raise_user_oauth_challenge emitted the header lowercase while the sibling raise_public and every resource_metadata (RFC 9728) emitter use the canonical WWW-Authenticate; align it. HTTP header names are case-insensitive on the wire so this is cosmetic for compliant clients, but it keeps the challenge builders consistent and matches RFC 6750. --- .../mcp_server/outbound_credentials/adapter.py | 2 +- .../mcp_server/outbound_credentials/test_adapter.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py b/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py index b266c5beb4d..b3e1cd844d8 100644 --- a/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py +++ b/litellm/proxy/_experimental/mcp_server/outbound_credentials/adapter.py @@ -178,5 +178,5 @@ def raise_user_oauth_challenge(server: MCPServer) -> NoReturn: raise HTTPException( status_code=401, detail="Unauthorized", - headers={"www-authenticate": f'Bearer resource_metadata="{resource_metadata}"'}, + headers={"WWW-Authenticate": f'Bearer resource_metadata="{resource_metadata}"'}, ) diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/outbound_credentials/test_adapter.py b/tests/test_litellm/proxy/_experimental/mcp_server/outbound_credentials/test_adapter.py index 060e117892b..383dc255607 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/outbound_credentials/test_adapter.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/outbound_credentials/test_adapter.py @@ -191,7 +191,7 @@ def test_raise_user_oauth_challenge_points_at_per_server_prm(): exc = exc_info.value assert exc.status_code == 401 assert ( - exc.headers["www-authenticate"] + exc.headers["WWW-Authenticate"] == 'Bearer resource_metadata="/.well-known/oauth-protected-resource/mcp/my-srv"' ) @@ -203,7 +203,7 @@ def test_raise_user_oauth_challenge_includes_server_root_path(): ): raise_user_oauth_challenge(_server(alias="my-srv")) assert ( - exc_info.value.headers["www-authenticate"] + exc_info.value.headers["WWW-Authenticate"] == 'Bearer resource_metadata="/.well-known/oauth-protected-resource/api/v1/mcp/my-srv"' ) @@ -219,4 +219,4 @@ def test_raise_user_oauth_challenge_includes_server_root_path(): def test_raise_user_oauth_challenge_name_fallback(kwargs, expected_name): with patch(_ROOT_PATH, return_value="/"), pytest.raises(HTTPException) as exc_info: raise_user_oauth_challenge(_server(**kwargs)) - assert f'/mcp/{expected_name}"' in exc_info.value.headers["www-authenticate"] + assert f'/mcp/{expected_name}"' in exc_info.value.headers["WWW-Authenticate"]