What
When you sign in to an MCP server (an external tool server Claude Code connects to) with OAuth, Claude Code stores details of how it found the server's sign-in service, in discoveryState. Before, only authorizationServerUrl was kept. Now it keeps more and loses less.
discoveryStatenow also keepsoauthMetadataFoundandauthServerMetadataUrlalongsideauthorizationServerUrl, including when credentials are copied or saved.saveTokensnow writes a mergeddiscoveryStatewith the authorization server used at sign-in (discovered or overridden), the metadata URL that was served, and whether the sign-in was interactive. Plain token saves used to leave it alone.- After an interactive sign-in, a helper builds the stored state, sets
oauthMetadataFound: trueand clearsauthServerMetadataUrlto null. A non-interactive refresh keeps the previous value. - A new internal flag,
_flowDiscoveryStateFromConfiguredUrl, tracks whether the sign-in's discovery state came from a configured metadata URL; when it did, the overridden authorization server URL is taken from that state. invalidateCredentials('discovery')now keeps a trimmed copy (authorization server,oauthMetadataFound,authServerMetadataUrl) instead of clearing it.saveDiscoveryStatemerges with the previous state, records which configuredauthServerMetadataUrlserved the metadata, and keeps an earlierregistrationNotOfferedAtwhen no metadata came back.- The XAA silent refresh records which server issued the token by merging, instead of overwriting
discoveryState.
Why
Later token refreshes and re-sign-ins can go back to the same authorization server that issued the token, rather than losing that pointer. This matters most for MCP servers with a configured or non-standard metadata URL.
Something disagreesSomething we can check disagrees with this entry, or the writer said they could not settle it.
The writer flagged doubt
The effect on login refresh is inferred rather than shown.