-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug
Calling transport.close()
on the NodeJS
server-side StreamableHTTPServerTransport
does not fully close all active streaming connections or resources. As a result, the Node.js process does not exit cleanly, and nodemon hangs with the message:
[nodemon] still waiting for 1 sub-process to finish...
To Reproduce
- Steps to reproduce the behavior:
- Run an MCP server using
StreamableHTTPServerTransport
. - Connect one or more streaming clients (e.g., MCP inspector).
- Handle shutdown signals (
SIGINT
,SIGTERM
) by callingtransport.close()
and closing the HTTP server. - Observe that despite calling
transport.close()
, the Node process remains alive and nodemon hangs waiting for the process to exit.
Expected behavior
- Calling
transport.close()
onStreamableHTTPServerTransport
should: - Immediately terminate all active streaming connections (
SSE
orHTTP
streams). - Clean up all timers, event listeners, and other resources.
- Fully free all handles so that the Node.js process can exit cleanly after shutdown.
Logs
If applicable, add logs to help explain your problem.
console.log('Active handles:', (process as any)._getActiveHandles());
shows lingering Socket and Server handles even after calling transport.close()
.
Also, nodemon logs:
[nodemon] still waiting for 1 sub-process to finish...
Additional context
This issue occurs specifically during shutdown triggered by process signals (SIGINT
and SIGTERM
). Despite closing the transport and HTTP server, active connections or internal resources remain open, preventing clean process exit. Improving transport.close()
to fully clean resources on signal-triggered shutdown would greatly improve usability and developer experience.