Title: Fix RFC 8252 Section 7.3 compliance for loopback redirect URIs by williamomeara · Pull Request #1934 · modelcontextprotocol/python-sdk · GitHub
Open Graph Title: Fix RFC 8252 Section 7.3 compliance for loopback redirect URIs by williamomeara · Pull Request #1934 · modelcontextprotocol/python-sdk
X Title: Fix RFC 8252 Section 7.3 compliance for loopback redirect URIs by williamomeara · Pull Request #1934 · modelcontextprotocol/python-sdk
Description: Problem The MCP SDK's OAuthClientMetadata.validate_redirect_uri() method performs exact string matching on redirect URIs, which violates RFC 8252 Section 7.3 for loopback addresses. RFC 8252 Section 7.3 states: "The authorization server MUST allow any port to be specified at the time of the request for loopback IP redirect URIs, to accommodate clients that obtain an available ephemeral port from the operating system at the time of the request." Impact This prevents native OAuth clients (like GitHub Copilot CLI) from successfully completing OAuth flows with MCP servers, as these clients typically use ephemeral ports for their loopback redirect listeners. Solution This PR updates the validation logic to be RFC 8252-compliant: For loopback addresses (localhost, 127.0.0.1, ::1): Port is ignored during validation; scheme, hostname, and path must match For non-loopback URIs: Exact matching as before (no behavior change) Changes Updated src/mcp/shared/auth.py: Added urllib.parse import for URL parsing Enhanced validate_redirect_uri() with RFC 8252 logic Added comprehensive docstring explaining the behavior Added tests/shared/test_rfc8252_redirect_uri.py: 13 comprehensive tests covering all validation scenarios Tests for loopback addresses (localhost, 127.0.0.1, ::1) Tests for non-loopback addresses (exact matching preserved) Edge cases and error conditions Testing All 13 new tests pass: tests/shared/test_rfc8252_redirect_uri.py::test_exact_match_non_loopback PASSED tests/shared/test_rfc8252_redirect_uri.py::test_loopback_localhost_port_ignored PASSED tests/shared/test_rfc8252_redirect_uri.py::test_loopback_ipv4_port_ignored PASSED tests/shared/test_rfc8252_redirect_uri.py::test_loopback_ipv6_port_ignored PASSED tests/shared/test_rfc8252_redirect_uri.py::test_loopback_scheme_must_match PASSED tests/shared/test_rfc8252_redirect_uri.py::test_loopback_path_must_match PASSED tests/shared/test_rfc8252_redirect_uri.py::test_loopback_hostname_must_match PASSED tests/shared/test_rfc8252_redirect_uri.py::test_multiple_redirect_uris_loopback PASSED tests/shared/test_rfc8252_redirect_uri.py::test_mixed_loopback_and_non_loopback PASSED tests/shared/test_rfc8252_redirect_uri.py::test_no_redirect_uris_registered PASSED tests/shared/test_rfc8252_redirect_uri.py::test_single_registered_uri_omit_request PASSED tests/shared/test_rfc8252_redirect_uri.py::test_multiple_registered_uris_omit_request PASSED tests/shared/test_rfc8252_redirect_uri.py::test_root_path_normalization PASSED Backward Compatibility This change is fully backward compatible: Non-loopback URIs continue to use exact matching Existing clients with static ports will continue to work Only adds support for the RFC-mandated ephemeral port behavior References RFC 8252 Section 7.3: Loopback Interface Redirection Real-world example: GitHub Copilot CLI uses ephemeral ports (e.g., http://127.0.0.1:60847/ varies per session)
Open Graph Description: Problem The MCP SDK's OAuthClientMetadata.validate_redirect_uri() method performs exact string matching on redirect URIs, which violates RFC 8252 Section 7.3 for loopback addresses. RFC 8252 Se...
X Description: Problem The MCP SDK's OAuthClientMetadata.validate_redirect_uri() method performs exact string matching on redirect URIs, which violates RFC 8252 Section 7.3 for loopback addresses. RFC 825...
Opengraph URL: https://github.com/modelcontextprotocol/python-sdk/pull/1934
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:1e6f3661-7d92-d0ef-98ea-13bc81cab1f8 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | EC34:869B8:CC6DA5:10B5361:6A5AEB4D |
| html-safe-nonce | 4408f87465bf0ff50bae02fa0a1e6f447fe8eb56dc020cb2563befd6036ee914 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFQzM0Ojg2OUI4OkNDNkRBNToxMEI1MzYxOjZBNUFFQjREIiwidmlzaXRvcl9pZCI6IjE1OTMyMDk0MzE1MTY3MDM1NjUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 72e7f52b5975e083166c070c653830ec3974c9bbf94ce95c5574f9f6e06b055c |
| hovercard-subject-tag | pull_request:3201359115 |
| 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/1934/files |
| twitter:image | https://avatars.githubusercontent.com/u/26003676?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/26003676?s=400&v=4 |
| og:image:alt | Problem The MCP SDK's OAuthClientMetadata.validate_redirect_uri() method performs exact string matching on redirect URIs, which violates RFC 8252 Section 7.3 for loopback addresses. RFC 8252 Se... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5290d7e14309ad1e76106a9c4237bd1041517e83ea182c8ab756752cb0c6940b |
| 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 | 9c975978430e9ad293956f2bbdaf153b1bd84a99 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width