Title: fix: normalize OAuth redirect URI URL subtypes by fengjikui · Pull Request #2953 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: fix: normalize OAuth redirect URI URL subtypes by fengjikui · Pull Request #2953 · modelcontextprotocol/python-sdk
X Title: fix: normalize OAuth redirect URI URL subtypes by fengjikui · Pull Request #2953 · modelcontextprotocol/python-sdk
Description: Summary Fixes #2687 by normalizing OAuthClientMetadata.redirect_uris entries at the model boundary. If callers pass a Pydantic URL subtype such as AnyHttpUrl, the value is revalidated through the declared AnyUrl field type instead of being stored as the stricter subtype. Root cause Pydantic v2 URL equality is type-strict. A stored AnyHttpUrl("https://example.com/callback") and an incoming AnyUrl("https://example.com/callback") serialize to the same string, but compare non-equal. That makes validate_redirect_uri() reject a registered redirect URI during OAuth flows. Changes Added a redirect_uris field validator that stringifies existing AnyUrl instances before Pydantic validates the field. Added regression coverage for OAuthClientInformationFull(redirect_uris=[AnyHttpUrl(...)]) validating an incoming equivalent AnyUrl(...). Kept JSON serialization unchanged and still reject unrelated redirect URIs. Validation uv run pytest tests/shared/test_auth.py::test_redirect_uri_subtypes_normalized_for_validation -q failed before the fix with InvalidRedirectUriError. uv run ruff format --check src/mcp/shared/auth.py tests/shared/test_auth.py uv run ruff check src/mcp/shared/auth.py tests/shared/test_auth.py uv run pytest tests/shared/test_auth.py tests/client/test_auth.py tests/interaction/auth/test_authorize_token.py -q -> 155 passed, 1 xfailed git diff --check
Open Graph Description: Summary Fixes #2687 by normalizing OAuthClientMetadata.redirect_uris entries at the model boundary. If callers pass a Pydantic URL subtype such as AnyHttpUrl, the value is revalidated through the d...
X Description: Summary Fixes #2687 by normalizing OAuthClientMetadata.redirect_uris entries at the model boundary. If callers pass a Pydantic URL subtype such as AnyHttpUrl, the value is revalidated through the d...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/2953
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:863291bd-3057-745e-de28-698d3f0280a5 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 8DD6:109F8C:1549E:1D4D8:6A5A3F0F |
| html-safe-nonce | 3a963489582308604bfa30a1e1cd4317485983829dced8c82786af751d1e9809 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4REQ2OjEwOUY4QzoxNTQ5RToxRDREODo2QTVBM0YwRiIsInZpc2l0b3JfaWQiOiI2NDg0NTg4Mjk0Mzk5NzM3NjE1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 0122477b2f79f40fa53256eb8ed0cb24f4b4bcea6d7e058a2b3c7fb5471ff96a |
| hovercard-subject-tag | pull_request:3919836068 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelcontextprotocol/python-sdk/pull/2953/files |
| twitter:image | https://avatars.githubusercontent.com/u/56265583?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/56265583?s=400&v=4 |
| og:image:alt | Summary Fixes #2687 by normalizing OAuthClientMetadata.redirect_uris entries at the model boundary. If callers pass a Pydantic URL subtype such as AnyHttpUrl, the value is revalidated through the d... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 19c67ad7579d2401ff06e88a32ef45460fbb40fab3191c7f7582d5e166f326fc |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelcontextprotocol/python-sdk git https://github.com/modelcontextprotocol/python-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 862584018 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/python-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 862584018 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/python-sdk |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | e618485bff22dab2ef1ffb4e34e4e6626688df69 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width