@@ -11,7 +11,19 @@ const server = new McpServer({
1111 version : "0.2.0" ,
1212} ) ;
1313
14- const thinkingServer = new SequentialThinkingServer ( ) ;
14+ const thinkingSessions = new Map < string , SequentialThinkingServer > ( ) ;
15+
16+ function getOrCreateThinkingServer ( sessionId ?: string ) : SequentialThinkingServer {
17+ if ( ! sessionId ) {
18+ return new SequentialThinkingServer ( ) ;
19+ }
20+
21+ if ( ! thinkingSessions . has ( sessionId ) ) {
22+ thinkingSessions . set ( sessionId , new SequentialThinkingServer ( ) ) ;
23+ }
24+
25+ return thinkingSessions . get ( sessionId ) ! ;
26+ }
1527
1628server . registerTool (
1729 "sequentialthinking" ,
@@ -91,6 +103,7 @@ You should:
91103 } ,
92104 } ,
93105 async ( args ) => {
106+ const thinkingServer = getOrCreateThinkingServer ( ) ;
94107 const result = thinkingServer . processThought ( args ) ;
95108
96109 if ( result . isError ) {
@@ -111,28 +124,69 @@ async function runServer() {
111124 if ( process . env . MCP_TRANSPORT === 'http' ) {
112125 const { createServer } = await import ( 'http' ) ;
113126 const transports : Record < string , StreamableHTTPServerTransport > = { } ;
127+ const sessionTimeouts : Record < string , NodeJS . Timeout > = { } ;
128+ const SESSION_TIMEOUT_MS = 30 * 60 * 1000 ; // 30 minutes
129+ const MAX_BODY_SIZE = 10 * 1024 * 1024 ; // 10MB
130+
131+ function cleanupSession ( sid : string ) {
132+ delete transports [ sid ] ;
133+ thinkingSessions . delete ( sid ) ;
134+ if ( sessionTimeouts [ sid ] ) {
135+ clearTimeout ( sessionTimeouts [ sid ] ) ;
136+ delete sessionTimeouts [ sid ] ;
137+ }
138+ }
139+
140+ function resetSessionTimeout ( sid : string ) {
141+ if ( sessionTimeouts [ sid ] ) {
142+ clearTimeout ( sessionTimeouts [ sid ] ) ;
143+ }
144+ sessionTimeouts [ sid ] = setTimeout ( ( ) => cleanupSession ( sid ) , SESSION_TIMEOUT_MS ) ;
145+ }
114146
115147 const httpServer = createServer ( async ( req , res ) => {
116148 const sessionId = req . headers [ 'mcp-session-id' ] as string | undefined ;
117149
118150 if ( req . method === 'POST' ) {
119- let body = '' ;
120- req . on ( 'data' , chunk => body += chunk ) ;
151+ const chunks : Buffer [ ] = [ ] ;
152+ let totalSize = 0 ;
153+
154+ req . on ( 'data' , chunk => {
155+ totalSize += chunk . length ;
156+ if ( totalSize > MAX_BODY_SIZE ) {
157+ req . destroy ( ) ;
158+ res . writeHead ( 413 ) ;
159+ res . end ( 'Request body too large' ) ;
160+ return ;
161+ }
162+ chunks . push ( chunk ) ;
163+ } ) ;
164+
121165 req . on ( 'end' , async ( ) => {
122- const parsedBody = body . trim ( ) ? JSON . parse ( body ) : undefined ;
166+ let parsedBody ;
167+ try {
168+ const body = Buffer . concat ( chunks ) . toString ( ) ;
169+ parsedBody = body . trim ( ) ? JSON . parse ( body ) : undefined ;
170+ } catch ( error ) {
171+ res . writeHead ( 400 ) ;
172+ res . end ( 'Invalid JSON' ) ;
173+ return ;
174+ }
123175
124176 let transport : StreamableHTTPServerTransport ;
125177 if ( sessionId && transports [ sessionId ] ) {
126178 transport = transports [ sessionId ] ;
179+ resetSessionTimeout ( sessionId ) ;
127180 } else if ( ! sessionId ) {
128181 transport = new StreamableHTTPServerTransport ( {
129182 sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
130183 onsessioninitialized : ( sid ) => {
131184 transports [ sid ] = transport ;
185+ resetSessionTimeout ( sid ) ;
132186 console . error ( 'Session initialized:' , sid ) ;
133187 } ,
134188 onsessionclosed : ( sid ) => {
135- delete transports [ sid ] ;
189+ cleanupSession ( sid ) ;
136190 console . error ( 'Session closed:' , sid ) ;
137191 }
138192 } ) ;
@@ -151,6 +205,7 @@ async function runServer() {
151205 res . end ( 'Invalid or missing session ID' ) ;
152206 return ;
153207 }
208+ resetSessionTimeout ( sessionId ) ;
154209 await transports [ sessionId ] . handleRequest ( req , res ) ;
155210 } else if ( req . method === 'DELETE' ) {
156211 if ( ! sessionId || ! transports [ sessionId ] ) {
@@ -159,6 +214,7 @@ async function runServer() {
159214 return ;
160215 }
161216 await transports [ sessionId ] . handleRequest ( req , res ) ;
217+ cleanupSession ( sessionId ) ;
162218 } else {
163219 res . writeHead ( 405 ) ;
164220 res . end ( 'Method not allowed' ) ;
0 commit comments