Propagate backend resources/prompts list_changed in vMCP - #5971
Merged
Conversation
JAORMX
requested review from
ChrisJBurns,
amirejaz,
jerm-dro,
jhrozek,
rdimitrov and
tgrunnagle
as code owners
July 24, 2026 14:07
#5965 propagated backend list_changed to clients for tools only. Resources and prompts were deferred: the backend connector dropped their list_changed notifications and vMCP advertised resources.listChanged=false (and never advertised the prompts capability at all, a spec-conformance defect since it served prompts per session). Extend the existing #5965 machinery — no new coordinator — to resources and prompts: dispatch their list_changed notifications, add KindResources/KindPrompts, run one coalescing resync worker per (session, kind), re-derive and REPLACE the session's advertised resources, resource templates, and prompts, and flip WithResourceCapabilities(true, true) + WithPromptCapabilities(true). The per-session go-sdk server then auto-emits list_changed downstream. Additions propagate; removals do not, because mcpcompat's per-session resource/template/prompt sync is add-only (tracked in stacklok/toolhive-core#184). Advertising listChanged stays honest — notifications are still emitted on change. Closes #5969 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MRh394VZgnqbYjJwjrcJWm
JAORMX
force-pushed
the
resources-prompts-list-changed-5969
branch
from
July 24, 2026 14:09
3209eb3 to
5264c7e
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5971 +/- ##
==========================================
+ Coverage 71.88% 71.94% +0.06%
==========================================
Files 715 715
Lines 73501 73571 +70
==========================================
+ Hits 52835 52933 +98
+ Misses 16883 16839 -44
- Partials 3783 3799 +16 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
rdimitrov
approved these changes
Jul 24, 2026
1 task
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.
Summary
#5965 propagated backend
list_changedto vMCP clients for tools only. Resources and prompts were explicitly deferred: the backend connector dropped theirlist_changednotifications, vMCP advertisedresources.listChanged=false, and it never advertised thepromptscapability at all — a spec-conformance defect, since MCP 2025-11-25 says "Servers that support prompts MUST declare thepromptscapability during initialization" and vMCP already serves prompts per session.This extends the existing #5965 machinery (no new coordinator) to resources and prompts:
notifications/resources/list_changedandnotifications/prompts/list_changed(addKindResources/KindPrompts); resource-template changes ride the resources method (there is no separate templates notification in 2025-11-25).(session, kind)— reusing Consume backend list_changed in vMCP and propagate to clients #5965'slistChangedResyncWorkerverbatim — so a tools change never triggers a resources/prompts re-apply (and vice-versa).SetSessionResources/SetSessionResourceTemplates/SetSessionPrompts). The per-session go-sdk server then auto-emits the downstreamlist_changed.WithResourceCapabilities(true, true)and addWithPromptCapabilities(true).Closes #5969
Type of change
Test plan
task test)task lint-fix)task lint-fix0 issues;go build/go vetclean;go test -raceacross./pkg/vmcp/...all green. Coverage added:ListResources+ListResourceTemplates, never tools/prompts); REPLACE-not-merge (a pre-seeded removed entry is dropped from the overlay); fail-loudly type-assert branches for resources/templates/prompts; auth-context reconstruction (identity + forwarded header) asserted for all three kinds.list_changedfire the sink with the right kind; end-to-end resync so a clientresources/list/resources/templates/list/prompts/listreflects added items, with explicit before-snapshots.resources.listChanged/prompts.listChanged/promptspresent +resources.subscriberetained; an add-only guard pins that a removed resource/prompt currently still appears (fails loudly when toolhive-core#184 lands).Does this introduce a user-facing change?
Yes: vMCP now propagates backend resources and prompts
list_changedto clients (added items appear on the next*/listwithout reconnecting), advertisesresources.listChanged=true, and — newly — advertises thepromptscapability at initialize (fixing a spec MUST that previously hid vMCP's prompts from clients gating oncapabilities.prompts).Special notes for reviewers
Reviewed by a 4-axis Opus panel (MCP-correctness, concurrency+quality, security, tests): security APPROVE, the rest APPROVE-WITH-NITS (all nits addressed).
Known limitation (tracked): stacklok/toolhive-core#184. mcpcompat's per-session sync for resources/resource templates/prompts is add-only (unlike tools, which reconciles removals via
RemoveTools). So additions propagate but removals do not — a backend-removed resource/prompt lingers in the advertised list until the session re-initializes. AdvertisinglistChanged: trueremains honest (a notification is emitted on change;listChangedpromises notification, not list minimization). Read-time access is unaffected — the read path re-derives admission per call, so a removed/deadmitted resource is denied at read time regardless of the stale list. Documented at theresyncSessionResources/resyncSessionPromptsapply paths; the add-only guard test will flip to assert removal once #184 lands.🤖 Generated with Claude Code
https://claude.ai/code/session_01MRh394VZgnqbYjJwjrcJWm