diff --git a/mcpServer/modules/filesystem/index.ts b/mcpServer/modules/filesystem/index.ts index 12485ba..a644761 100644 --- a/mcpServer/modules/filesystem/index.ts +++ b/mcpServer/modules/filesystem/index.ts @@ -633,6 +633,20 @@ function runServer() { transport.onclose = () => { sseTransportsBySessionId.delete(transport.sessionId); }; + // SSE heartbeat to prevent client ReadTimeout during idle (e.g. while waiting for Ollama) + const heartbeatIntervalMs = 15_000; + const heartbeatInterval = setInterval(() => { + try { + if (!res.writableEnded) { + res.write(': heartbeat\n\n'); + } else { + clearInterval(heartbeatInterval); + } + } catch { + clearInterval(heartbeatInterval); + } + }, heartbeatIntervalMs); + res.on('close', () => clearInterval(heartbeatInterval)); await server.connect(transport); console.error("Secure MCP Filesystem Server: new SSE client connected"); } catch (error) { diff --git a/mcpServer/modules/memory/index.ts b/mcpServer/modules/memory/index.ts index e938d2d..7508e5a 100644 --- a/mcpServer/modules/memory/index.ts +++ b/mcpServer/modules/memory/index.ts @@ -483,6 +483,18 @@ function runServer() { transport.onclose = () => { sseTransportsBySessionId.delete(transport.sessionId); }; + const heartbeatInterval = setInterval(() => { + try { + if (!res.writableEnded) { + res.write(': heartbeat\n\n'); + } else { + clearInterval(heartbeatInterval); + } + } catch { + clearInterval(heartbeatInterval); + } + }, 15_000); + res.on('close', () => clearInterval(heartbeatInterval)); await server.connect(transport); console.error("Knowledge Graph MCP Server: new SSE client connected"); } catch (error) { diff --git a/mcpServer/modules/sequentialthinking/index.ts b/mcpServer/modules/sequentialthinking/index.ts index ea84d65..d7b7866 100644 --- a/mcpServer/modules/sequentialthinking/index.ts +++ b/mcpServer/modules/sequentialthinking/index.ts @@ -123,6 +123,18 @@ function runServer() { transport.onclose = () => { sseTransportsBySessionId.delete(transport.sessionId); }; + const heartbeatInterval = setInterval(() => { + try { + if (!res.writableEnded) { + res.write(': heartbeat\n\n'); + } else { + clearInterval(heartbeatInterval); + } + } catch { + clearInterval(heartbeatInterval); + } + }, 15_000); + res.on('close', () => clearInterval(heartbeatInterval)); await server.connect(transport); console.error("Sequential Thinking MCP Server: new SSE client connected"); } catch (error) {