fix(mcp): scope oauth callback ports per provider - #34280
Conversation
|
Thanks for isolating the per-provider callback-port issue. The current-main premise is still valid: both construction paths overwrite Problems
Suggested changes
Automated hermes-sweeper review. |
…cross ports _wait_for_callback still read the legacy module-level _oauth_port, so with two concurrent OAuth flows, flow A's callback wait bound flow B's port while A's redirect URI pointed at A's port — the callback-side half of the cross-flow collision that #65622 fixed on the redirect side. _make_callback_waiter(port) closes over each flow's resolved port; both provider construction sites (build_oauth_auth and MCPOAuthManager._build_provider) now wire per-flow waiters. The legacy _wait_for_callback delegates for backwards compatibility. Direction credit to @LeonSGP43 (#34280) and the #34260 analysis.
…cross ports _wait_for_callback still read the legacy module-level _oauth_port, so with two concurrent OAuth flows, flow A's callback wait bound flow B's port while A's redirect URI pointed at A's port — the callback-side half of the cross-flow collision that #65622 fixed on the redirect side. _make_callback_waiter(port) closes over each flow's resolved port; both provider construction sites (build_oauth_auth and MCPOAuthManager._build_provider) now wire per-flow waiters. The legacy _wait_for_callback delegates for backwards compatibility. Direction credit to @LeonSGP43 (#34280) and the #34260 analysis.
|
Resolved on main via PR #65664 (commit d34cc40), which implements the same per-flow callback-waiter direction your PR and your #34260 analysis called for — |
…cross ports _wait_for_callback still read the legacy module-level _oauth_port, so with two concurrent OAuth flows, flow A's callback wait bound flow B's port while A's redirect URI pointed at A's port — the callback-side half of the cross-flow collision that NousResearch#65622 fixed on the redirect side. _make_callback_waiter(port) closes over each flow's resolved port; both provider construction sites (build_oauth_auth and MCPOAuthManager._build_provider) now wire per-flow waiters. The legacy _wait_for_callback delegates for backwards compatibility. Direction credit to @LeonSGP43 (NousResearch#34280) and the NousResearch#34260 analysis.
…cross ports _wait_for_callback still read the legacy module-level _oauth_port, so with two concurrent OAuth flows, flow A's callback wait bound flow B's port while A's redirect URI pointed at A's port — the callback-side half of the cross-flow collision that NousResearch#65622 fixed on the redirect side. _make_callback_waiter(port) closes over each flow's resolved port; both provider construction sites (build_oauth_auth and MCPOAuthManager._build_provider) now wire per-flow waiters. The legacy _wait_for_callback delegates for backwards compatibility. Direction credit to @LeonSGP43 (NousResearch#34280) and the NousResearch#34260 analysis.
Summary
_oauth_portfor compatibility, but stop using it as the live dispatch source once the provider is builtTesting
uv run --frozen pytest -q -o addopts='' tests/tools/test_mcp_oauth.py -k "per_provider or RedirectHandlerSshHint or WaitForCallbackNoBlocking or configure_callback_port or build_oauth_auth_preserves_server_url_path"uv run --frozen pytest -q -o addopts='' tests/tools/test_mcp_oauth_manager.py tests/tools/test_mcp_oauth.py -k "manager or per_provider or port_stored_globally or returns_oauth_provider or scope_passed_through or pre_registered_client_id_stored"uv run --frozen ruff check tools/mcp_oauth.py tools/mcp_oauth_manager.py tests/tools/test_mcp_oauth.pygit diff --checkRefs #34260