Repository navigation
mcp: do not cache resources/read results of multi round-trip retries - #1371
Merged
guglielmo-san merged 3 commits intoOct 12, 2026
Merged
guglielmo-san merged 3 commits into
guglielmo-san merged 3 commits into
Conversation
ReadResource cached every result under its URI and looked every request up by URI alone, so the result of a retry carrying inputResponses was served on the next plain read, and a manual retry was answered with the cached interim result. Skip the cache for requests carrying input responses or request state, and do not store retried or input_required results. The caching specification forbids all three. Fixes modelcontextprotocol#1369
vbcherepanov
force-pushed
the
fix/readresource-mrtr-cache
branch
from
October 12, 2026 06:20
98ebe54 to
4ebf5f4
Compare
Comment on lines
104
to
106
| if reqMap == nil && !mrtrResult.NeedsInput() { | ||
| return res, nil | ||
| } |
Contributor
There was a problem hiding this comment.
Suggested change
| if reqMap == nil && !mrtrResult.NeedsInput() { | |
| if r, ok := res.(retriedResult); ok && retries > 1 { | |
| r.markRetried() | |
| } | |
| return res, nil | |
| } |
Contributor
Author
|
Applied in 8aa288c. I kept the |
guglielmo-san
approved these changes
Oct 12, 2026
Contributor
|
@vbcherepanov thank you for the contribution! |
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.
ClientSession.ReadResourcecached every successful result under its URI and looked every request up by URI alone. The multi round-trip middleware runs insidehandleSend, so the result of a retry carryinginputResponsesandrequestStatewas cached and served on the next plain read, which bypassed the elicitation that gated the resource. With the middleware disabled, a caller's manual retry was answered from the cache with the interiminput_requiredresult of the first read and never reached the server.This change keeps multi round-trip traffic out of the cache in both directions:
InputResponsesorRequestStateis neither served from the cache nor stored.ReadResourceResultit obtained by retrying, through a small unexportedretriedResultinterface, andReadResourcedoes not store such a result.input_requiredresult is not stored.Results that needed no input are cached as before. There is no change to the exported API or to the wire format; the marker is an unexported field.
The specification says results of retries "MUST NOT be cached, as they depend on inputs that are not part of the cache key", that a cached response must not be served "for a request whose method or parameters differ from the request that produced it", and that interim results "are not cacheable" (2026-07-28, Caching).
Fixes #1369
Tested with
go test ./... -raceand the new tests at-race -count=50.TestMultiRoundTrip_ReadResource_RetryResultNotCachedcovers the automatic retry and includes a positive control for a plain cached resource.TestMultiRoundTrip_ReadResource_ManualRetryBypassesCachecovers the manual retry loop. Both fail on main and pass with this change.