@@ -603,6 +603,16 @@ def _select_authorization_server(self, advertised: list[str]) -> str:
603603 """Which of the servers listed in protected resource metadata to use: the first (the list is never empty)."""
604604 return advertised [0 ]
605605
606+ def _needs_token_refresh (self ) -> bool :
607+ return (not self .context .is_token_valid ()) and self .context .can_refresh_token ()
608+
609+ def _unauthorized_token_changed (self , response : httpx2 .Response , sent_access_token : str | None ) -> bool :
610+ """True when a 401 is stale because another request already replaced the access token."""
611+ if response .status_code != 401 :
612+ return False
613+ current = self .context .current_tokens .access_token if self .context .current_tokens else None
614+ return current is not None and current != sent_access_token
615+
606616 def _expected_issuer (self ) -> str :
607617 """The issuer that authorization server metadata and client credentials must belong to: the
608618 PRM-advertised server, or on the legacy no-PRM path the resource server's origin, which is what
@@ -626,14 +636,13 @@ async def _auth_flow(self, request: httpx2.Request) -> AsyncGenerator[httpx2.Req
626636
627637 # Capture protocol version from request headers
628638 self .context .protocol_version = request .headers .get (MCP_PROTOCOL_VERSION_HEADER )
629- if not self .context .is_token_valid () and self .context .can_refresh_token ():
630- needs_refresh = True
639+ needs_refresh = self ._needs_token_refresh ()
631640
632641 if needs_refresh :
633642 async with self .context .refresh_lock :
634643 refresh_request = None
635644 async with self .context .lock :
636- if not self .context . is_token_valid () and self . context . can_refresh_token ():
645+ if self ._needs_token_refresh ():
637646 refresh_request = await self ._refresh_token ()
638647 if refresh_request is not None :
639648 refresh_response = yield refresh_request
@@ -654,12 +663,7 @@ async def _auth_flow(self, request: httpx2.Request) -> AsyncGenerator[httpx2.Req
654663
655664 if response .status_code == 401 or step_up :
656665 async with self .context .lock :
657- current_access_token = self .context .current_tokens .access_token if self .context .current_tokens else None
658- if (
659- response .status_code == 401
660- and current_access_token is not None
661- and current_access_token != sent_access_token
662- ):
666+ if self ._unauthorized_token_changed (response , sent_access_token ):
663667 # Another request refreshed or re-authorized while this one was in flight.
664668 self ._add_auth_header (request )
665669 yield request
0 commit comments