@@ -323,6 +323,8 @@ export class StreamableHTTPClientTransport implements Transport {
323323 private _serverRetryMs ?: number ; // Server-provided retry delay from SSE retry field
324324 private readonly _reconnectionScheduler ?: ReconnectionScheduler ;
325325 private _cancelReconnection ?: ( ) => void ;
326+ private _pendingAuthPromise ?: Promise < void > ;
327+ private _authReject ?: ( error : Error ) => void ;
326328
327329 onclose ?: ( ) => void ;
328330 onerror ?: ( error : Error ) => void ;
@@ -499,6 +501,9 @@ export class StreamableHTTPClientTransport implements Transport {
499501 }
500502
501503 private async _startOrAuthSse ( options : StartSSEOptions , isAuthRetry = false , stepUpRetries = 0 ) : Promise < void > {
504+ if ( this . _pendingAuthPromise ) {
505+ await this . _pendingAuthPromise ;
506+ }
502507 const { resumptionToken, requestSignal } = options ;
503508 // Same guard as `_handleSseStream`: a resurrected listen stream (the
504509 // POST-SSE → GET reconnect path threads `requestSignal` through
@@ -867,17 +872,35 @@ export class StreamableHTTPClientTransport implements Transport {
867872 { fetchFn : this . _fetchWithInit , resourceMetadataUrl : this . _resourceMetadataUrl }
868873 ) ;
869874
870- const result = await auth ( this . _oauthProvider , {
871- serverUrl : this . _url ,
872- authorizationCode,
873- iss : issParam ,
874- resourceMetadataUrl : this . _resourceMetadataUrl ,
875- scope : this . _scope ,
876- fetchFn : this . _fetchWithInit ,
877- skipIssuerMetadataValidation : this . _skipIssuerMetadataValidation
875+ let authResolve : ( ) => void ;
876+ this . _pendingAuthPromise = new Promise < void > ( ( resolve , reject ) => {
877+ authResolve = resolve ;
878+ this . _authReject = reject ;
878879 } ) ;
879- if ( result !== 'AUTHORIZED' ) {
880- throw new UnauthorizedError ( 'Failed to authorize' ) ;
880+ // Prevent UnhandledPromiseRejection if it fails and no one awaits it
881+ this . _pendingAuthPromise . catch ( ( ) => { } ) ;
882+
883+ try {
884+ const result = await auth ( this . _oauthProvider , {
885+ serverUrl : this . _url ,
886+ authorizationCode,
887+ iss : issParam ,
888+ resourceMetadataUrl : this . _resourceMetadataUrl ,
889+ scope : this . _scope ,
890+ fetchFn : this . _fetchWithInit ,
891+ skipIssuerMetadataValidation : this . _skipIssuerMetadataValidation
892+ } ) ;
893+ if ( result !== 'AUTHORIZED' ) {
894+ throw new UnauthorizedError ( 'Failed to authorize' ) ;
895+ }
896+ authResolve ! ( ) ;
897+ } catch ( error ) {
898+ const err = error instanceof Error ? error : new Error ( String ( error ) ) ;
899+ this . _authReject ?.( err ) ;
900+ throw error ;
901+ } finally {
902+ this . _pendingAuthPromise = undefined ;
903+ this . _authReject = undefined ;
881904 }
882905 }
883906
@@ -887,6 +910,13 @@ export class StreamableHTTPClientTransport implements Transport {
887910 } finally {
888911 this . _cancelReconnection = undefined ;
889912 this . _abortController ?. abort ( ) ;
913+
914+ if ( this . _authReject ) {
915+ this . _authReject ( new Error ( 'Transport closed' ) ) ;
916+ this . _pendingAuthPromise = undefined ;
917+ this . _authReject = undefined ;
918+ }
919+
890920 this . onclose ?.( ) ;
891921 }
892922 }
@@ -918,6 +948,9 @@ export class StreamableHTTPClientTransport implements Transport {
918948 isAuthRetry : boolean ,
919949 stepUpRetries = 0
920950 ) : Promise < void > {
951+ if ( this . _pendingAuthPromise ) {
952+ await this . _pendingAuthPromise ;
953+ }
921954 try {
922955 const { resumptionToken, onresumptiontoken } = options || { } ;
923956
0 commit comments