Skip to content

vMCP backend revision cache has no success/TTL re-probe (stale on stateless redeploy) #5992

Description

@JAORMX

Part of #5743 / follow-up to the go-sdk v1.7 / MCP 2026-07-28 adoption (#5754). Surfaced by the Opus review panel.

Context

httpBackendClient caches each backend's negotiated MCP revision (probeRevision → setRevision). The cache self-corrects only on error (dispatch → isRevisionMismatch → reclassify), not on success and with no TTL.

The gap

If a backend is first probed Legacy (2025-11-25, stateful) and is later redeployed stateless/Modern (2026-07-28), the cache stays pinned Legacy indefinitely:

  • Wire behavior stays correct — the go-sdk v1.7 client's Connect is Modern-first and negotiates Modern transparently even on vMCP's "Legacy" code path (via server/discover), so calls still hit the right protocol. This is why it's not a correctness bug.
  • But CachedRevision (which feeds CRD status / telemetry read-models) reports Legacy forever — an operator-facing status inaccuracy — and every call pays the heavier per-call legacy initialize + discover + subscribe + Close handshake instead of using the lighter stateless path.

The reverse and dangerous direction — a Modern-cached backend redeployed stateful/Legacy — is self-corrected: discover now lacks 2026-07-28 → errModernNegotiatedDown → isRevisionMismatch (Modern arm) → reclassify → Legacy. So only the Legacy→Modern transition is left stale.

Proposed fix

Add a TTL-based re-probe (or success-path re-validation) to the revision cache so a redeployed backend's revision is refreshed, correcting both the telemetry/status inaccuracy and the per-call handshake overhead. The code already carries a NOTE deferring this.

Also worth a test

The "stale Legacy cache is harmless" property is currently pinned only for ListCapabilities (forwarding=false). The forwarding CallTool path (WithContinuousListening standalone GET stream) against a real stateless Modern backend is untested — low risk, but the harmlessness claim is asserted more broadly than it's covered.

Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions