Skip to content

fix(mcp): add TTL-based session cleanup to prevent memory leak#194

Open
Satvik77777 wants to merge 3 commits into
accordproject:mainfrom
Satvik77777:fix/mcp-session-cleanup
Open

fix(mcp): add TTL-based session cleanup to prevent memory leak#194
Satvik77777 wants to merge 3 commits into
accordproject:mainfrom
Satvik77777:fix/mcp-session-cleanup

Conversation

@Satvik77777
Copy link
Copy Markdown
Contributor

Summary

The global transports map in mcp.ts had no cleanup
mechanism. Sessions were only removed when
transport.onclose fired correctly. Unclean client
disconnects (network drops, crashes, timeouts) left
transports in the map forever, causing unbounded
memory growth that crashes the server in production.

What this PR does

New cleanup mechanism

  • sessionLastActivity map tracks last request
    timestamp per session
  • setInterval runs every 5 minutes removing sessions
    idle for 30+ minutes
  • interval.unref() prevents blocking process exit

Activity tracking

  • lastActivity updated on every incoming request
    for existing sessions
  • lastActivity set on onsessioninitialized callback

Cleanup on disconnect

  • sessionLastActivity cleaned up on transport.onclose
  • sessionLastActivity cleaned up on SSE res.on("close")
  • structured console.error logging for cleanup events

Tests (3 new, 14 total passing)

  • tracks session activity on initialization
  • cleanup interval registered with unref
  • session removed from both maps on close

References

Author Checklist

  • DCO sign-off provided
  • Memory leak fix
  • Tests added and passing (14/14)
  • TypeScript compilation verified

Satvik77777 added 3 commits June 5, 2026 11:07
Resolves test coverage gap for the new MCP handler.
- Extracted getServer() for testability.
- Wrote tests for HTTP boundary error cases (400 responses).
- Wrote internal tests using InMemoryTransport to verify getTemplate, getAgreement, and trigger-agreement tools directly without battling strict StreamableHTTPServerTransport payload requirements.
- Fixed a bug where mcp-session-id was checked on incoming requests but not attached to the outgoing initialize response header.

Signed-off-by: Satvik77777 <satvikaini02@gmail.com>
- locks in the session header bug fix against future regression
- per review feedback from @JayDS22

Signed-off-by: Satvik77777 <satvikaini02@gmail.com>
- add sessionLastActivity map tracking last request timestamp per session
- add setInterval cleanup every 5 minutes removing sessions idle for 30+ minutes
- call .unref() on interval to prevent blocking process exit
- update lastActivity on every incoming request for existing sessions
- clean up sessionLastActivity on transport.onclose and SSE disconnect
- add structured logging for session cleanup events
- closes accordproject#193

Signed-off-by: Satvik77777 <satvikaini02@gmail.com>
@Satvik77777
Copy link
Copy Markdown
Contributor Author

Satvik77777 commented Jun 7, 2026

Hi @niallroche @mttrbrts — this PR fixes a memory
leak where unclean MCP client disconnects left
sessions in the transports map forever. Added
TTL-based cleanup running every 5 minutes with
30 minute idle timeout. 14/14 tests passing,
DCO signed. Directly relevant to @JayDS22 's GSoC
work on MCP hardening

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(mcp): transports map grows indefinitely — memory leak on unclean client disconnect

1 participant