Repository navigation
fix(core): fence runtime MCP tool reconciliation - #39898
Closed
kitlangton wants to merge 1 commit into
Closed
kitlangton wants to merge 1 commit into
kitlangton wants to merge 1 commit into
Conversation
Contributor
Author
|
Closing this implementation for now. The consistency gap and deterministic reproduction are tracked in #39902 so we can revisit the general runtime MCP contract separately. This was not the cause of the original voice tool failure. |
3 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Make runtime MCP lifecycle mutations read-your-writes consistent with the ToolRegistry and Code Mode catalog. After an MCP add, remove, connect, or disconnect request returns, the next session tool snapshot now reflects that mutation.
Before / After
Before:
MCP.addconnected the server, discovered its tools, publishedmcp.tools.changed, and returned.McpToolconsumed that event on an asynchronously forked stream, so an immediate session request could snapshot the previous direct-tool or Code Mode catalog while reconciliation was still in flight.After: runtime MCP handlers await an explicit
McpTool.reconcilefence after mutating MCP state. The fence serializes behind any event-driven reconciliation and returns only after the complete current MCP tool set has replaced the prior registry scope.How
packages/core/src/tool/mcp.tsexposes the existing serialized reconciliation effect as a Location-scoped service while retaining asynchronous reconciliation for server-originated tool-list updates.packages/server/src/handlers/mcp.tsawaits that service after runtime add, remove, connect, and disconnect operations.packages/core/test/mcp-tool-reconciliation.test.tsblocks event-driven reconciliation to prove publication can complete while a snapshot is stale, then verifies the explicit fence waits and makes the Code Mode path immediately visible.Scope
This does not make all event-bus subscribers synchronous and does not change server-originated MCP list-change behavior. The stronger guarantee applies at the runtime MCP HTTP lifecycle boundary.
Testing
bun typecheckinpackages/corebun run test test/mcp.test.ts test/mcp-tool-reconciliation.test.tsinpackages/core: 23 tests, 67 expectationsbun typecheckinpackages/serverbun run testinpackages/server: 16 tests, 39 expectationsFlow