feat(client): accept a cached era verdict on ConnectOptions.prior (#2511)

This commit is contained in:
Felix Weinberger 2026-07-17 17:25:02 +01:00 • committed by GitHub
commit f60dff0674
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 523 additions and 86 deletions

View file

@ -109,7 +109,12 @@ The probe request itself already carries the per-request `_meta` envelope
the envelope to every outgoing request and notification. Tooling that classifies
traffic must not treat "saw an envelope" as "modern era negotiated": the legacy-fallback
path also begins with one enveloped probe. A gateway/worker fleet can skip the
probe entirely with `client.connect(transport, { prior: persistedDiscoverResult })`.
probe entirely with `client.connect(transport, { prior: { kind: 'modern', discover } })`
(wrapping a persisted `DiscoverResult`) — or, for a server known out-of-band to be
legacy, with `{ prior: { kind: 'legacy' } }`, which goes straight to `initialize`.
Freshness of a cached legacy verdict is the host's responsibility (a stale one succeeds
silently against an upgraded server); stop supplying it and the configured
mode decides again (an `'auto'` client re-probes).
### Server over HTTP: `createMcpHandler`

View file

@ -1756,11 +1756,18 @@ the named class from the explicit subpath
(`@modelcontextprotocol/{client,server}/validators/ajv` or `…/cf-worker`) — importing
from a subpath means the corresponding peer dep must be in your `package.json`.
### `Client.connect(transport, { prior })` — zero-round-trip connect
### `Client.connect(transport, { prior })` — connect from a cached era verdict
Probe once, persist `client.getDiscoverResult()` (`JSON.stringify`), and feed it to
every worker as `client.connect(transport, { prior })` — 2026-07-28+ only. New exported
type `ConnectOptions` (extends `RequestOptions` with `prior?: DiscoverResult`).
every worker as `client.connect(transport, { prior: { kind: 'modern', discover } })`.
New exported types
`ConnectOptions` (extends `RequestOptions` with `prior?: PriorDiscovery`)
and `PriorDiscovery` — a cached era verdict: the modern arm wraps a `DiscoverResult`
(zero round trips), the legacy arm (`{ kind: 'legacy' }`) skips the probe and runs the
plain `initialize` handshake for servers known to be pre-2026. Freshness is the
supplying host's responsibility — date cached legacy verdicts in your own storage and
stop supplying them past your policy horizon (a stale one succeeds silently against an
upgraded server).
### Serving the 2026-07-28 revision