@@ -200,20 +200,45 @@ export function startMcpServer(config: McpServerConfig, port: number): void {
200200 next ( ) ;
201201 } ) ;
202202
203- // Track transports by session ID, and which vendor owns each session
203+ const MAX_SESSIONS = 500 ;
204+ const SESSION_TTL_MS = 30 * 60 * 1000 ;
205+
204206 const transports : Record < string , StreamableHTTPServerTransport > = { } ;
205207 const sessionVendors : Record < string , string > = { } ;
208+ const sessionLastSeen : Record < string , number > = { } ;
209+
210+ setInterval ( ( ) => {
211+ const now = Date . now ( ) ;
212+ for ( const sid of Object . keys ( sessionLastSeen ) ) {
213+ if ( now - sessionLastSeen [ sid ] > SESSION_TTL_MS ) {
214+ transports [ sid ] ?. close ?.( ) ;
215+ delete transports [ sid ] ;
216+ delete sessionVendors [ sid ] ;
217+ delete sessionLastSeen [ sid ] ;
218+ }
219+ }
220+ } , 60_000 ) ;
206221
207222 app . post ( "/mcp" , async ( req , res ) => {
208223 try {
209224 const sessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
210225
211226 if ( sessionId && transports [ sessionId ] ) {
227+ sessionLastSeen [ sessionId ] = Date . now ( ) ;
212228 await transports [ sessionId ] . handleRequest ( req , res , req . body ) ;
213229 return ;
214230 }
215231
216232 if ( ! sessionId && isInitializeRequest ( req . body ) ) {
233+ if ( Object . keys ( transports ) . length >= MAX_SESSIONS ) {
234+ res . status ( 503 ) . json ( {
235+ jsonrpc : "2.0" ,
236+ error : { code : - 32000 , message : "Too many active sessions" } ,
237+ id : null ,
238+ } ) ;
239+ return ;
240+ }
241+
217242 const vendor = ( req as any ) . vendor as string ;
218243
219244 const transport = new StreamableHTTPServerTransport ( {
@@ -222,6 +247,7 @@ export function startMcpServer(config: McpServerConfig, port: number): void {
222247 onsessioninitialized : ( sid ) => {
223248 transports [ sid ] = transport ;
224249 sessionVendors [ sid ] = vendor ;
250+ sessionLastSeen [ sid ] = Date . now ( ) ;
225251 } ,
226252 } ) ;
227253
@@ -230,6 +256,7 @@ export function startMcpServer(config: McpServerConfig, port: number): void {
230256 if ( sid ) {
231257 delete transports [ sid ] ;
232258 delete sessionVendors [ sid ] ;
259+ delete sessionLastSeen [ sid ] ;
233260 }
234261 } ;
235262
@@ -257,21 +284,44 @@ export function startMcpServer(config: McpServerConfig, port: number): void {
257284 } ) ;
258285
259286 app . get ( "/mcp" , async ( req , res ) => {
260- const sessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
261- if ( ! sessionId || ! transports [ sessionId ] ) {
262- res . status ( 400 ) . send ( "Invalid or missing session ID" ) ;
263- return ;
287+ try {
288+ const sessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
289+ if ( ! sessionId || ! transports [ sessionId ] ) {
290+ res . status ( 400 ) . send ( "Invalid or missing session ID" ) ;
291+ return ;
292+ }
293+ sessionLastSeen [ sessionId ] = Date . now ( ) ;
294+ await transports [ sessionId ] . handleRequest ( req , res ) ;
295+ } catch ( error ) {
296+ console . error ( "[mcp] GET error:" , error ) ;
297+ if ( ! res . headersSent ) {
298+ res . status ( 500 ) . json ( {
299+ jsonrpc : "2.0" ,
300+ error : { code : - 32603 , message : "Internal server error" } ,
301+ id : null ,
302+ } ) ;
303+ }
264304 }
265- await transports [ sessionId ] . handleRequest ( req , res ) ;
266305 } ) ;
267306
268307 app . delete ( "/mcp" , async ( req , res ) => {
269- const sessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
270- if ( ! sessionId || ! transports [ sessionId ] ) {
271- res . status ( 400 ) . send ( "Invalid or missing session ID" ) ;
272- return ;
308+ try {
309+ const sessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
310+ if ( ! sessionId || ! transports [ sessionId ] ) {
311+ res . status ( 400 ) . send ( "Invalid or missing session ID" ) ;
312+ return ;
313+ }
314+ await transports [ sessionId ] . handleRequest ( req , res ) ;
315+ } catch ( error ) {
316+ console . error ( "[mcp] DELETE error:" , error ) ;
317+ if ( ! res . headersSent ) {
318+ res . status ( 500 ) . json ( {
319+ jsonrpc : "2.0" ,
320+ error : { code : - 32603 , message : "Internal server error" } ,
321+ id : null ,
322+ } ) ;
323+ }
273324 }
274- await transports [ sessionId ] . handleRequest ( req , res ) ;
275325 } ) ;
276326
277327 app . get ( "/health" , ( _req , res ) => {
0 commit comments