@@ -39,9 +39,15 @@ function getTimestamp(): string {
39
39
}
40
40
41
41
// Debug logging function
42
- export async function debugLog ( serverUrlHash : string , message : string , ...args : any [ ] ) : Promise < void > {
42
+ export async function debugLog ( message : string , ...args : any [ ] ) : Promise < void > {
43
43
if ( ! DEBUG ) return ;
44
44
45
+ const serverUrlHash = global . currentServerUrlHash ;
46
+ if ( ! serverUrlHash ) {
47
+ console . error ( "[DEBUG LOG ERROR] global.currentServerUrlHash is not set. Cannot write debug log." ) ;
48
+ return ;
49
+ }
50
+
45
51
try {
46
52
// Format with timestamp and PID
47
53
const formattedMessage = `[${ getTimestamp ( ) } ][${ pid } ] ${ message } ` ;
@@ -72,7 +78,7 @@ export function log(str: string, ...rest: unknown[]) {
72
78
73
79
// If debug mode is on, also log to debug file
74
80
if ( DEBUG && global . currentServerUrlHash ) {
75
- debugLog ( global . currentServerUrlHash , str , ...rest ) . catch ( ( ) => { } ) ;
81
+ debugLog ( str , ...rest ) . catch ( ( ) => { } ) ;
76
82
}
77
83
}
78
84
@@ -90,7 +96,7 @@ export function mcpProxy({ transportToClient, transportToServer }: { transportTo
90
96
log ( '[Local→Remote]' , message . method || message . id )
91
97
92
98
if ( DEBUG ) {
93
- debugLog ( global . currentServerUrlHash ! , 'Local → Remote message' , {
99
+ debugLog ( 'Local → Remote message' , {
94
100
method : message . method ,
95
101
id : message . id ,
96
102
params : message . params ? JSON . stringify ( message . params ) . substring ( 0 , 500 ) : undefined
@@ -103,7 +109,7 @@ export function mcpProxy({ transportToClient, transportToServer }: { transportTo
103
109
log ( JSON . stringify ( message , null , 2 ) )
104
110
105
111
if ( DEBUG ) {
106
- debugLog ( global . currentServerUrlHash ! , 'Initialize message with modified client info' , { clientInfo } ) . catch ( ( ) => { } )
112
+ debugLog ( 'Initialize message with modified client info' , { clientInfo } ) . catch ( ( ) => { } )
107
113
}
108
114
}
109
115
@@ -116,7 +122,7 @@ export function mcpProxy({ transportToClient, transportToServer }: { transportTo
116
122
log ( '[Remote→Local]' , message . method || message . id )
117
123
118
124
if ( DEBUG ) {
119
- debugLog ( global . currentServerUrlHash ! , 'Remote → Local message' , {
125
+ debugLog ( 'Remote → Local message' , {
120
126
method : message . method ,
121
127
id : message . id ,
122
128
result : message . result ? 'result-present' : undefined ,
@@ -133,7 +139,7 @@ export function mcpProxy({ transportToClient, transportToServer }: { transportTo
133
139
}
134
140
135
141
transportToClientClosed = true
136
- if ( DEBUG ) debugLog ( global . currentServerUrlHash ! , 'Local transport closed, closing remote transport' ) . catch ( ( ) => { } )
142
+ if ( DEBUG ) debugLog ( 'Local transport closed, closing remote transport' ) . catch ( ( ) => { } )
137
143
transportToServer . close ( ) . catch ( onServerError )
138
144
}
139
145
@@ -142,7 +148,7 @@ export function mcpProxy({ transportToClient, transportToServer }: { transportTo
142
148
return
143
149
}
144
150
transportToServerClosed = true
145
- if ( DEBUG ) debugLog ( global . currentServerUrlHash ! , 'Remote transport closed, closing local transport' ) . catch ( ( ) => { } )
151
+ if ( DEBUG ) debugLog ( 'Remote transport closed, closing local transport' ) . catch ( ( ) => { } )
146
152
transportToClient . close ( ) . catch ( onClientError )
147
153
}
148
154
@@ -151,12 +157,12 @@ export function mcpProxy({ transportToClient, transportToServer }: { transportTo
151
157
152
158
function onClientError ( error : Error ) {
153
159
log ( 'Error from local client:' , error )
154
- if ( DEBUG ) debugLog ( global . currentServerUrlHash ! , 'Error from local client' , { errorMessage : error . message , stack : error . stack } ) . catch ( ( ) => { } )
160
+ if ( DEBUG ) debugLog ( 'Error from local client' , { errorMessage : error . message , stack : error . stack } ) . catch ( ( ) => { } )
155
161
}
156
162
157
163
function onServerError ( error : Error ) {
158
164
log ( 'Error from remote server:' , error )
159
- if ( DEBUG ) debugLog ( global . currentServerUrlHash ! , 'Error from remote server' , { errorMessage : error . message , stack : error . stack } ) . catch ( ( ) => { } )
165
+ if ( DEBUG ) debugLog ( 'Error from remote server' , { errorMessage : error . message , stack : error . stack } ) . catch ( ( ) => { } )
160
166
}
161
167
}
162
168
@@ -227,27 +233,27 @@ export async function connectToRemoteServer(
227
233
} )
228
234
229
235
try {
230
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Attempting to connect to remote server' , { sseTransport } )
236
+ if ( DEBUG ) await debugLog ( 'Attempting to connect to remote server' , { sseTransport } )
231
237
232
238
if ( client ) {
233
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Connecting client to transport' )
239
+ if ( DEBUG ) await debugLog ( 'Connecting client to transport' )
234
240
await client . connect ( transport )
235
241
} else {
236
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Starting transport directly' )
242
+ if ( DEBUG ) await debugLog ( 'Starting transport directly' )
237
243
await transport . start ( )
238
244
if ( ! sseTransport ) {
239
245
// Extremely hacky, but we didn't actually send a request when calling transport.start() above, so we don't
240
246
// know if we're even talking to an HTTP server. But if we forced that now we'd get an error later saying that
241
247
// the client is already connected. So let's just create a one-off client to make a single request and figure
242
248
// out if we're actually talking to an HTTP server or not.
243
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Creating test transport for HTTP-only connection test' )
249
+ if ( DEBUG ) await debugLog ( 'Creating test transport for HTTP-only connection test' )
244
250
const testTransport = new StreamableHTTPClientTransport ( url , { authProvider, requestInit : { headers } } )
245
251
const testClient = new Client ( { name : 'mcp-remote-fallback-test' , version : '0.0.0' } , { capabilities : { } } )
246
252
await testClient . connect ( testTransport )
247
253
}
248
254
}
249
255
log ( `Connected to remote server using ${ transport . constructor . name } ` )
250
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , `Connected to remote server successfully` , { transportType : transport . constructor . name } )
256
+ if ( DEBUG ) await debugLog ( `Connected to remote server successfully` , { transportType : transport . constructor . name } )
251
257
252
258
return transport
253
259
} catch ( error ) {
@@ -287,57 +293,57 @@ export async function connectToRemoteServer(
287
293
} else if ( error instanceof UnauthorizedError || ( error instanceof Error && error . message . includes ( 'Unauthorized' ) ) ) {
288
294
log ( 'Authentication required. Initializing auth...' )
289
295
if ( DEBUG ) {
290
- await debugLog ( global . currentServerUrlHash ! , 'Authentication required, initializing auth process' , {
296
+ await debugLog ( 'Authentication required, initializing auth process' , {
291
297
errorMessage : error . message ,
292
298
stack : error . stack
293
299
} )
294
300
}
295
301
296
302
// Initialize authentication on-demand
297
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Calling authInitializer to start auth flow' )
303
+ if ( DEBUG ) await debugLog ( 'Calling authInitializer to start auth flow' )
298
304
const { waitForAuthCode, skipBrowserAuth } = await authInitializer ( )
299
305
300
306
if ( skipBrowserAuth ) {
301
307
log ( 'Authentication required but skipping browser auth - using shared auth' )
302
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Authentication required but skipping browser auth - using shared auth' )
308
+ if ( DEBUG ) await debugLog ( 'Authentication required but skipping browser auth - using shared auth' )
303
309
} else {
304
310
log ( 'Authentication required. Waiting for authorization...' )
305
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Authentication required. Waiting for authorization...' )
311
+ if ( DEBUG ) await debugLog ( 'Authentication required. Waiting for authorization...' )
306
312
}
307
313
308
314
// Wait for the authorization code from the callback
309
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Waiting for auth code from callback server' )
315
+ if ( DEBUG ) await debugLog ( 'Waiting for auth code from callback server' )
310
316
const code = await waitForAuthCode ( )
311
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Received auth code from callback server' )
317
+ if ( DEBUG ) await debugLog ( 'Received auth code from callback server' )
312
318
313
319
try {
314
320
log ( 'Completing authorization...' )
315
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Completing authorization with transport.finishAuth' )
321
+ if ( DEBUG ) await debugLog ( 'Completing authorization with transport.finishAuth' )
316
322
await transport . finishAuth ( code )
317
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Authorization completed successfully' )
323
+ if ( DEBUG ) await debugLog ( 'Authorization completed successfully' )
318
324
319
325
if ( recursionReasons . has ( REASON_AUTH_NEEDED ) ) {
320
326
const errorMessage = `Already attempted reconnection for reason: ${ REASON_AUTH_NEEDED } . Giving up.`
321
327
log ( errorMessage )
322
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Already attempted auth reconnection, giving up' , { recursionReasons : Array . from ( recursionReasons ) } )
328
+ if ( DEBUG ) await debugLog ( 'Already attempted auth reconnection, giving up' , { recursionReasons : Array . from ( recursionReasons ) } )
323
329
throw new Error ( errorMessage )
324
330
}
325
331
326
332
// Track this reason for recursion
327
333
recursionReasons . add ( REASON_AUTH_NEEDED )
328
334
log ( `Recursively reconnecting for reason: ${ REASON_AUTH_NEEDED } ` )
329
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Recursively reconnecting after auth' , { recursionReasons : Array . from ( recursionReasons ) } )
335
+ if ( DEBUG ) await debugLog ( 'Recursively reconnecting after auth' , { recursionReasons : Array . from ( recursionReasons ) } )
330
336
331
337
// Recursively call connectToRemoteServer with the updated recursion tracking
332
338
return connectToRemoteServer ( client , serverUrl , authProvider , headers , authInitializer , transportStrategy , recursionReasons )
333
339
} catch ( authError ) {
334
340
log ( 'Authorization error:' , authError )
335
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Authorization error during finishAuth' , { errorMessage : authError . message , stack : authError . stack } )
341
+ if ( DEBUG ) await debugLog ( 'Authorization error during finishAuth' , { errorMessage : authError . message , stack : authError . stack } )
336
342
throw authError
337
343
}
338
344
} else {
339
345
log ( 'Connection error:' , error )
340
- if ( DEBUG ) await debugLog ( global . currentServerUrlHash ! , 'Connection error' , {
346
+ if ( DEBUG ) await debugLog ( 'Connection error' , {
341
347
errorMessage : error . message ,
342
348
stack : error . stack ,
343
349
transportType : transport . constructor . name
@@ -617,7 +623,7 @@ export async function parseCommandLineArgs(args: string[], usage: string) {
617
623
global . currentServerUrlHash = serverUrlHash
618
624
619
625
if ( DEBUG ) {
620
- debugLog ( serverUrlHash , `Starting mcp-remote with server URL: ${ serverUrl } ` ) . catch ( ( ) => { } )
626
+ debugLog ( `Starting mcp-remote with server URL: ${ serverUrl } ` ) . catch ( ( ) => { } )
621
627
}
622
628
623
629
const defaultPort = calculateDefaultPort ( serverUrlHash )
0 commit comments