@@ -9,8 +9,67 @@ import {
99} from "@modelcontextprotocol/sdk/shared/auth.js" ;
1010import { SESSION_KEYS , getServerSpecificKey } from "./constants" ;
1111
12+ export const getClientInformationFromSessionStorage = async ( {
13+ serverUrl,
14+ isPreregistered,
15+ } : {
16+ serverUrl : string ;
17+ isPreregistered ?: boolean ;
18+ } ) => {
19+ const key = getServerSpecificKey (
20+ isPreregistered
21+ ? SESSION_KEYS . PREREGISTERED_CLIENT_INFORMATION
22+ : SESSION_KEYS . CLIENT_INFORMATION ,
23+ serverUrl ,
24+ ) ;
25+
26+ const value = sessionStorage . getItem ( key ) ;
27+ if ( ! value ) {
28+ return undefined ;
29+ }
30+
31+ return await OAuthClientInformationSchema . parseAsync ( JSON . parse ( value ) ) ;
32+ } ;
33+
34+ export const saveClientInformationToSessionStorage = ( {
35+ serverUrl,
36+ clientInformation,
37+ isPreregistered,
38+ } : {
39+ serverUrl : string ;
40+ clientInformation : OAuthClientInformation ;
41+ isPreregistered ?: boolean ;
42+ } ) => {
43+ const key = getServerSpecificKey (
44+ isPreregistered
45+ ? SESSION_KEYS . PREREGISTERED_CLIENT_INFORMATION
46+ : SESSION_KEYS . CLIENT_INFORMATION ,
47+ serverUrl ,
48+ ) ;
49+ sessionStorage . setItem ( key , JSON . stringify ( clientInformation ) ) ;
50+ } ;
51+
52+ export const clearClientInformationFromSessionStorage = ( {
53+ serverUrl,
54+ isPreregistered,
55+ } : {
56+ serverUrl : string ;
57+ isPreregistered ?: boolean ;
58+ } ) => {
59+ const key = getServerSpecificKey (
60+ isPreregistered
61+ ? SESSION_KEYS . PREREGISTERED_CLIENT_INFORMATION
62+ : SESSION_KEYS . CLIENT_INFORMATION ,
63+ serverUrl ,
64+ ) ;
65+ sessionStorage . removeItem ( key ) ;
66+ } ;
67+
1268export class InspectorOAuthClientProvider implements OAuthClientProvider {
13- constructor ( public serverUrl : string ) {
69+ constructor (
70+ protected serverUrl : string ,
71+ protected resource ?: string ,
72+ ) {
1473 // Save the server URL to session storage
1574 sessionStorage . setItem ( SESSION_KEYS . SERVER_URL , serverUrl ) ;
1675 }
@@ -31,24 +90,29 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
3190 }
3291
3392 async clientInformation ( ) {
34- const key = getServerSpecificKey (
35- SESSION_KEYS . CLIENT_INFORMATION ,
36- this . serverUrl ,
93+ // Try to get the preregistered client information from session storage first
94+ const preregisteredClientInformation = await getClientInformationFromSessionStorage ( {
95+ serverUrl : this . serverUrl ,
96+ isPreregistered : true ,
97+ } ) ;
98+
99+ // If no preregistered client information is found, get the dynamically registered client information
100+ return (
101+ preregisteredClientInformation ??
102+ ( await getClientInformationFromSessionStorage ( {
103+ serverUrl : this . serverUrl ,
104+ isPreregistered : false ,
105+ } ) )
37106 ) ;
38- const value = sessionStorage . getItem ( key ) ;
39- if ( ! value ) {
40- return undefined ;
41- }
42-
43- return await OAuthClientInformationSchema . parseAsync ( JSON . parse ( value ) ) ;
44107 }
45108
46109 saveClientInformation ( clientInformation : OAuthClientInformation ) {
47- const key = getServerSpecificKey (
48- SESSION_KEYS . CLIENT_INFORMATION ,
49- this . serverUrl ,
50- ) ;
51- sessionStorage . setItem ( key , JSON . stringify ( clientInformation ) ) ;
110+ // Save the dynamically registered client information to session storage
111+ saveClientInformationToSessionStorage ( {
112+ serverUrl : this . serverUrl ,
113+ clientInformation,
114+ isPreregistered : false ,
115+ } ) ;
52116 }
53117
54118 async tokens ( ) {
@@ -67,6 +131,18 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
67131 }
68132
69133 redirectToAuthorization ( authorizationUrl : URL ) {
134+ /**
135+ * Note: This resource parameter is for testing purposes in Inspector.
136+ * Once MCP Client SDK supports resource indicators, this parameter
137+ * will be passed to the SDK's auth method similar to how scope is passed.
138+ *
139+ * See: https://github.com/modelcontextprotocol/typescript-sdk/pull/498
140+ *
141+ * TODO: @xiaoyijun Remove this once MCP Client SDK supports resource indicators.
142+ */
143+ if ( this . resource ) {
144+ authorizationUrl . searchParams . set ( "resource" , this . resource ) ;
145+ }
70146 window . location . href = authorizationUrl . href ;
71147 }
72148
@@ -92,9 +168,10 @@ export class InspectorOAuthClientProvider implements OAuthClientProvider {
92168 }
93169
94170 clear ( ) {
95- sessionStorage . removeItem (
96- getServerSpecificKey ( SESSION_KEYS . CLIENT_INFORMATION , this . serverUrl ) ,
97- ) ;
171+ clearClientInformationFromSessionStorage ( {
172+ serverUrl : this . serverUrl ,
173+ isPreregistered : false ,
174+ } ) ;
98175 sessionStorage . removeItem (
99176 getServerSpecificKey ( SESSION_KEYS . TOKENS , this . serverUrl ) ,
100177 ) ;
0 commit comments