Skip to content

Commit 04df856

Browse files
author
Jah-yee
committed
fix: preserve existing refresh_token when server omits it in refresh response
Per RFC 6749 Section 6, the authorization server MAY issue a new refresh token in the refresh response. If omitted, the client must preserve the existing one. This fix prevents token refresh failures after the first refresh when using OAuth providers that don't return refresh tokens in responses (e.g., Google, Auth0 without rotation, Okta in persistent token mode). Fixes #2270
1 parent 62eb08e commit 04df856

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/mcp/client/auth/oauth2.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,17 @@ async def _handle_refresh_response(self, response: httpx.Response) -> bool: # p
458458
content = await response.aread()
459459
token_response = OAuthToken.model_validate_json(content)
460460

461+
# Per RFC 6749 Section 6, the server MAY issue a new refresh token.
462+
# If the response omits it, preserve the existing one.
463+
if (
464+
not token_response.refresh_token
465+
and self.context.current_tokens
466+
and self.context.current_tokens.refresh_token
467+
):
468+
token_response = token_response.model_copy(
469+
update={"refresh_token": self.context.current_tokens.refresh_token}
470+
)
471+
461472
self.context.current_tokens = token_response
462473
self.context.update_token_expiry(token_response)
463474
await self.context.storage.set_tokens(token_response)

0 commit comments

Comments
 (0)