-
Notifications
You must be signed in to change notification settings - Fork 3.3k
fix(mcp): harden notification system against race conditions #3168
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
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
- Guard concurrent connect() calls in connection manager with connectingServers Set - Suppress post-disconnect notification handler firing in MCP client - Clean up Redis event listeners in pub/sub dispose() - Add tests for all three hardening fixes (11 new tests)
Greptile OverviewGreptile SummaryThis PR hardens the MCP notification system against race conditions with three key fixes:
The PR also introduces comprehensive real-time notification infrastructure: a new Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant MCP as External MCP Server
participant Client as McpClient
participant ConnMgr as ConnectionManager
participant PubSub as Redis PubSub
participant Service as McpService
participant SSE as SSE Endpoint
participant Browser as Browser/UI
Note over ConnMgr,Client: Connection Setup (with race protection)
Service->>ConnMgr: connect(config, userId, workspaceId)
ConnMgr->>ConnMgr: Check connectingServers Set
alt Already connecting or connected
ConnMgr-->>Service: return existing state
else Not connecting
ConnMgr->>ConnMgr: Add to connectingServers Set
ConnMgr->>Client: new McpClient(onToolsChanged callback)
Client->>MCP: connect()
MCP-->>Client: connection established
Client->>Client: Register notification handler
ConnMgr->>ConnMgr: Remove from connectingServers
ConnMgr-->>Service: supportsListChanged: true
end
Note over Browser,SSE: Browser subscribes to updates
Browser->>SSE: EventSource connection
SSE->>ConnMgr: subscribe(listener)
SSE->>PubSub: onToolsChanged(listener)
Note over MCP,Browser: Tool change notification flow
MCP->>Client: notifications/tools/list_changed
Client->>Client: Check if (!this.isConnected) return
Client->>ConnMgr: onToolsChanged(serverId)
ConnMgr->>PubSub: publishToolsChanged(event)
PubSub->>ConnMgr: broadcasts to all processes
ConnMgr->>Service: cache invalidation
ConnMgr->>SSE: forward event to listener
SSE->>Browser: SSE event: tools_changed
Browser->>Browser: Invalidate React Query cache
Note over ConnMgr,PubSub: Cleanup on dispose
ConnMgr->>PubSub: dispose()
PubSub->>PubSub: removeAllListeners()
PubSub->>PubSub: quit() clients
ConnMgr->>ConnMgr: Clear connectingServers Set
|
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.
10 files reviewed, 3 comments
Additional Comments (1)
Deploy errors are now rendered in a |
|
@greptile |
|
@cursor review |
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.
6 files reviewed, no comments
|
@cursor review |
Bugbot couldn't runSomething went wrong. Try again by commenting "Cursor review" or "bugbot run", or contact support (requestId: serverGenReqId_9070a327-63c1-43eb-8631-c031c300a272). |
|
@cursor review |
|
@greptile |
|
@cursor review |
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.
8 files reviewed, no comments
|
@cursor review |
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.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Summary
connect()calls in connection manager with aconnectingServersSet to prevent duplicate client creationif (!this.isConnected) returnguard in MCP client notification handler to suppress post-disconnect callbacksremoveAllListeners()on Redis pub/sub clients beforequit()indispose()to prevent listener accumulationconnectingServersindispose()for consistency with other collection cleanupType of Change
Testing
tsc --noEmitcleanChecklist