fix(server): track the current registry key when a handle is renamed - #2761
Open
krishnendu-2003 wants to merge 1 commit into
Open
fix(server): track the current registry key when a handle is renamed#2761krishnendu-2003 wants to merge 1 commit into
krishnendu-2003 wants to merge 1 commit into
Conversation
The update closure for prompts, resources and resource templates captured the registration key and never reassigned it, so remove() deleted the key the entry had already vacated and left the live entry listed and callable. RegisteredTool already tracked its current key; these three now do too. Fixes modelcontextprotocol#2723
🦋 Changeset detectedLatest commit: 34f91cb The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/core
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
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.
This fixes an issue where renaming a registered prompt, resource, or resource template would break
remove().When a handle is renamed, the captured registry key is now updated as well. This means a later
remove()deletes the entry from the key it actually lives under.Fixes #2723.
Motivation and Context
Previously, calling
remove()after renaming a handle withupdate()would silently do nothing.The problem was that the
updateclosure kept referencing the original registration key. After a rename, the entry had already moved to a new key, butremove()was still doing:delete this._registeredX[key]using the old key.
As a result, the renamed entry stayed registered, remained callable, and still appeared in list responses. A
list_changednotification was also emitted even though nothing had actually been removed.The stale key caused another issue as well. The
updates.name !== namecheck could incorrectly prevent a handle from being renamed back to its original name.RegisteredToolalready handles this correctly by keeping track of its current registry key in the toolupdateclosure inmcp.ts.This change applies the same approach to:
There is no new abstraction and no public API change.
How Has This Been Tested?
Added:
test/integration/test/issues/test2723.remove-after-rename.test.tsThe test covers four cases:
remove()remove()remove()remove()The tests verify the behaviour through the protocol using:
prompts/listresources/listresources/templates/listrather than inspecting internal registry state.
All four cases fail on
mainand pass with this change.The existing tests only covered updates to non-key fields, which is why this behaviour was not caught earlier.
Full local test results:
packages/server: 482 passingtest/integration: 374 passingtest/e2e: 2639 passingtypecheck:all: passinglint:all: passingbuild:all: passingI also see two local failures that appear to be environmental and reproduce on an unmodified
mainbranch:protocol:timeout:max-total [sse]Appears related to SSE and fake-timer scheduling on macOS.
cloudflareWorkersAppears related to Wrangler cold start behaviour because
workerd's build script is skipped by pnpm locally.Neither test suite exercises the code changed in this PR.
Breaking Changes
There is no API change.
The only behavioural change is the bug fix itself: after a handle is renamed, calling
remove()now actually removes it.Previously, the renamed entry incorrectly remained registered. Any code relying on that behaviour was relying on the bug.
One related issue is intentionally left out of scope: renaming a handle onto an already occupied key currently has no duplicate-key protection, so the existing entry can be displaced.
I can open a separate issue for that if needed.
v1.xalso has the same problem in all four registration closures, including tools. TheRegisteredToolfix currently only exists onmain.I can open a backport PR for
v1.xonce this change lands.Types of changes
Checklist