File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -85,6 +85,13 @@ def _empty_string_optional_url_to_none(cls, v: object) -> object:
8585 return None
8686 return v
8787
88+ @field_validator ("redirect_uris" , mode = "before" )
89+ @classmethod
90+ def _normalize_redirect_uris (cls , v : object ) -> object :
91+ if isinstance (v , list ):
92+ return [str (uri ) for uri in v ]
93+ return v
94+
8895 def validate_scope (self , requested_scope : str | None ) -> list [str ] | None :
8996 if requested_scope is None :
9097 return None
Original file line number Diff line number Diff line change 11"""Tests for OAuth 2.0 shared code."""
22
33import pytest
4- from pydantic import ValidationError
4+ from pydantic import AnyHttpUrl , AnyUrl , ValidationError
55
66from mcp .shared .auth import OAuthClientInformationFull , OAuthClientMetadata , OAuthMetadata
77
@@ -109,6 +109,18 @@ def test_valid_url_passes_through_unchanged():
109109 assert str (metadata .client_uri ) == "https://udemy.com/"
110110
111111
112+ def test_redirect_uri_url_subtypes_are_normalized ():
113+ info = OAuthClientInformationFull (
114+ client_id = "abc123" ,
115+ redirect_uris = [AnyHttpUrl ("https://example.com/callback" )],
116+ )
117+
118+ incoming = AnyUrl ("https://example.com/callback" )
119+
120+ assert info .validate_redirect_uri (incoming ) == incoming
121+ assert info .model_dump (mode = "json" )["redirect_uris" ] == ["https://example.com/callback" ]
122+
123+
112124def test_information_full_inherits_coercion ():
113125 """OAuthClientInformationFull subclasses OAuthClientMetadata, so the
114126 same coercion applies to DCR responses parsed via the full model."""
You can’t perform that action at this time.
0 commit comments