@@ -141,7 +141,7 @@ let backingServerTransport: Transport | undefined;
141
141
142
142
app . get ( "/mcp" , async ( req , res ) => {
143
143
const sessionId = req . headers [ "mcp-session-id" ] as string ;
144
- console . log ( `Received GET message for sessionId ${ sessionId } ` ) ;
144
+ console . log ( `GET /mcp for sessionId ${ sessionId } ` ) ;
145
145
try {
146
146
const transport = webAppTransports . get (
147
147
sessionId ,
@@ -160,7 +160,7 @@ app.get("/mcp", async (req, res) => {
160
160
161
161
app . post ( "/mcp" , async ( req , res ) => {
162
162
const sessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
163
- console . log ( `Received POST message for sessionId ${ sessionId } ` ) ;
163
+ console . log ( `POST /mcp for sessionId ${ sessionId } ` ) ;
164
164
if ( ! sessionId ) {
165
165
try {
166
166
console . log ( "New streamable-http connection" ) ;
@@ -228,7 +228,7 @@ app.post("/mcp", async (req, res) => {
228
228
229
229
app . get ( "/stdio" , async ( req , res ) => {
230
230
try {
231
- console . log ( "New connection " ) ;
231
+ console . log ( "GET /stdio " ) ;
232
232
233
233
try {
234
234
await backingServerTransport ?. close ( ) ;
@@ -254,18 +254,53 @@ app.get("/stdio", async (req, res) => {
254
254
console . log ( "Created web app transport" ) ;
255
255
256
256
await webAppTransport . start ( ) ;
257
- ( backingServerTransport as StdioClientTransport ) . stderr ! . on (
258
- "data" ,
259
- ( chunk ) => {
260
- webAppTransport . send ( {
261
- jsonrpc : "2.0" ,
262
- method : "notifications/stderr" ,
263
- params : {
264
- content : chunk . toString ( ) ,
265
- } ,
266
- } ) ;
267
- } ,
268
- ) ;
257
+
258
+ // Handle client disconnection
259
+ res . on ( "close" , ( ) => {
260
+ console . log (
261
+ `Client disconnected from session ${ webAppTransport . sessionId } ` ,
262
+ ) ;
263
+ // Clean up the transport map
264
+ webAppTransports . delete ( webAppTransport . sessionId ) ;
265
+ } ) ;
266
+
267
+ // Create a stderr handler that checks connection state
268
+ const stderrHandler = ( chunk : Buffer ) => {
269
+ // Only send if the transport exists in our map (meaning it's still active)
270
+ if ( webAppTransports . has ( webAppTransport . sessionId ) ) {
271
+ webAppTransport
272
+ . send ( {
273
+ jsonrpc : "2.0" ,
274
+ method : "notifications/stderr" ,
275
+ params : {
276
+ content : chunk . toString ( ) ,
277
+ } ,
278
+ } )
279
+ . catch ( ( error : any ) => {
280
+ console . error (
281
+ `Error sending stderr data to client: ${ error . message } ` ,
282
+ ) ;
283
+ // If we hit an error sending, clean up the transport
284
+ webAppTransports . delete ( webAppTransport . sessionId ) ;
285
+ } ) ;
286
+ }
287
+ } ;
288
+
289
+ if ( ( backingServerTransport as StdioClientTransport ) . stderr ) {
290
+ ( backingServerTransport as StdioClientTransport ) . stderr ! . on (
291
+ "data" ,
292
+ stderrHandler ,
293
+ ) ;
294
+
295
+ // Store the handler reference so we can remove it when client disconnects
296
+ res . on ( "close" , ( ) => {
297
+ if ( ( backingServerTransport as StdioClientTransport ) . stderr ) {
298
+ (
299
+ backingServerTransport as StdioClientTransport
300
+ ) . stderr ! . removeListener ( "data" , stderrHandler ) ;
301
+ }
302
+ } ) ;
303
+ }
269
304
270
305
mcpProxy ( {
271
306
transportToClient : webAppTransport ,
@@ -282,7 +317,7 @@ app.get("/stdio", async (req, res) => {
282
317
app . get ( "/sse" , async ( req , res ) => {
283
318
try {
284
319
console . log (
285
- "New SSE connection. NOTE: The sse transport is deprecated and has been replaced by streamable-http" ,
320
+ "GET /sse ( NOTE: The sse transport is deprecated and has been replaced by streamable-http) " ,
286
321
) ;
287
322
288
323
try {
@@ -324,7 +359,7 @@ app.get("/sse", async (req, res) => {
324
359
app . post ( "/message" , async ( req , res ) => {
325
360
try {
326
361
const sessionId = req . query . sessionId ;
327
- console . log ( `Received message for sessionId ${ sessionId } ` ) ;
362
+ console . log ( `POST / message for sessionId ${ sessionId } ` ) ;
328
363
329
364
const transport = webAppTransports . get (
330
365
sessionId as string ,
@@ -341,13 +376,15 @@ app.post("/message", async (req, res) => {
341
376
} ) ;
342
377
343
378
app . get ( "/health" , ( req , res ) => {
379
+ console . log ( "GET /health" ) ;
344
380
res . json ( {
345
381
status : "ok" ,
346
382
} ) ;
347
383
} ) ;
348
384
349
385
app . get ( "/config" , ( req , res ) => {
350
386
try {
387
+ console . log ( "GET /config" ) ;
351
388
res . json ( {
352
389
defaultEnvironment,
353
390
defaultCommand : values . env ,
0 commit comments