@@ -17,6 +17,8 @@ import { InspectorConfig } from "./configurationTypes";
1717
1818/**
1919 * Get proxy headers for authentication
20+ * @param config - Inspector configuration containing proxy authentication settings
21+ * @returns Headers object with Content-Type and optional Bearer token
2022 */
2123function getProxyHeaders ( config : InspectorConfig ) : Record < string , string > {
2224 const { token, header } = getMCPProxyAuthToken ( config ) ;
@@ -32,121 +34,147 @@ function getProxyHeaders(config: InspectorConfig): Record<string, string> {
3234}
3335
3436/**
35- * Discover OAuth Authorization Server Metadata via proxy
37+ * Common helper for proxying fetch requests
38+ * @param endpoint - The API endpoint path (e.g., "/oauth/metadata")
39+ * @param method - HTTP method (GET or POST)
40+ * @param config - Inspector configuration containing proxy settings
41+ * @param body - Optional request body object
42+ * @param queryParams - Optional query parameters to append to URL
43+ * @returns Promise resolving to the typed response
44+ * @throws Error if the request fails or returns non-ok status
3645 */
37- export async function discoverAuthorizationServerMetadataViaProxy (
38- authServerUrl : URL ,
46+ async function proxyFetch < T > (
47+ endpoint : string ,
48+ method : "GET" | "POST" ,
3949 config : InspectorConfig ,
40- ) : Promise < OAuthMetadata > {
50+ body ?: object ,
51+ queryParams ?: Record < string , string > ,
52+ ) : Promise < T > {
4153 const proxyAddress = getMCPProxyAddress ( config ) ;
42- const url = new URL ( "/oauth/metadata" , proxyAddress ) ;
43- url . searchParams . set ( "authServerUrl" , authServerUrl . toString ( ) ) ;
54+ const url = new URL ( endpoint , proxyAddress ) ;
55+
56+ if ( queryParams ) {
57+ Object . entries ( queryParams ) . forEach ( ( [ key , value ] ) => {
58+ url . searchParams . set ( key , value ) ;
59+ } ) ;
60+ }
4461
4562 const response = await fetch ( url . toString ( ) , {
46- method : "GET" ,
63+ method,
4764 headers : getProxyHeaders ( config ) ,
65+ ...( body && { body : JSON . stringify ( body ) } ) ,
4866 } ) ;
4967
5068 if ( ! response . ok ) {
5169 const error = await response
5270 . json ( )
5371 . catch ( ( ) => ( { error : response . statusText } ) ) ;
54- throw new Error (
55- `Failed to discover OAuth metadata: ${ error . error || response . statusText } ` ,
56- ) ;
72+ throw new Error ( error . error || response . statusText ) ;
5773 }
5874
5975 return await response . json ( ) ;
6076}
6177
78+ /**
79+ * Discover OAuth Authorization Server Metadata via proxy
80+ * @param authServerUrl - The OAuth authorization server URL
81+ * @param config - Inspector configuration containing proxy settings
82+ * @returns Promise resolving to OAuth metadata
83+ * @throws Error if metadata discovery fails
84+ */
85+ export async function discoverAuthorizationServerMetadataViaProxy (
86+ authServerUrl : URL ,
87+ config : InspectorConfig ,
88+ ) : Promise < OAuthMetadata > {
89+ try {
90+ return await proxyFetch < OAuthMetadata > (
91+ "/oauth/metadata" ,
92+ "GET" ,
93+ config ,
94+ undefined ,
95+ { authServerUrl : authServerUrl . toString ( ) } ,
96+ ) ;
97+ } catch ( error ) {
98+ throw new Error (
99+ `Failed to discover OAuth metadata: ${ error instanceof Error ? error . message : String ( error ) } ` ,
100+ ) ;
101+ }
102+ }
103+
62104/**
63105 * Discover OAuth Protected Resource Metadata via proxy
106+ * @param serverUrl - The MCP server URL
107+ * @param config - Inspector configuration containing proxy settings
108+ * @returns Promise resolving to OAuth protected resource metadata
109+ * @throws Error if resource metadata discovery fails
64110 */
65111export async function discoverOAuthProtectedResourceMetadataViaProxy (
66112 serverUrl : string ,
67113 config : InspectorConfig ,
68114) : Promise < OAuthProtectedResourceMetadata > {
69- const proxyAddress = getMCPProxyAddress ( config ) ;
70- const url = new URL ( "/oauth/resource-metadata" , proxyAddress ) ;
71- url . searchParams . set ( "serverUrl" , serverUrl ) ;
72-
73- const response = await fetch ( url . toString ( ) , {
74- method : "GET" ,
75- headers : getProxyHeaders ( config ) ,
76- } ) ;
77-
78- if ( ! response . ok ) {
79- const error = await response
80- . json ( )
81- . catch ( ( ) => ( { error : response . statusText } ) ) ;
115+ try {
116+ return await proxyFetch < OAuthProtectedResourceMetadata > (
117+ "/oauth/resource-metadata" ,
118+ "GET" ,
119+ config ,
120+ undefined ,
121+ { serverUrl } ,
122+ ) ;
123+ } catch ( error ) {
82124 throw new Error (
83- `Failed to discover resource metadata: ${ error . error || response . statusText } ` ,
125+ `Failed to discover resource metadata: ${ error instanceof Error ? error . message : String ( error ) } ` ,
84126 ) ;
85127 }
86-
87- return await response . json ( ) ;
88128}
89129
90130/**
91131 * Register OAuth client via proxy (Dynamic Client Registration)
132+ * @param registrationEndpoint - The OAuth client registration endpoint URL
133+ * @param clientMetadata - OAuth client metadata for registration
134+ * @param config - Inspector configuration containing proxy settings
135+ * @returns Promise resolving to OAuth client information
136+ * @throws Error if client registration fails
92137 */
93138export async function registerClientViaProxy (
94139 registrationEndpoint : string ,
95140 clientMetadata : OAuthClientMetadata ,
96141 config : InspectorConfig ,
97142) : Promise < OAuthClientInformation > {
98- const proxyAddress = getMCPProxyAddress ( config ) ;
99- const url = new URL ( "/oauth/register" , proxyAddress ) ;
100-
101- const response = await fetch ( url . toString ( ) , {
102- method : "POST" ,
103- headers : getProxyHeaders ( config ) ,
104- body : JSON . stringify ( {
105- registrationEndpoint,
106- clientMetadata,
107- } ) ,
108- } ) ;
109-
110- if ( ! response . ok ) {
111- const error = await response
112- . json ( )
113- . catch ( ( ) => ( { error : response . statusText } ) ) ;
143+ try {
144+ return await proxyFetch < OAuthClientInformation > (
145+ "/oauth/register" ,
146+ "POST" ,
147+ config ,
148+ { registrationEndpoint, clientMetadata } ,
149+ ) ;
150+ } catch ( error ) {
114151 throw new Error (
115- `Failed to register client: ${ error . error || response . statusText } ` ,
152+ `Failed to register client: ${ error instanceof Error ? error . message : String ( error ) } ` ,
116153 ) ;
117154 }
118-
119- return await response . json ( ) ;
120155}
121156
122157/**
123158 * Exchange authorization code for tokens via proxy
159+ * @param tokenEndpoint - The OAuth token endpoint URL
160+ * @param params - Token exchange parameters (code, client_id, etc.)
161+ * @param config - Inspector configuration containing proxy settings
162+ * @returns Promise resolving to OAuth tokens
163+ * @throws Error if token exchange fails
124164 */
125165export async function exchangeAuthorizationViaProxy (
126166 tokenEndpoint : string ,
127167 params : Record < string , string > ,
128168 config : InspectorConfig ,
129169) : Promise < OAuthTokens > {
130- const proxyAddress = getMCPProxyAddress ( config ) ;
131- const url = new URL ( "/oauth/token" , proxyAddress ) ;
132-
133- const response = await fetch ( url . toString ( ) , {
134- method : "POST" ,
135- headers : getProxyHeaders ( config ) ,
136- body : JSON . stringify ( {
170+ try {
171+ return await proxyFetch < OAuthTokens > ( "/oauth/token" , "POST" , config , {
137172 tokenEndpoint,
138173 params,
139- } ) ,
140- } ) ;
141-
142- if ( ! response . ok ) {
143- const error = await response
144- . json ( )
145- . catch ( ( ) => ( { error : response . statusText } ) ) ;
174+ } ) ;
175+ } catch ( error ) {
146176 throw new Error (
147- `Failed to exchange authorization code: ${ error . error || response . statusText } ` ,
177+ `Failed to exchange authorization code: ${ error instanceof Error ? error . message : String ( error ) } ` ,
148178 ) ;
149179 }
150-
151- return await response . json ( ) ;
152180}
0 commit comments