What happened?
MCP OAuth token responses treat expires_in=0 as if no expiry was provided.
In both authenticate() and refresh handling, the code only sets expiresAt when tokenResponse.expires_in is truthy:
if (tokenResponse.expires_in) {
token.expiresAt = Date.now() + tokenResponse.expires_in * 1000;
}
So a token endpoint response like this:
access_token=tok&token_type=Bearer&expires_in=0
gets saved without expiresAt, which makes it look non-expiring instead of immediately expired.
The form-urlencoded parser also uses parseInt, so malformed values such as expires_in=3600abc are partially accepted.
What did you expect?
expires_in=0 should produce an immediate expiresAt, and malformed expires_in values should not be silently accepted or saved.
What happened?
MCP OAuth token responses treat
expires_in=0as if no expiry was provided.In both
authenticate()and refresh handling, the code only setsexpiresAtwhentokenResponse.expires_inis truthy:So a token endpoint response like this:
gets saved without
expiresAt, which makes it look non-expiring instead of immediately expired.The form-urlencoded parser also uses
parseInt, so malformed values such asexpires_in=3600abcare partially accepted.What did you expect?
expires_in=0should produce an immediateexpiresAt, and malformedexpires_invalues should not be silently accepted or saved.