@@ -78,6 +78,7 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
7878 private _server : http . Server | null ,
7979 private _port : number ,
8080 private _authCodePromise : Promise < string > | null ,
81+ private _cancelCallbackServer : ( ( ) => void ) | null ,
8182 private readonly _tokenEndpointAuthMethod : string ,
8283 private readonly _grantTypes : string [ ] ,
8384 private readonly _scopes : string [ ] ,
@@ -122,9 +123,9 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
122123 }
123124
124125 // Extract auth-method preferences.
125- // Prefer "none" → first supported → " client_secret_post"
126+ // Only pick methods we actually implement: "none" or " client_secret_post".
126127 const authMethods : string [ ] = authServerMeta ?. token_endpoint_auth_methods_supported ?? [ ]
127- const tokenEndpointAuthMethod = authMethods . includes ( "none" ) ? "none" : ( authMethods [ 0 ] ?? "client_secret_post" )
128+ const tokenEndpointAuthMethod = authMethods . includes ( "none" ) ? "none" : "client_secret_post"
128129 const grantTypes : string [ ] = authServerMeta ?. grant_types_supported ?? [ "authorization_code" , "refresh_token" ]
129130 const scopes : string [ ] = authServerMeta ?. scopes_supported ?? [ ]
130131
@@ -142,6 +143,7 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
142143 null ,
143144 0 ,
144145 null ,
146+ null ,
145147 tokenEndpointAuthMethod ,
146148 grantTypes ,
147149 scopes ,
@@ -178,9 +180,10 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
178180
179181 private async _doStartCallbackServer ( ) : Promise < void > {
180182 this . _closed = false
181- const { server, port, result } = await startCallbackServer ( this . _port , this . _state )
183+ const { server, port, result, cancel } = await startCallbackServer ( this . _port , this . _state )
182184 this . _server = server
183185 this . _port = port
186+ this . _cancelCallbackServer = cancel
184187 this . _authCodePromise = result . then ( ( r ) => {
185188 if ( r . error ) throw new Error ( `OAuth authorization failed: ${ r . error } ` )
186189 if ( ! r . code ) throw new Error ( "No authorization code received in callback" )
@@ -442,6 +445,12 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
442445 code_verifier : codeVerifier ,
443446 }
444447
448+ // RFC 8707: include resource indicator so servers that bind token requests
449+ // to a specific resource can validate the exchange.
450+ if ( this . _resourceIndicator ) {
451+ params . resource = this . _resourceIndicator
452+ }
453+
445454 // Include client_secret in the body when the auth method is client_secret_post.
446455 if ( this . _tokenEndpointAuthMethod === "client_secret_post" && this . _clientInfo . client_secret ) {
447456 params . client_secret = this . _clientInfo . client_secret
@@ -489,6 +498,11 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
489498 client_id : clientId ,
490499 }
491500
501+ // RFC 8707: include resource indicator in refresh requests too.
502+ if ( this . _resourceIndicator ) {
503+ params . resource = this . _resourceIndicator
504+ }
505+
492506 if ( this . _tokenEndpointAuthMethod === "client_secret_post" && this . _clientInfo ?. client_secret ) {
493507 params . client_secret = this . _clientInfo . client_secret
494508 }
@@ -521,8 +535,9 @@ export class McpOAuthClientProvider implements OAuthClientProvider {
521535 }
522536 if ( ! this . _closed && this . _server ) {
523537 this . _closed = true
524- await stopCallbackServer ( this . _server ) . catch ( ( ) => { } )
538+ await stopCallbackServer ( this . _server , this . _cancelCallbackServer ?? ( ( ) => { } ) ) . catch ( ( ) => { } )
525539 this . _server = null
540+ this . _cancelCallbackServer = null
526541 this . _authCodePromise = null
527542 }
528543 }
0 commit comments