@@ -5,8 +5,12 @@ import {
55 registerClient ,
66 startAuthorization ,
77 exchangeAuthorization ,
8+ defaultValidateResource ,
89 discoverOAuthProtectedResourceMetadata ,
910} from "@modelcontextprotocol/sdk/client/auth.js" ;
11+ import {
12+ resourceUrlFromServerUrl
13+ } from "@modelcontextprotocol/sdk/shared/auth-utils.js" ;
1014import {
1115 OAuthMetadataSchema ,
1216 OAuthProtectedResourceMetadata ,
@@ -39,10 +43,8 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
3943 resourceMetadata = await discoverOAuthProtectedResourceMetadata (
4044 context . serverUrl ,
4145 ) ;
42- if ( resourceMetadata ) {
43- if ( resourceMetadata . authorization_servers ?. length ) {
44- authServerUrl = new URL ( resourceMetadata . authorization_servers [ 0 ] ) ;
45- }
46+ if ( resourceMetadata ?. authorization_servers ?. length ) {
47+ authServerUrl = new URL ( resourceMetadata . authorization_servers [ 0 ] ) ;
4648 }
4749 } catch ( e ) {
4850 if ( e instanceof Error ) {
@@ -52,12 +54,10 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
5254 }
5355 }
5456
57+ let resource : string | undefined ;
5558 if ( resourceMetadata ) {
56- if ( resourceMetadata . resource !== context . serverUrl ) {
57- throw new Error (
58- `Resource URL from metadata does not match server URL. ${ resourceMetadata . resource } != ${ context . serverUrl } ` ,
59- ) ;
60- }
59+ resource = resourceUrlFromServerUrl ( context . serverUrl ) ;
60+ defaultValidateResource ( resource , resourceMetadata . resource )
6161 }
6262
6363 const metadata = await discoverOAuthMetadata ( authServerUrl ) ;
@@ -68,6 +68,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
6868 context . provider . saveServerMetadata ( parsedMetadata ) ;
6969 context . updateState ( {
7070 resourceMetadata,
71+ resource,
7172 resourceMetadataError,
7273 authServerUrl,
7374 oauthMetadata : parsedMetadata ,
@@ -123,7 +124,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
123124 clientInformation,
124125 redirectUrl : context . provider . redirectUrl ,
125126 scope,
126- resource : new URL ( context . serverUrl ) ,
127+ resource : context . state . resource ,
127128 } ,
128129 ) ;
129130
@@ -174,7 +175,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
174175 authorizationCode : context . state . authorizationCode ,
175176 codeVerifier,
176177 redirectUri : context . provider . redirectUrl ,
177- resource : new URL ( context . serverUrl ) ,
178+ resource : context . state . resource ,
178179 } ) ;
179180
180181 context . provider . saveTokens ( tokens ) ;
@@ -184,7 +185,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
184185 } ) ;
185186 } ,
186187 } ,
187-
188+
188189 validate_token : {
189190 canTransition : async ( context ) => {
190191 return ! ! context . state . oauthTokens && ! ! context . state . oauthTokens . access_token ;
@@ -197,7 +198,7 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
197198 try {
198199 // Create a simple client with the StreamableHTTP transport
199200 const transport = new StreamableHTTPClientTransport (
200- new URL ( context . serverUrl ) ,
201+ new URL ( context . serverUrl ) ,
201202 {
202203 requestInit : {
203204 headers : {
@@ -206,16 +207,16 @@ export const oauthTransitions: Record<OAuthStep, StateTransition> = {
206207 }
207208 }
208209 ) ;
209-
210+
210211 const client = new Client (
211212 { name : "mcp-auth-validator" , version : "1.0.0" } ,
212213 { capabilities : { } }
213214 ) ;
214-
215+
215216 // Connect and list tools to validate the token
216217 await client . connect ( transport ) ;
217218 const response = await client . listTools ( ) ;
218-
219+
219220 // Successfully validated token
220221 context . updateState ( {
221222 oauthStep : "complete" ,
0 commit comments