Build1 distinct publisher3 min readUpdated
The 2026-07-28 MCP spec borrowed HTTP's cache vocabulary for tool catalogs. One Rust lab shows why checking that the fields exist proves nothing about whether the next call is skippable.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The 2026-07-28 MCP spec added `ttlMs` and `cacheScope` stamps to `tools/list` under SEP-2549, modeled on HTTP `Cache-Control` [1]. A write-up from the mcp-better project argues that those fields are a server's statement about later reuse, not evidence of it, and that a client confirming the fields are present and well-formed has proved only that the server said something [2][3].
The mechanism is dull and therefore likely. A server can emit `ttlMs: 60000` with `cacheScope: Public` and change its catalog on the very next call; the stamp remains syntactically valid and a presence-only probe still passes [4]. Sixty thousand milliseconds is a minute of a client happily calling tools that the server no longer lists [5]. The post's framing of the official pitch is that clients now know exactly how long `tools/list` is fresh [6]; its counter is that HTTP taught this lesson already, since `max-age=60` was never proof that the next GET returns the same bytes, and MCP imported the words without importing a test [7].
The interesting part is the author's own bug. Their `contrast-smoke` example paired a good server with a labeled liar, `mcp-worse`, and gated on one boolean: unstamped OR wrong catalog order [8]. Then `mcp-better` grew a third tool, `confirm_echo`, so the name mismatch became permanently true and the stamp half of the check stopped carrying weight [9]. Had `mcp-worse` later gained stamps, the example would still have printed OK, failing on contents alone, with the negative case for `ttlMs` silently gone [10]. The guard meant to keep the companion a reliable liar only fired when every clause went green at once, which makes partial decay invisible [11]. The author credits a commenter with naming it, and states the rule as one smallest lie per claim: a liar that fails for two reasons is weaker evidence than two liars that each fail for one [12][13].
The current tree splits the predicate into `is_unstamped` and `wrong_names`, both of which must stay true on the companion, and exits non-zero naming the clause that went green [14]. The published `v0.5.0` tag still ships the OR [15]. Captured output from 2026-08-19 shows the good server at `ttl=Some(60000) scope=Some(Public)` and the companion at `ttl=None scope=None` [16].
Even fixed, the author is explicit that this is not a cache test. Order is a property of the list the probe is holding and can be inspected; `ttlMs` and `cacheScope` describe how that list may be reused later [17]. Falsifying a TTL claim needs an observation pair that straddles a change, and since the lab's catalog is compiled in, the claim cannot be violated yet: declared, not falsified [18]. The related `order-restart-smoke` check compares `ttl_a == ttl_b` across two processes, which tests that the number is restart-stable, not that the caching behavior it describes holds [19].
The operator reading is short. If you are building an MCP client, invalidation has to be yours, because the stamp is the server's assertion about its own future. Watch for the moment catalogs stop being compiled in and start being generated: the post argues `ttlMs` is then the first stamp with room to lie and the clause with the least behind it [20].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The 2026-07-28 MCP spec added list-cache stamps (SEP-2549), putting ttlMs and cacheScope on tools/list, modeled on HTTP Cache-Control.
The post argues a stamp on tools/list is a claim about later reuse, and that presence is not proof the next call is cacheable.
Confirming that ttlMs and cacheScope exist and look well-formed proves the server made a claim; it does not prove a client would be right to skip the next tools/list.
A server can print ttlMs: 60000, cacheScope: Public and change its catalog on the next call; the stamp is still well-formed and a probe that only checks presence will still pass.
The post characterises the official framing as some version of: clients know exactly how long tools/list is fresh.
The post argues HTTP already taught this, since Cache-Control: max-age=60 is a statement and not proof the next GET returns the same bytes, and that MCP imported the words but not a test.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Reproducible artefact, single self-published source
The technical core is unusually checkable for a blog post: two predicate implementations are quoted verbatim, clone/build/run commands are given, and a dated run output is reproduced, and the author explicitly bounds what was and was not falsified. But everything comes from one self-published item by the repo's own author; the spec claim (SEP-2549, 2026-07-28) has no independent corroboration in the cluster, and the central caching argument rests on reasoning plus a toy lab with a compiled-in catalog rather than on an observed TTL violation.
One author's lab; no third-party use shown
Adoption evidence is limited to a spec revision described by the source and one self-authored Rust repository with two demo binaries and one captured run. No third-party server, client, deployment, download figure or user of ttlMs/cacheScope appears anywhere in the cluster, and the released v0.5.0 tag does not even contain the improved check.
Deliberately deflationary framing
The piece under-claims relative to its evidence: it exists to argue that a stamp is not a receipt, retracts the strength of its own earlier harness, credits a reader comment for finding the flaw, and lists what the work is not (not a cache test, not a security scanner, not a rewrite). The one place it stretches is the forward-looking assertion that ttlMs will be the first stamp with room to lie once catalogs go dynamic, which remains untested.
Author promotes own repo and series
The source is self-published on dev.to by the maintainer of the repository under discussion, includes clone instructions for that repo, links to prior posts in the same series, and closes with an AAIF Ambassador identification framing the piece as MCP education. That creates a clear promotional incentive, partly offset by the fact that the post's substance is a public correction of the author's own tooling and an admission that the released tag is weaker.
Internally consistent but uncorroborated
Confidence in the reasoning about stamp semantics is fairly high because it is self-contained logic supported by quoted code and output, but confidence in the surrounding facts is low: one publisher, one author, no independent view of the spec or of the repository state, and two claims that are avowedly forecasts rather than observations.
build
The only way to prove a contract test can fail is to ship a server that lies1 distinct publisher
build
Rate limit your MCP servers, because a retrying agent turns one error into a billing incident1 distinct publisher
build
The MCP transport your search results teach has been deprecated since March1 distinct publisher
build
MCP 2026-07-28 drops the `result` wrapper, and your unit tests will not notice1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 20, 2026