Repository navigation
Conversation
🦋 Changeset detectedLatest commit: 15e9641 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: |
|
Read the diff against One edge the new Discarding the read is probably the safer behaviour, since the entry may belong to the old connection's server identity. If it is intended, a test with a parked Is the discard-on-reconnect result deliberate? |
|
@arhancanli Thanks for catching this. The original revision did not explicitly document or test the reconnect case. I agree that a lookup started on an old connection should be discarded after reset, even when a user-supplied store retains its entries; fresh reads can still reuse the retained data. Adding the requested tests exposed another edge: if a fresh read recreates the same key at generation 0 before the old The 8 new cases cover private/public probes, reconnecting to the same or a different server identity, and a fresh same-key read before releasing the parked one. Four fail on the previous PR revision; all 8 pass with this change. They also verify that fresh reads can use the retained store. I have left Validation: 67 cache tests; 44 client test files / 1,083 tests; 23 integration files / 444 tests; client typecheck and lint all pass. The PR description and changeset now state the reset behavior explicitly. |
|
Thanks for the detailed follow-up. I read the new diff: capturing On leaving |
|
@arhancanli Tracked separately in #3075 now. Thanks for flagging it. I reproduced the coordinator behavior on both pinned main and this PR head in all 8 combinations of private/public scope, same/different server identity, and with/without a fresh write before the old response reaches I agree a connection-generation guard is the right direction. Its snapshot needs to be taken before the asynchronous fetch and carried through to |
An asynchronous
ResponseCacheStore.get()can return a snapshot after the SDK has processed a change notification and deleted that entry.Client.listTools()then returns the old catalogue without refetching. The same lookup feeds resource reads and the derived tool-definition/output-validator indexes.Motivation and Context
Capture the existing per-key eviction generation before probing the store and recheck it after each awaited lookup. If invalidation intervened, treat the result as a cache miss. Unrelated keys retain their cache hits. A connection-generation check also discards reads pending across
resetForReconnect(), even when a new read recreates the same key at generation 0. A retained user-supplied store remains available to fresh reads. This addresses pending reads; asynchronous store mutation ordering is the separate concern in #2688.How Has This Been Tested?
Deterministic tests park a cache read, change the scripted server catalogue, deliver
notifications/tools/list_changed, then release the old snapshot. Both private and shared-public cache paths are exercised throughClient.listTools(). Additional cases cover per-URI invalidation, derived tool metadata and unrelated-key controls. No sleeps are used.On macOS, Node 22.23.3, pnpm 10.26.1:
lint:all.protocol:timeout:max-total [sse 2026-07-28]. The same failure reproduces with the original cache source when running the complete protocol test file, matching [v2] e2eprotocol:timeout:max-totalis flaky over SSE: fake timers advance before the request reaches the server #3045. The isolated max-total cases pass. Full E2E is not claimed green.Breaking Changes
None. The public API and store interface are unchanged. Includes a client patch changeset.
Types of changes
AI assistance was used for investigation, implementation and tests.