LATEST_PROTOCOL_VERSION misdescribes what the shim requests, and Initialize silently discards the caller's version

Aperta
#193 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
48/100
Tipo di issue
Documentazione
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
go
Ambito
api, backend

Direzione di ricerca

Inizia da mcpcompat/mcp/jsonrpc.go e client.Initialize, quindi esamina i tre punti di chiamata in produzione in pkg/transport/bridge.go, pkg/vmcp/client/client.go e pkg/vmcp/session/internal/backend/mcp_session.go. Esamina TestListCapabilities_MisCachedLegacy_SelfHealsViaSDKNegotiation e la limitazione collegata di go-sdk prima di decidere come documentare LATEST_PROTOCOL_VERSION. Il lavoro è completato quando il comportamento di Initialize e la semantica della costante sono espliciti, la validazione è coperta e il comportamento attuale della negoziazione non viene modificato.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

needs-triage

Rescoped. This issue originally bundled two conformance findings that turned out to be upstream-only; those are now go-sdk#1112 and go-sdk#1113. See the correction comment for why neither was fixable here. What remains below is shim-side.

The defect

mcpcompat exports a constant that no longer describes what the shim does:

// mcpcompat/mcp/jsonrpc.go:15
const LATEST_PROTOCOL_VERSION = "2025-11-25"

Meanwhile go-sdk's latestProtocolVersion is 2026-07-28, and client.Initialize calls Connect(ctx, tr, nil) — so the shim always requests 2026-07-28 on the wire, whatever the caller asked for. request.Params.ProtocolVersion is read nowhere in Initialize.

The combination is what makes this worth fixing: a consumer reads LATEST_PROTOCOL_VERSION, reasonably concludes the shim speaks 2025-11-25, passes it to Initialize, and gets 2026-07-28 requested — silently.

That is not hypothetical. Every ToolHive production initialize does exactly this:

  • pkg/transport/bridge.go:197
  • pkg/vmcp/client/client.go:852
  • pkg/vmcp/session/internal/backend/mcp_session.go:553

Important: do not "fix" this by honouring the request

The substitution is load-bearing for ToolHive today. Because the wire request is 2026-07-28, a Modern-capable backend answers initialize with 2026-07-28, which is precisely how ToolHive's legacyInit detects a mis-cached backend and flips its revision cache Legacy→Modern (stacklok/toolhive#5997, pinned by TestListCapabilities_MisCachedLegacy_SelfHealsViaSDKNegotiation).

Honouring a requested 2025-11-25 would make that backend negotiate 2025-11-25, the self-heal would never fire, and vMCP's Legacy→Modern correction would silently regress. Rejecting an unhonourable request would break all three production call sites immediately, since they all pass a version that cannot be honoured.

Honouring is also not currently possible: ClientSessionOptions.protocolVersion is unexported upstream (go-sdk#1113).

Proposed work — documentation and validation only, no behaviour change

  • Document client.Initialize: state plainly that Params.ProtocolVersion does not influence the wire version, that go-sdk requests its own latest and negotiates down, and link go-sdk#1113. This removes the silence, which is the actual harm.
  • Fix or document LATEST_PROTOCOL_VERSION. Two options, and this is the decision worth discussing:
    • Document it as an mcp-go compatibility constant that reflects neither the revision the shim requests nor the newest it supports. Zero risk.
    • Change it to 2026-07-28. Behaviourally a no-op for Initialize (the value is discarded anyway), but it is exported and consumers may compare against it, so it needs a consumer sweep first. toolhive uses it in at least the three production sites above plus several tests.
  • Validate genuinely invalid input: a requested version that go-sdk does not recognise at all is unambiguously a caller bug and can return an error, with no effect on any current caller.

Non-goal

Making the shim honour arbitrary requested versions. That is blocked on go-sdk#1113 and, per the above, would need a coordinated change in toolhive because the current behaviour is depended upon.

Generated with Claude Code

Lingua principale
Go
Stelle
2
Fork
6
Merge medio
23h 44m
PR unite (30g)
133

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di stacklok/toolhive-core

Tutte le issue di stacklok/toolhive-core

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.