Repository navigation
fix(mcp): emit the cache hints 2026-07-28 requires on tools/list - #685
Merged
Merged
Conversation
`ListToolsResult::with_all_items` leaves `ttlMs` and `cacheScope` unset, and rmcp only strips `resultType` for legacy peers — nothing fills these in. Protocol 2026-07-28 made both fields required on `tools/list` (SEP-2549 `CacheableResult`), so a strict client rejects the response before it reaches a tool call: the TypeScript SDK 2.0.0 client fails with `Invalid result for tools/list: expected number, received undefined` at `ttlMs`. `server/discover` succeeds first, which makes it read like a client bug until you look at the wire. rmcp 3.1.1 fixes this for servers built from `#[tool_handler]` (modelcontextprotocol/rust-sdk#1120). This server hand-writes `ServerHandler::list_tools`, so the macro fix does not reach it. The tool set is derived from the clap tree once in `EcpMcpServer::new` and never changes while the process lives, so the hint is public and any TTL up to the session length would be honest; 60s matches rmcp's own conformance server and keeps a session that outlives an `ecp` upgrade from calling a subcommand the new binary dropped. Peers older than 2026-07-28 predate both fields and keep the legacy wire shape, matching how the macro gates them. Alongside: `cargo update` (rkyv 0.8.18, rmcp 3.1.1, clap 4.6.6, blake3 1.8.6 and their transitive set), and `taiki-e/install-action` to v2.85.10 — tool-manifest updates only, cargo-nextest 0.9.143 among them.
clippy::items_after_test_module (-D warnings in CI) rejects any item declared after a `#[cfg(test)] mod`.
coseto6125
enabled auto-merge (squash)
August 7, 2026 18:53
Contributor
ecp impact cache (0 symbols) — internal, used by
|
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
ecp mcp servehand-writesServerHandler::list_tools, andListToolsResult::with_all_itemsleavesttlMs/cacheScopeunset. Protocol2026-07-28made both required ontools/list(SEP-2549CacheableResult),so a spec-strict client rejects the response before it ever reaches a tool call:
server/discoversucceeds first, which makes it read like a client bug until youlook at the wire. rmcp only strips
resultTypefor legacy peers — nothing fillsthese in.
rmcp 3.1.1 fixed this for servers generated from
#[tool_handler](rust-sdk#1120).
This server does not use the macro, so the upstream fix does not reach it — it is
the hand-written case the issue names as the workaround.
Why 60 s / public
The tool set is derived from the clap tree once in
EcpMcpServer::newand neverchanges while the process lives, so any TTL up to the session length would be
honest, and there is no per-user data in it. 60 s matches rmcp's own conformance
server and keeps a session that outlives an
ecpupgrade from calling asubcommand the new binary dropped. Peers older than
2026-07-28predate bothfields and keep the legacy wire shape, matching how the macro gates them.
Dependency refresh
cargo update— rkyv 0.8.18, rmcp 3.1.1, clap 4.6.6, blake3 1.8.6, bytecheck0.8.3, ptr_meta 0.3.2, rancor 0.1.3, zerocopy 0.8.56 and the rest of the tree.
rmcp = "3"→"3.1"— this change usesRequestContext::protocol_version()and the
ListToolsResultcache-hint builders, both 3.1.taiki-e/install-actionv2.85.8 → v2.85.10 — tool-manifest updates only(cargo-nextest 0.9.143 among them).
harden-runnerv2.20.1 andcodeql-actionv4.37.6 from chore(deps): bump the all-minor-patch group with 6 updates #684 are already thenewest releases. Neither changelog is actionable here: harden-runner's changes
are block-mode and AWS CodeBuild (these workflows run
egress-policy: audit),and codeql-action 4.37.6 only moves the default
config-filepath, which thisrepo does not set.
ccstays on 1.2.67 rather than 1.4.1:tree-sitter-sequel0.3.11 pinscc = "~1.2.1", so nothing in the tree can move past 1.2.x until that grammarrelaxes it.
Tests
server::testscover the wire shape directly — serializedttlMs/cacheScopepresent for
2026-07-28and for a version newer than any this build knows, andabsent for
2025-11-25/2025-06-18/2024-11-05and for an unnegotiatedpeer. Verified they fail without the fix (
ttlMscomes backNull).Local:
cargo fmt --all --checkandcargo clippy --workspace --all-targets --all-features -- -D warningsclean;ecp-core, ecp-mcp, ecp-cli (1281) and ecp-analyzer (2515) test suites all green.