-
Notifications
You must be signed in to change notification settings - Fork 107
Add SSE heartbeat mechanism to prevent MCP disconnections #286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
a2ca0f7 to
920e337
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements an SSE heartbeat mechanism to prevent MCP connection timeouts during periods of inactivity. A heartbeat message (SSE comment) is sent every 30 seconds to keep connections alive.
Key Changes:
- Added heartbeat interval mechanism that sends ": heartbeat\n\n" messages every 30 seconds on SSE connections
- Enhanced cleanup logic to properly clear heartbeat intervals when connections close or error
- Added error handlers for both SSE and Streamable HTTP endpoints to ensure proper resource cleanup
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/services/mcpService.ts | Implements heartbeat mechanism with 30-second intervals for /sse endpoint, adds cleanup logic for intervals, and adds error event handlers for both /sse and /mcp endpoints |
| test/mcp-http-e2e.test.ts | Adds E2E test that verifies heartbeat messages are sent by directly connecting to the SSE endpoint and waiting for the heartbeat comment |
| src/services/mcpService.test.ts | Adds unit tests for service registration and cleanup, verifying that heartbeat intervals are properly tracked and cleaned up |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // Check that routes are registered (printRoutes uses a tree format) | ||
| const routes = server.printRoutes(); | ||
| expect(routes).toContain("essages"); |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assertion checks for "essages" instead of the full route path "/messages" or "messages". While this may work if printRoutes() outputs routes in a tree format, it's fragile and unclear. Consider using a more specific assertion that matches the full route path, or add a comment explaining why a partial match is necessary.
| expect(routes).toContain("essages"); | |
| expect(routes).toContain("/messages"); |
- Remove unused connectionClosed variable in E2E test - Remove misleading unit test that didn't actually verify heartbeat - Add clarifying comments for Fastify radix tree route assertions - Improve route assertions to be more specific
|
Addressed the review comments in commit 4c976f3:
All tests pass (5 unit tests, 3 E2E tests). |
|
🎉 This PR is included in version 1.32.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Implement a Server-Sent Events (SSE) heartbeat mechanism to keep the MCP connection alive and prevent disconnections after a period of inactivity. This change includes corresponding tests to verify the functionality of the heartbeat feature.
Fixes #285