Repository navigation
Conversation
🦋 Changeset detectedLatest commit: 6d9e4be The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/core
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6d9e4be81f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!supported.includes(options.protocolVersion)) { | ||
| throw new UnsupportedProtocolVersionError({ supported, requested: options.protocolVersion }); | ||
| } | ||
| this._negotiatedProtocolVersion = options.protocolVersion; |
There was a problem hiding this comment.
Notify the transport of the explicitly selected revision
When options is used with a custom transport that implements setProtocolVersion (for example, one that uses the selected revision to configure framing or headers), this branch updates only the Server and never calls that transport hook. The normal server initialize path calls this.transport?.setProtocolVersion(...), and modern client negotiation likewise propagates its choice, so an explicitly connected server and its transport can retain different version state for the whole connection; propagate options.protocolVersion to the transport as part of this path.
Useful? React with 👍 / 👎.
| throw new UnsupportedProtocolVersionError({ supported, requested: options.protocolVersion }); | ||
| } | ||
| this._negotiatedProtocolVersion = options.protocolVersion; | ||
| this._explicitProtocolVersion = true; |
There was a problem hiding this comment.
Reset and backfill identity on explicit modern connects
When a Server that completed a legacy initialize is closed and then reconnected through this explicit-modern path, _clientCapabilities and _clientVersion still belong to the old client because this path changes only the protocol version and modern connections never run _oninitialize to overwrite them. getClientCapabilities() and getClientVersion() explicitly remain functional for 2026 requests via envelope backfilling, but the manual connection path never performs the equivalent of seedClientIdentityFromEnvelope, so modern handlers can observe the previous client's identity (or undefined on a fresh instance); clear connection-scoped identity and backfill it from the validated envelope.
Useful? React with 👍 / 👎.
Fixes #3055.
A gateway cannot forward a change notification faithfully through
ServerEventBus: the event carries only a kind/URI, so the listen router drops custom_metaand extension params. A manually connectedServeralso rejects a correctly classified modern request because advertising supported versions does not bind the instance's serving revision.Keep optional notification params on bus events. The listen router retains those fields while stamping its own subscription ID, and resource events use their authoritative URI for filtering and delivery. Add an optional
ServerConnectOptionsargument toServer.connectandMcpServer.connectso a custom serving entry can bind a supported modern revision before transport startup. Clear that explicit binding on close; existing legacy connections keep their initialization flow.Ten public API regressions cover all four change notification kinds over real HTTP, both server classes, unsupported revisions, and a later legacy connection. All ten fail on the unmodified source and pass with this change. Includes documentation and a server patch changeset.
Validation on macOS with Node 24:
pnpm lint:allpasses from a fresh checkout.pnpm build:allandpnpm typecheck:allpass.node scripts/smoke-dist-types.mjspasses for ESM and CommonJS withoutskipLibCheck.pnpm test:all: all 271 test files report passed, with 7,207 tests passed and 141 existing expected failures. It exits nonzero on an unhandled 200 msREQUEST_TIMEOUTrejection fromscenarios/protocol.test.ts.The protocol timeout rejection also occurs without this change. An earlier full run reported two unhandled rejections; replaying only
scenarios/protocol.test.tsagainst unmodified upstream commit9bc40e903fde15534ec06ff4c1347d47000dbe16reproduced both (358 passed, 50 expected failures, two unhandled errors). The latest full run reports one of those rejections. No timeout, assertion, expected failure, or lint rule was changed.