Repository navigation
fix(mcp): emit SEP-2549 cache hints on tools/list for 2026-07-28 peers - #1187
Merged
Merged
Conversation
Clients that negotiate MCP protocol 2026-07-28 require `ttlMs` and `cacheScope` on list results (SEP-2549). The hand-written `list_tools` handler left both unset, so strict clients rejected the tools/list response outright and the server connected with no tools at all. Emit immediately-stale public hints (`ttlMs: 0`, `cacheScope: public`) when the negotiated version is 2026-07-28 or newer — preserving the pre-SEP-2549 no-caching behavior — and keep the old wire shape for legacy peers, mirroring what rmcp's `#[tool_handler]` macro does since rmcp 3.1.1. Also bumps rmcp 3.0.1 -> 3.1.2. Covered by an in-process client/server test pair asserting the hints are present for a 2026-07-28 peer and absent for a legacy one.
Contributor
SCIP oracle — resolution reportHeuristic→compiler edge resolution per corpus. Δ compares resolved-after to the
resolved = |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
|
| Project | rag-rat |
| Branch | chore/rmcp-bump |
| Testbed | ubuntu-latest |
⚠️ WARNING: No Threshold found!Without a Threshold, no Alerts will ever be generated.
- Estimated Cycles (cycles)
- Instructions (instructions)
- RAM Hits (hits)
- Total read+write (reads/writes)
- LL Hits (hits)
- L1 Hits (hits)
Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the--ci-only-thresholdsflag.
Click to view all benchmark results
| Benchmark | Estimated Cycles | cycles x 1e6 | Instructions | instructions x 1e6 | L1 Hits | hits x 1e6 | LL Hits | hits x 1e6 | RAM Hits | hits x 1e3 | Total read+write | reads/writes x 1e6 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| rag_pipeline::pipeline::index cargo_resolver:resolver_config() | 📈 view plot | 1,952.53 x 1e6 | 📈 view plot | 1,233.57 x 1e6 | 📈 view plot | 1,714.18 x 1e6 | 📈 view plot | 38.64 x 1e6 | 📈 view plot | 1,290.64 x 1e3 | 📈 view plot | 1,754.11 x 1e6 |
| rag_pipeline::pipeline::query_cold cargo_resolver:resolver_built_config() | 📈 view plot | 340.60 x 1e6 | 📈 view plot | 226.81 x 1e6 | 📈 view plot | 323.73 x 1e6 | 📈 view plot | 3.15 x 1e6 | 📈 view plot | 31.66 x 1e3 | 📈 view plot | 326.92 x 1e6 |
| rag_pipeline::pipeline::query_warm cargo_resolver:resolver_index() | 📈 view plot | 314.11 x 1e6 | 📈 view plot | 208.79 x 1e6 | 📈 view plot | 298.39 x 1e6 | 📈 view plot | 2.91 x 1e6 | 📈 view plot | 32.98 x 1e3 | 📈 view plot | 301.34 x 1e6 |
Contributor
|
| Project | rag-rat |
| Branch | chore/rmcp-bump |
| Testbed | ubuntu-latest |
Click to view all benchmark results
| Benchmark | Latency | Benchmark Result seconds (s) (Result Δ%) | Upper Boundary seconds (s) (Limit %) |
|---|---|---|---|
| index_time/full_rebuild_cargo | 📈 view plot 🚷 view threshold | 5.93 s(+6.23%)Baseline: 5.58 s | 6.32 s (93.83%) |
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.
Problem
Clients that negotiate MCP protocol version 2026-07-28 require
ttlMsandcacheScopeon list results (SEP-2549) and reject atools/listresponse without them:Because the rejection happens at
tools/list, the server connects with no tools at all — every session against a strict 2026-07-28 client is bricked.Fix
The hand-written
ServerHandler::list_toolsnow emits immediately-stale public cache hints (ttlMs: 0,cacheScope: "public") when the negotiated protocol version is 2026-07-28 or newer, and keeps the pre-SEP-2549 wire shape for legacy peers that may reject unknown fields. This mirrors what rmcp's#[tool_handler]macro does since 3.1.1 (modelcontextprotocol/rust-sdk#1120) — the macro fix doesn't reach hand-written handlers, so the gate is applied at our handler.ttlMs: 0deliberately opts out of client-side caching: the catalog is static per binary, not per server identity — hot-upgrade (SIGUSR1 exec) and version bumps can change it with no client-visible signal, and the only fetch it would save is one local stdio round trip per session. A real TTL should only land together withtools/listChangedwiring.Also bumps rmcp 3.0.1 → 3.1.2.
Verification
tools/listthrough a real in-process client/server pair (rmcpclientfeature as a dev-dependency, scoped out of the production feature set by resolver 3), asserting the hints are present for a 2026-07-28 peer and absent for a legacy peer; the positive test fails if the gate is reverted.rag-rat-mcpsuite green under nextest andcargo test; clippy--no-default-featuresand default-features legs clean under-D warnings; nightly rustfmt applied.