MCP: advertise SEP-2549 cache hints for the static reference resources
- Dominant language
- PHP
- Stars
- 3.4k
- Forks
- 1.2k
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 433
Description
Part of #19965. Blocked by the protocol era adoption.
## Problem
The reference resources are effectively static for a given deployment: `shopware://entities`, `shopware://state-machines`, `shopware://business-events`, `shopware://flow-actions`, `shopware://sales-channels`, `shopware://currencies`, `shopware://languages`. Agents re-read them constantly, and each read is a full request through authentication, rate limiting and the allowlist.
The backlog in `src/Core/Framework/Mcp/AGENTS.md` currently attacks this from the rate-limiter side only, which throttles rather than avoids the work.
## What changed upstream
`mcp/sdk` 0.8 adds `Wire\CachePolicy` (`Builder::setCachePolicy()`) for SEP-2549 caching hints, defaulting to `ttlMs: 0, cacheScope: private`, with a `ReadResourceResult` able to override per response. The bundle exposes it as `servers..cache` with per-method overrides such as `tools/list` and `resources/read`.
The spec requires the hints on `server/discover`, the list methods and `resources/read`.
## Scope
- Decide a default TTL and scope, then per-method overrides.
- Be deliberate about `public` versus `private`: `tools/list` varies per integration because the allowlist and enabled toolsets filter it, so it must stay `private`. The static reference resources are the candidates for a longer TTL.
- Check the interaction with `McpRateLimiter`: hints that actually reduce traffic may make the current limits look different.
## Blocked by
The cache hints are put on answers by the modern-era leg.
---
## Validated against mcp/sdk 0.8.1 + symfony/mcp-bundle 0.13.0
Checked 2026-09-16 against the [#19963](https://github.com/shopware/shopware/pull/19963) branch, which vendors `mcp/sdk` v0.8.1 and `symfony/mcp-bundle` v0.13.0. Both are the latest published releases, so nothing newer is pending. Line numbers refer to that branch.
**Holds.** `Wire\CachePolicy` (`Server/Wire/CachePolicy.php:31`), `Builder::setCachePolicy()` (`Server/Builder.php:353`), and the bundle's `cache` node (`vendor/symfony/mcp-bundle/config/options.php:160`) all exist as described. The `AGENTS.md` claim is accurate too: the backlog attacks this from the rate limiter side at `src/Core/Framework/Mcp/AGENTS.md:194-198`.
**"Blocked by" is correct.** `CachePolicy` is consumed only by `Rev2026Codec`, which is constructed only by `StatelessProtocol` (`Server/Stateless/StatelessProtocol.php:110`). On the handshake era the policy never reaches the wire.
**Cross reference #20504.** Its follow-ups name a non-zero `ttlMs` on `tools/list` as the spec's own mitigation for clients that never re-list, which is the failure this epic otherwise addresses through notifications. Worth scoping the two together.
One clarification while doing so: this issue says `tools/list` "must stay `private`", and that stays true. `cacheScope` and `ttlMs` are independent, so `private` plus a non-zero TTL is a valid and probably the wanted combination. Saying so explicitly avoids the next reader concluding that a per-integration surface cannot be cached at all.
Contributor guide
Research direction
Start with the backlog guidance in src/Core/Framework/Mcp/AGENTS.md and the validated mcp/sdk and symfony/mcp-bundle versions. Read CachePolicy, Builder::setCachePolicy(), Rev2026Codec, and StatelessProtocol, then compare the cache behavior with McpRateLimiter and follow-up #20504. Done means agreed defaults and per-method cache hints are applied only to the modern-era responses, with tools/list remaining private.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, symfony
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100