Skip to content

chore: upgrade the MCP TypeScript SDK from 2.0.0-beta.5 to 2.0.0 - #1989

Merged
cliffhall merged 2 commits into
v2/mainfrom
v2/chore/1988-sdk-2.0.0
Aug 12, 2026
Merged

chore: upgrade the MCP TypeScript SDK from 2.0.0-beta.5 to 2.0.0#1989
cliffhall merged 2 commits into
v2/mainfrom
v2/chore/1988-sdk-2.0.0

Conversation

@cliffhall

Copy link
Copy Markdown
Member

Closes #1988

Moves the four MCP SDK packages off the 2.0.0-beta.5 prerelease onto 2.0.0 final (published 2026-07-27).

The change

-"@modelcontextprotocol/client": "2.0.0-beta.5",
-"@modelcontextprotocol/core": "2.0.0-beta.5",
-"@modelcontextprotocol/server": "2.0.0-beta.5",
-"@modelcontextprotocol/server-legacy": "2.0.0-beta.5",
+"@modelcontextprotocol/client": "2.0.0",
+"@modelcontextprotocol/core": "2.0.0",
+"@modelcontextprotocol/server": "2.0.0",
+"@modelcontextprotocol/server-legacy": "2.0.0",

Root package.json only, per the placement rule — Node resolution walks up, so the root install already serves every client and a per-client declaration would install a second copy that drifts (#1970). Verified post-install: one copy of each at 2.0.0, and clients/*/node_modules/@modelcontextprotocol/* does not exist. ext-apps is a separate package on its own ^1.7.4 line and is untouched.

The lockfile delta is exactly the four packages — 19 insertions, 19 deletions, no transitive churn.

Reviewing the delta

beta.5 → 2.0.0 is seven commits. Each checked for call-site impact:

Change Impact here
core/src/schemas.ts (+16/−16) None. Doc-comment only — every hunk rewrites a spec URL from a commit-pinned GitHub blob to the published 2026-07-28 page. No schema surface change, so core/mcp and core/json are unaffected.
fix(validators): honor declared draft-07/06 JSON Schema dialects instead of rejecting them Can only widen the set of tool schemas we accept.
SSE keep-alive frames, legacyWrap, createMcpHandler Server-side; exercised through test-servers/, not client code.
zod range client@2.0.0 wants ^4.2.0; we are on ^4.4.3. No move, so no risk of the #1896 dual-copy tsc heap blowup. verify:dep-lockstep stays green.
fix(client) #2564: probe 401/403 → auth failure, not legacy evidence Real reach — see below.

On #2564 and issue #1807

SDK PR #2564 is the upstream fix #1807 is blocked on. The probe classifier now gets explicit rows ahead of the JSON-RPC body parse: a 401/403 rejects as a typed SdkHttpError (ClientHttpAuthentication / ClientHttpForbidden) carrying the status, rather than falling into the conservative legacy fallback.

Deliberately not acted on in this PR. The directAuthRecovery clause in inspectorClient.ts still sets interceptAuthChallenges, so the challenge is converted to a typed AuthChallengeError before the classifier ever sees the 401 — connect behavior is unchanged by this bump. #1807 (milestone v2.4.0, waiting on sdk) can now delete that || this.probesProtocolEra() workaround and lean on the SDK verdict, exactly as its in-code comment instructs. Folding an auth-path change into a dependency bump would make both harder to review and to revert.

One thing #1807 will need to handle: SdkHttpError carries the status at err.data.status, and its message reads …(HTTP 401). isUnauthorizedError in core/auth/utils.ts checks err.status / err.code and matches \bfailed\b[^\n]*\(401\), so it would not recognize the new error as-is. That is a note for #1807, not a defect introduced here — the intercept means the path is not reached today.

Docs

Corrected the two auth as-built specs, which claimed beta.4 and so were already stale before this change.

specification/v2_new_spec_impact.md is left alone on purpose: it is a dated pre-upgrade impact analysis ("currently depends on sdk@1.29.0", "stable release planned alongside the spec on July 28"). Editing its premises would rewrite the record rather than update it.

Verification

npm run ci passes end to end — validate → the per-file ≥90 coverage gate → verify:build-gate → all six smokes → Storybook.

verify:build-gate OK — vite build fails on a Node built-in in the browser graph (#1769 gate fired).
smoke:launcher OK    smoke:cli OK    smoke:tui OK    smoke:web OK
smoke:web:browser OK — rendered "Add Servers" with no uncaught errors
smoke:web:app OK     — connected, opened "mcp_app_demo", widget reached data-app-status="ready"
Storybook:  Test Files 112 passed (112)   Tests 472 passed (472)

smoke:web:app is the load-bearing one for a protocol-library bump: it drives connect → open app → widget handshake against a real composable server, so it covers the transport, the sandbox proxy, and the UI-protocol bridge in one assertion.

No screenshots: this is a dependency bump with no UI change. The two headless-Chromium smokes above are the visual proof — smoke:web:browser asserts a clean first paint and smoke:web:app asserts a rendered widget, both against the prod bundle built on 2.0.0.

The SDK shipped 2.0.0 final on 2026-07-27. Shipping the Inspector against a
prerelease of its core protocol library is a supply-chain and reproducibility
liability we no longer have a reason to carry: a beta is eligible for unpublish
and deprecation in a way a stable release is not.

Bumped in the root package.json only — client, core, server, server-legacy.
Node resolution walks up, so the root install already serves every client; a
per-client declaration would install a second copy that drifts from it (#1970).
Verified after install: one copy of each at 2.0.0, no clients/*/node_modules/
@modelcontextprotocol/* at all. ext-apps is a separate package on its own ^1.7.4
line and is untouched.

The beta.5 → 2.0.0 delta is seven commits. Reviewed each for call-site impact:

  - core/src/schemas.ts (+16/-16) is doc-comment only — every hunk rewrites a
    spec URL from a commit-pinned GitHub blob to the published 2026-07-28 page.
    No schema surface change, so nothing in core/mcp or core/json is affected.
  - client 2.0.0 wants zod ^4.2.0; we are on ^4.4.3, so no zod move and no risk
    of the #1896 dual-copy tsc heap blowup. verify:dep-lockstep stays green and
    the lockfile delta is exactly the four packages with no transitive churn.
  - fix(validators) honors declared draft-07/06 JSON Schema dialects instead of
    rejecting them, which can only widen the set of tool schemas we accept.
  - The SSE keep-alive and legacyWrap changes are server-side, exercised by the
    test servers rather than by client code.

The one change with real behavioral reach is #2564: the negotiation probe now
classifies HTTP 401/403 as an auth failure instead of legacy-era evidence. That
is the upstream fix #1807 is blocked on, and it is left for that issue — the
directAuthRecovery clause in inspectorClient.ts still intercepts the challenge
before the classifier sees it, so this bump does not change connect behavior.
#1807 can now delete the workaround and lean on the SDK verdict, but doing it
here would smuggle an auth change into a dependency bump.

Also corrected the two auth as-built specs, which still claimed beta.4 —
already stale before this change. v2_new_spec_impact.md is deliberately left
alone: it is a dated pre-upgrade analysis, and editing its premises would
rewrite the record rather than update it.

npm run ci passes end to end: validate, the per-file >=90 coverage gate,
verify:build-gate, all six smokes (including web:app driving connect -> open
app -> data-app-status="ready"), and 472 Storybook tests.

Closes #1988

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HDdo1rNRVQnVRRdsqSrvG3
Signed-off-by: cliffhall <cliff@futurescale.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the shared MCP TypeScript SDK dependencies from beta.5 to stable 2.0.0.

Changes:

  • Updates four root SDK dependencies and lockfile entries.
  • Refreshes SDK-version references in two auth specifications.
  • Leaves required packaging, showcase-config verification, and one stale EMA specification unresolved.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
package.json Pins four MCP SDK packages to 2.0.0.
package-lock.json Resolves the updated SDK packages.
specification/v2_auth_sdk_consolidation.md Updates the documented client version.
specification/v2_auth_hardening.md Updates the documented client version.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment thread package.json
Comment thread package.json
Comment thread specification/v2_auth_sdk_consolidation.md
Review caught that v2_auth_ema.md contradicted itself. Its "TypeScript SDK
(implemented)" section claimed Inspector depends on `@modelcontextprotocol/sdk`
v1.x only (`^1.29.0`) and that there is "no `@modelcontextprotocol/client` v2
dependency in the tree today" — while the subsection immediately below it
documents which v2 client helpers the EMA legs have adopted.

Checked rather than assumed: every module the section's table names imports the
v2 client (emaFlow, idpOidc, resourceContext, tokenEndpoint, transportProvider,
wire, and providers.ts), and there are zero v1 SDK imports in first-party code.
The v1 SDK is present in the tree only as a peer pulled in by ext-apps, which
AGENTS.md already states must never become a direct dependency.

Rewrote the paragraph to say what is true and name the version, so it stays
consistent with the two auth specs corrected in the previous commit.

The per-row "v1 SDK" attributions in the table below it are wrong for the same
reason, but correcting each one means auditing which SDK symbol each leg calls
today — a real audit, not a version-string refresh, and out of scope for a
dependency bump. Left for a follow-up rather than guessed at here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HDdo1rNRVQnVRRdsqSrvG3
Signed-off-by: cliffhall <cliff@futurescale.com>
@cliffhall

Copy link
Copy Markdown
Member Author

Review round 1 — responses

All three comments were actionable and pointed at acceptance criteria from #1988. Mirroring here since inline threads get hidden once the fix is pushed.

1. Run pack:verify. Done, passes — tarball OK at 26 files with no source maps and clients/web/{build,dist,static} present, clean-consumer install of 190 packages, then the installed bin driving --help dispatch, a real --cli tools/list over stdio, and prod --web serving the shipped dist. Correctly identified as the gap ci cannot cover: the SDK packages are runtime dependencies resolved from the root manifest by a published install, and the client builds externalize npm packages, so the tarball is where a bad declaration would surface.

2. Exercise the era-sensitive showcase configs. Done — all 15 HTTP configs driven through the built CLI over a real transport, era derived from each config's transport.modern rather than guessed. 14 pass and match their documented shape. Full table in the inline thread.

This turned up a genuine bug — but not one this PR causes. logging-modern-http.json cannot connect at all:

Method `logging/setLevel` is not supported by the negotiated protocol version (wire era 2026-07-28)

I reverted the tree to 2.0.0-beta.5, reinstalled, reproduced it byte-identically, and restored 2.0.0 — so it predates the bump. Cause: clients/cli/src/cli.ts:152 hardcodes initialLoggingLevel: "debug", and core/mcp/inspectorClient.ts:1940 gates that connect-time call on the server capability but not the era. The CLI therefore cannot reach any modern server advertising logging, on any method. Web and TUI never pass initialLoggingLevel, which is why the documented by-hand web flow works and this stayed hidden. Filed as #1990 (bug, High, v2.3.0).

3. v2_auth_ema.md is stale. Fixed in 5587829. It was self-contradictory, claiming a v1-only SDK dependency while the subsection beneath it documented adopted v2 client helpers. Verified rather than assumed: every module that section names imports the v2 client, and there are zero v1 SDK imports in first-party code (v1 1.30.0 is only ext-apps's peer).

The per-row "v1 SDK" attributions in that table are wrong for the same reason and are deliberately left: correcting them means auditing which SDK symbol each EMA leg calls today, which is an audit rather than a version-string refresh. Same for the later checklist item. Flagged so it reads as a conscious deferral.

Not changed

The suggestion that the smoke suite should cover the showcase configs is a fair observation and a real gap, but committing new smoke tooling is its own change, not part of a dependency bump. The verification above was a one-off harness.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

@cliffhall
cliffhall merged commit 57d6e0d into v2/main Aug 12, 2026
10 checks passed
@cliffhall
cliffhall deleted the v2/chore/1988-sdk-2.0.0 branch August 12, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Issues and PRs for v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: upgrade the MCP TypeScript SDK from 2.0.0-beta.5 to 2.0.0

2 participants