diff --git a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py index f596f9af914..b918a687d85 100644 --- a/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py +++ b/litellm/proxy/_experimental/mcp_server/discoverable_endpoints.py @@ -1014,7 +1014,7 @@ async def authorize_with_server( existing_params: Final = dict(parse_qsl(parsed_auth_url.query)) existing_params.update(params) final_url: Final = urlunparse(parsed_auth_url._replace(query=urlencode(existing_params))) - response: Final = RedirectResponse(final_url) + response: Final = RedirectResponse(final_url, status_code=303 if connection is not None else 307) _set_oauth_state_cookie(response, request, relay_state, encoded_state) if connection is not None and len(response.headers["set-cookie"]) > 4096: return _oauth_error(400, "invalid_request", "Connection authorization metadata is too large") diff --git a/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py b/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py index f02ab09ebbd..bac15f0de98 100644 --- a/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py +++ b/litellm/proxy/_experimental/mcp_server/gateway_dcr_flow.py @@ -1716,7 +1716,7 @@ async def authorize_connection( **TOKEN_NO_CACHE_HEADERS, "Referrer-Policy": "no-referrer", "X-Frame-Options": "DENY", - "Content-Security-Policy": "default-src 'none'; form-action 'self'; frame-ancestors 'none'", + "Content-Security-Policy": "default-src 'none'; frame-ancestors 'none'", } ), ) diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py b/tests/test_litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py index d07bfc4d31e..fbe82f07674 100644 --- a/tests/test_litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py +++ b/tests/test_litellm/proxy/_experimental/mcp_server/test_discoverable_endpoints.py @@ -12474,7 +12474,7 @@ def _complete_keyed_oauth(harness): client_id, verifier, handle = _start_keyed_oauth(harness) consent = harness.client.post("/authorize/connection/complete", data={"flow": handle, "decision": "approve"}) - assert consent.status_code == 307, consent.text + assert consent.status_code == 303, consent.text upstream = urlparse(consent.headers["location"]) assert upstream.netloc == "provider.example" params = parse_qs(upstream.query) @@ -12601,7 +12601,7 @@ def test_keyed_connection_cookie_sizes_are_browser_safe(keyed_oauth_client, stat assert approved.json()["error"] == "invalid_request" assert state_length == 1024 else: - assert approved.status_code == 307 + assert approved.status_code == 303 assert all(len(value) <= 4096 for value in approved.headers.get_list("set-cookie")) harness.upstream.post.assert_not_called() @@ -12893,7 +12893,7 @@ def test_keyed_connection_callback_cancellation_and_replay(keyed_oauth_client, c harness = keyed_oauth_client _, _, handle = _start_keyed_oauth(harness) approved = harness.client.post("/authorize/connection/complete", data={"flow": handle, "decision": "approve"}) - assert approved.status_code == 307 + assert approved.status_code == 303 state = parse_qs(urlparse(approved.headers["location"]).query)["state"][0] cookies = dict(harness.client.cookies.items()) response = harness.client.get( @@ -12919,7 +12919,7 @@ def test_keyed_connection_replayed_approved_consent_does_not_redirect_twice(keye _, _, handle = _start_keyed_oauth(harness) cookies = dict(harness.client.cookies.items()) approved = harness.client.post("/authorize/connection/complete", data={"flow": handle, "decision": "approve"}) - assert approved.status_code == 307 + assert approved.status_code == 303 harness.client.cookies.update(cookies) repeated = harness.client.post("/authorize/connection/complete", data={"flow": handle, "decision": "approve"}) assert repeated.status_code == 400 @@ -12935,7 +12935,7 @@ def test_keyed_connection_expired_callback_never_issues_code(keyed_oauth_client, harness = keyed_oauth_client _, _, handle = _start_keyed_oauth(harness) approved = harness.client.post("/authorize/connection/complete", data={"flow": handle, "decision": "approve"}) - assert approved.status_code == 307 + assert approved.status_code == 303 state = parse_qs(urlparse(approved.headers["location"]).query)["state"][0] clock = MagicMock() clock.now.return_value = datetime.now(timezone.utc) + timedelta(days=1)