-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Version Packages (alpha) #1845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Version Packages (alpha) #1845
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,22 @@ | ||
| # @modelcontextprotocol/client | ||
|
|
||
| ## 2.0.0-alpha.3 | ||
|
|
||
| ### Minor Changes | ||
|
|
||
| - [#1653](https://github.com/modelcontextprotocol/typescript-sdk/pull/1653) [`6bec24a`](https://github.com/modelcontextprotocol/typescript-sdk/commit/6bec24a14cb7e3dbe9f5e04aeb893cd0d6e8cb83) Thanks [@rechedev9](https://github.com/rechedev9)! - Add `validateClientMetadataUrl()` | ||
| utility for early validation of `clientMetadataUrl` | ||
|
|
||
| Exports a `validateClientMetadataUrl()` function that `OAuthClientProvider` implementations can call in their constructors to fail fast on invalid URL-based client IDs, instead of discovering the error deep in the auth flow. | ||
|
Check warning on line 10 in packages/client/CHANGELOG.md
|
||
|
Comment on lines
+3
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 PR #1843 didn't just add the Extended reasoning...What the bug isCommit 7ba58da (PR #1843, shipping in this alpha.3 release) deleted the line Neither alpha.3 CHANGELOG section mentions this. Why this is distinct from the existing #1843 commentInline comment 3068107615 already asks for a CHANGELOG entry for #1843, but frames it as a purely additive feature ("new Step-by-step proof
ImpactAny alpha.2 consumer who imported This is filed as a nit because (a) breaking changes between alpha pre-releases are expected, (b) the actionable fix is the same one-line CHANGELOG addition already requested in 3068107615 — just with the correct "Breaking: moved" framing rather than "Added", and (c) How to fixWhen adding the #1843 entry to both
rather than just "Added |
||
|
|
||
| ### Patch Changes | ||
|
|
||
| - [#1655](https://github.com/modelcontextprotocol/typescript-sdk/pull/1655) [`1eb3123`](https://github.com/modelcontextprotocol/typescript-sdk/commit/1eb31236e707c4f4ab9234d87db21ab3f34bf0bc) Thanks [@nielskaspers](https://github.com/nielskaspers)! - fix(client): append custom | ||
| Accept headers to spec-required defaults in StreamableHTTPClientTransport | ||
|
|
||
|
Comment on lines
+3
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 PR #1843 (commit 7ba58da) added the Extended reasoning...CF Workers validator feature silently absent from alpha.3 CHANGELOGWhat the bug is and how it manifests PR #1843 (commit 7ba58da) landed two concrete, user-visible additions to both The specific code path
Addressing the refutations Two verifiers argued this is "not actionable" because the Changesets workflow can only produce entries from changeset files and the version-bump PR cannot retroactively create them. This reasoning is correct about how Changesets generates content automatically, but misses the point: CHANGELOG.md files are plain text and can be edited manually before a PR is merged. Version-bump PRs that accidentally missed changesets are routinely fixed by hand-editing the CHANGELOG before the merge/publish. Since this PR has not yet been merged, the omission is still correctable here. The workflow contract is with the automation, not with the maintainers — maintainers always retain the ability to amend the generated text. Why existing code does not prevent it There is no CI check that validates CHANGELOG completeness against the set of merged commits between two version tags. The Changesets action produces whatever its inputs say; it cannot detect omitted changeset files. The alpha pre-release mode does not lower the practical importance of this: the Step-by-step proof
How to fix Manually add a patch-change entry to both - [#1843](https://github.com/modelcontextprotocol/typescript-sdk/pull/1843) Add `./validators/cf-worker` sub-path export and `CfWorkerJsonSchemaValidator` for Cloudflare Workers environments. Import from `@modelcontextprotocol/client/validators/cf-worker` (or `/server/`) to use the workerd-compatible JSON Schema validator.This is a one-time manual correction; no changeset infrastructure changes are needed. |
||
| Custom Accept headers provided via `requestInit.headers` are now appended to the spec-mandated Accept types instead of being overwritten. This ensures the required media types (`application/json, text/event-stream` for POST; `text/event-stream` for GET SSE) are always present | ||
| while allowing users to include additional types for proxy/gateway routing. | ||
|
|
||
|
Comment on lines
+15
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The CHANGELOG entry says custom Accept headers are "appended to the spec-mandated Accept types", implying spec-required types come first, but the actual implementation does the reverse: user-provided types are placed first and spec-required types are appended last. The description should be corrected to accurately reflect the ordering, e.g., "spec-mandated Accept types are appended to any custom Accept headers". Extended reasoning...CHANGELOG Wording Inverts Actual Accept Header OrderingWhat the bug is and how it manifests The new CHANGELOG entry (line 10) states: "Custom Accept headers provided via requestInit.headers are now appended to the spec-mandated Accept types instead of being overwritten." In standard English, "X appended to Y" means Y is the base and X is added after — so this sentence implies spec-required types come first, with user custom types added afterward. However, the actual implementation in streamableHttp.ts does the opposite. The GET SSE path uses: The specific code path and why it matters Per RFC 7231, when multiple Accept types share equal q-values, earlier entries carry higher implicit preference. So the actual behavior gives user-provided types higher preference than spec-required types. The CHANGELOG implies the opposite preference ordering. While this ordering may be intentional (user routing hints for proxies need higher preference), the documentation still misrepresents which type comes first. Addressing the refutation The refutation argues that user-types-first is intentional for proxy/gateway routing, that CHANGELOG entries are not formal specs, and that this is a version-bump PR. These points are valid context, but they do not resolve the wording inaccuracy. The key claim in the CHANGELOG — that spec-required types are always present — is correct, but the described ordering is backwards. The fix is a one-line wording update, not a code change. Since this CHANGELOG entry appears in this PR's diff, this is the appropriate place to catch it. Step-by-step proof of the discrepancy
Impact and fix This is a documentation-only inaccuracy — the functional behavior is correct (spec-required types are always present). The fix is to update the CHANGELOG wording to something like: "spec-mandated Accept types are appended to any custom Accept headers provided via requestInit.headers", which accurately reflects user types appearing first with spec types appended after. The secondary q-value deduplication issue (e.g., text/event-stream; q=0.9 not deduped against text/event-stream) is a pre-existing edge case from PR #1655 and not introduced by this PR. |
||
| ## 2.0.0-alpha.2 | ||
|
|
||
|
Comment on lines
+3
to
21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 PR #1842 (commit 1eb80c4, 'v2: add guard methods') introduced new public API type guards — at minimum isCallToolResult and isJSONRPCResponse — to @modelcontextprotocol/client and @modelcontextprotocol/server without a changeset file, so these exports are absent from all alpha.3 CHANGELOGs. Before merging, manually add CHANGELOG entries for the new guard functions in packages/client/CHANGELOG.md and packages/server/CHANGELOG.md under 2.0.0-alpha.3. Extended reasoning...Guard methods from PR #1842 absent from alpha.3 CHANGELOGsWhat the bug is and how it manifests PR #1842 (commit 1eb80c4, 'v2: add guard methods') added new type guard functions to The specific code path The guards flow: Why existing code does not prevent it There is no CI check that validates CHANGELOG completeness against the set of merged commits. The Changesets action only generates entries from changeset files it finds; it cannot detect commits that should have had a changeset but did not. This is the same root cause as the CF Workers CHANGELOG omission (PR #1843). Impact Users upgrading from alpha.2 to alpha.3 who read the release notes have no way to discover these new type guard exports. Alpha users actively track release notes precisely to find new APIs, so undocumented public additions reduce the practical value of the alpha program. The omission is a documentation gap with no functional impact. Step-by-step proof
How to fix Manually add a patch-change entry to both |
||
| ### Patch Changes | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| { | ||
| "name": "@modelcontextprotocol/client", | ||
| "version": "2.0.0-alpha.2", | ||
| "version": "2.0.0-alpha.3", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The browser export condition for ./_shims in packages/client/package.json routes to dist/shimsBrowser.mjs, which contains a bare external ESM import of @cfworker/json-schema (inlined from core via noExternal, but with @cfworker/json-schema left external). Since @cfworker/json-schema is only in devDependencies and not in dependencies or peerDependencies, any browser bundler (Vite, webpack, Rollup, esbuild) that resolves the browser export condition will fail with a module-not-found error. Fix by adding @cfworker/json-schema as an optional peerDependency in packages/client/package.json. Extended reasoning...Client shimsBrowser.mjs requires @cfworker/json-schema but it is not in runtime dependenciesWhat the bug is and how it manifests packages/client/package.json exports the ./_shims entry with a browser condition that points to dist/shimsBrowser.mjs. This file is built from packages/client/src/shimsBrowser.ts, which exports CfWorkerJsonSchemaValidator as DefaultJsonSchemaValidator from @modelcontextprotocol/core (line 6). packages/core/src/validators/cfWorkerProvider.ts has a static top-level import: import { Validator } from '@cfworker/json-schema' (line 11). The tsdown.config.ts sets noExternal: ['@modelcontextprotocol/core'], so all of core is inlined into the client bundle — but @cfworker/json-schema is NOT in noExternal and therefore remains as a bare external ESM import statement in the emitted dist/shimsBrowser.mjs. The specific code path that triggers it Browser bundlers (Vite, webpack, Rollup, esbuild) automatically select the browser export condition when targeting browsers. Any developer building a browser application that imports @modelcontextprotocol/client will have their bundler resolve ./_shims → dist/shimsBrowser.mjs, which immediately encounters import { Validator } from '@cfworker/json-schema' as the first top-level import. Since @cfworker/json-schema is only in devDependencies of packages/client/package.json and not in dependencies or peerDependencies, it is never installed for npm consumers. Why existing code does not prevent it packages/core/package.json does list @cfworker/json-schema as an optional peerDependency. However, core is "private": true and never published to npm, so its dependency declarations are invisible to external consumers. The only package.json that matters to browser bundler consumers is packages/client/package.json, and there @cfworker/json-schema appears exclusively in devDependencies. No package manager will warn users to install it, and no bundler will find it in node_modules. What the impact is Any developer targeting a browser environment with @modelcontextprotocol/client@2.0.0-alpha.3 will receive a module-not-found error for @cfworker/json-schema at build time (static bundlers like Vite/esbuild) or at runtime. The browser condition is applied automatically — no explicit import of the validator sub-path is needed to trigger this. This bug is distinct from the workerd condition issue (bug_003) and the server browser condition issue (bug_008); the client's shimsBrowser.ts has CORS_IS_POSSIBLE=true semantics distinct from the workerd shim but still uses CfWorkerJsonSchemaValidator, so the same missing dependency applies here. Step-by-step proof
How to fix Add @cfworker/json-schema as an optional peerDependency in packages/client/package.json. This ensures package managers warn browser-targeting consumers to install @cfworker/json-schema and makes the runtime requirement visible in the published package metadata. Alternatively, add @cfworker/json-schema to noExternal in the client's tsdown.config.ts to bundle it directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Commit 7ba58da rewrote the JSDoc at Extended reasoning...Published JSDoc promises bundling that the build does not deliverWhat the bug is Commit 7ba58da (PR #1843, shipping in this alpha.3 release) changed the JSDoc block in
to:
The same commit removed However, the only build-config change in 7ba58da was adding Why this is distinct from the four earlier dependency comments One reviewer will reasonably note that comments 3035194589, 3073682357, 3073682371, and 3073783213 already cover the module-not-found symptom and that two of them mention
So this comment is the root-cause framing that resolves the ambiguity across the four prior reports, not a fifth restatement of the symptom. Why nothing prevents it
Step-by-step proof
Impact Same runtime blast radius already described in the earlier comments (module-not-found on Node, browser, and workerd). The additional impact here is that the published type definitions actively mislead users into not installing the missing packages, and the migration guide reinforces that. Per REVIEW.md: "prose that promises behavior the code no longer ships misleads consumers." Fix Extend noExternal: ['@modelcontextprotocol/core', 'ajv', 'ajv-formats', '@cfworker/json-schema'],This makes the build match the JSDoc, the migration guide, and the peerDependency removal in one change. If maintainers instead prefer the runtime-/peer-dependency route, then the JSDoc at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 PR #1875 (commit 9ed62fe, shipping in this alpha.3 release) added a Extended reasoning...What the bug isPR #1875 (commit 9ed62fe — direct parent of this version-bump commit, so it ships in
The implementation does spread new jose.SignJWT(claims)
.setProtectedHeader({ alg, typ: 'JWT' })
.setIssuer(options.issuer)
.setSubject(options.subject)
.setAudience(audience)
.setIssuedAt(now)
.setExpirationTime(now + lifetimeSeconds)
.setJti(jti)
.sign(...)Each of those setters writes back into the payload after the constructor copies Why existing code doesn't prevent itVerified against jose@6.2.2 source ( The tests added in 9ed62fe only exercise non-standard claims ( Step-by-step proof
ImpactThis is a docs-vs-implementation contradiction in a public API surface that ships to npm in this release. A user who follows the JSDoc to override The spread at line 60 is effectively dead code for the six standard claims — it only matters for additional, non-standard claims. How to fixTwo options, pick one:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟣 🟣 Pre-existing — and a correction to the five prior runtime-dependency comments (3035194589 / 3073682357 / 3073682371 / 3073783213 / 3078795515): I built dist and verified that Extended reasoning...Correction to prior comments + actual residual issuePrior comments are factually wrong about runtime. Five earlier comments on this PR (3035194589, 3073682357, 3073682371, 3073783213, 3078795515) assert that
Why the earlier reasoning was wrong: those comments assumed tsdown/rolldown externalises every bare import not listed in The actual residual issue (type-only)What the dist inspection did surface is that the bundled type declarations still reference external packages. import { Ajv } from 'ajv';
import { JSONSchema } from 'json-schema-typed';These are used at Neither Step-by-step proof
Impact and fixRuntime is fine; this is a compile-time-only break for the Two fix options:
Filed primarily so the maintainers don't act on the incorrect runtime-crash framing / |
||
| "description": "Model Context Protocol implementation for TypeScript - Client package", | ||
| "license": "MIT", | ||
| "author": "Anthropic, PBC (https://anthropic.com)", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,12 @@ | ||
| # @modelcontextprotocol/core | ||
|
|
||
| ## 2.0.0-alpha.2 | ||
|
|
||
| ### Patch Changes | ||
|
|
||
| - [#1768](https://github.com/modelcontextprotocol/typescript-sdk/pull/1768) [`866c08d`](https://github.com/modelcontextprotocol/typescript-sdk/commit/866c08d3640c5213f80c3b4220e24c42acfc2db8) Thanks [@felixweinberger](https://github.com/felixweinberger)! - Allow additional JSON | ||
| Schema properties in elicitInput's requestedSchema type by adding .catchall(z.unknown()), matching the pattern used by inputSchema. This fixes type incompatibility when using Zod v4's .toJSONSchema() output which includes extra properties like $schema and additionalProperties. | ||
|
Comment on lines
+3
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The Extended reasoning...What the bug is
Why changesets doesn't propagate thisThere is also a structural issue beyond the documentation gap: Relationship to prior commentsThis is distinct from the previously-filed comments about PR #1842 and PR #1843 (which lacked changeset files entirely). Here a changeset does exist but targets an unpublished package. It is the same class of outcome (missing entry in published CHANGELOGs) with a different root cause (mis-targeted vs. missing changeset). This pattern is not new — the alpha.1 core CHANGELOG already contains several core-only entries (#1735, #1790, #1766, #1762) that similarly never appeared in client/server CHANGELOGs, so maintainers may consider this established practice. That precedent is why this is filed as a nit rather than a blocking issue, but the devDependency-propagation observation is worth surfacing because it means core-only changesets are effectively no-ops for publishing. Step-by-step proof
Impact and fixImpact is documentation-only in this release (the fix does ship), but the changeset is structurally mis-targeted. Short-term: manually add the #1768 entry under |
||
|
|
||
| ## 2.0.0-alpha.1 | ||
|
|
||
|
Comment on lines
+3
to
11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The isCallToolResult guard (introduced in PR #1842, now published in this alpha.2 version bump) returns false for any object missing an explicit content key, but CallToolResultSchema.safeParse({}).success returns true because content carries .default([]). The migration guide at docs/migration.md:450-454 explicitly presents isCallToolResult(value) as a direct drop-in replacement for CallToolResultSchema.safeParse(value).success; that equivalence claim is incorrect and will silently produce false negatives for users following the guide with objects lacking an explicit content field. Extended reasoning...What the bug is: isCallToolResult in packages/core/src/types/guards.ts contains an early-exit check !("content" in value) that short-circuits for any object without a content own-property, even if that object would parse successfully via the schema. Meanwhile, CallToolResultSchema defines content: z.array(ContentBlockSchema).default([]), so CallToolResultSchema.safeParse({}).success === true. The two are not equivalent. The migration guide makes an explicit, incorrect equivalence claim: docs/migration.md:450-454 presents isCallToolResult(value) as a direct drop-in replacement for CallToolResultSchema.safeParse(value).success. Any user migrating by substituting isCallToolResult will silently get false for a valid CallToolResult whose content field was omitted in the raw object — e.g. a tool response carrying only structuredContent before going through Zod parsing. Addressing the refutations: The refutations correctly observe that (a) the TypeScript output type for CallToolResult has content as a required field (Zod's .default([]) makes it required in the output, optional only in input), (b) the MCP spec says content is "always present" for backwards compatibility, and (c) values returned by client.callTool() have already been Zod-parsed so content will be present. These are valid, and they explain why real-world breakage is narrow in normal SDK usage. However, the refutations do not resolve the issue: the migration guide's equivalence claim is stated unconditionally, without the caveat that it only holds for already-parsed values. A developer writing a custom validator, testing raw server responses, or constructing a CallToolResult-shaped object manually before parsing will encounter a false negative. The guard is intentionally stricter than safeParse, but the migration guide does not communicate this distinction. Concrete proof: (1) Raw object: { isError: false } — no content key, but valid per schema since content defaults to []. (2) CallToolResultSchema.safeParse({ isError: false }).success returns true. (3) isCallToolResult({ isError: false }) returns false due to the !("content" in value) early exit. (4) A user following the migration guide who swaps step 2 for step 3 silently rejects a valid value. Impact and fix: The bug's practical blast radius is limited to objects that have not been Zod-parsed yet; in the normal SDK flow those are rare. But this is a published migration guide making a false API contract claim. The fix is either to remove the !("content" in value) early-exit in guards.ts (making the guard consistent with safeParse semantics), or to update the migration guide to clearly document that isCallToolResult is stricter and requires content to be explicitly present in the raw object. |
||
| ### Minor Changes | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| { | ||
| "name": "@modelcontextprotocol/core", | ||
| "private": true, | ||
| "version": "2.0.0-alpha.1", | ||
| "version": "2.0.0-alpha.2", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟣 Pre-existing: Extended reasoning...Analysis
These two declarations are semantically contradictory. A direct dependency auto-installs and requires nothing from the consumer; a non-optional peer dependency generates package-manager warnings telling consumers they must install the dependency themselves. Why existing code does not prevent thisThe Step-by-step proof
ImpactPractical impact is minimal: FixRemove the |
||
| "description": "Model Context Protocol implementation for TypeScript - Core package", | ||
| "license": "MIT", | ||
| "author": "Anthropic, PBC (https://anthropic.com)", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,12 @@ | ||
| # @modelcontextprotocol/server | ||
|
|
||
| ## 2.0.0-alpha.3 | ||
|
|
||
| ### Patch Changes | ||
|
|
||
| - [#1788](https://github.com/modelcontextprotocol/typescript-sdk/pull/1788) [`df4b6cc`](https://github.com/modelcontextprotocol/typescript-sdk/commit/df4b6cc88d6f24fc857519cf506a7a039f532637) Thanks [@claygeo](https://github.com/claygeo)! - Prevent stack overflow in | ||
| StreamableHTTPServerTransport.close() with re-entrant guard | ||
|
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 The CHANGELOG entry for 2.0.0-alpha.3 references a non-existent class name Extended reasoning...What the bug is The new CHANGELOG entry in
No class named The specific code that was changed The re-entrancy fix (a Why existing validation doesn't catch it Changesets generates CHANGELOG prose from the markdown body of changeset files. The changeset author used the shorthand Impact Developers searching the CHANGELOG or codebase for Step-by-step proof
How to fix Change the CHANGELOG entry to: "Prevent stack overflow in |
||
|
|
||
| ## 2.0.0-alpha.2 | ||
|
|
||
| ### Patch Changes | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| { | ||
| "name": "@modelcontextprotocol/server", | ||
| "version": "2.0.0-alpha.2", | ||
| "version": "2.0.0-alpha.3", | ||
| "description": "Model Context Protocol implementation for TypeScript - Server package", | ||
| "license": "MIT", | ||
| "author": "Anthropic, PBC (https://anthropic.com)", | ||
|
Comment on lines
1
to
6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 PR #1843 removed @cfworker/json-schema from peerDependencies of both @modelcontextprotocol/client and @modelcontextprotocol/server while simultaneously adding ./validators/cf-worker sub-path exports and workerd shims that depend on it at runtime, meaning any Cloudflare Workers consumer will get a module-not-found error. Re-add @cfworker/json-schema as an optional peerDependency in packages/client/package.json and packages/server/package.json before publishing these alpha.3 packages. Extended reasoning...@cfworker/json-schema removed from peerDependencies but required at runtimeWhat the bug is and how it manifests PR #1843 (commit 7ba58da, merged before this version-bump PR) made two contradictory changes simultaneously: (1) it added new ./validators/cf-worker sub-path exports and workerd condition shims in both @modelcontextprotocol/client and @modelcontextprotocol/server that depend on @cfworker/json-schema, and (2) it removed @cfworker/json-schema from the peerDependencies of both published packages. As a result, any consumer who installs @modelcontextprotocol/server@2.0.0-alpha.3 or @modelcontextprotocol/client@2.0.0-alpha.3 will not have @cfworker/json-schema in their node_modules, and runtime module resolution will fail. The specific code path that triggers it The chain is: packages/server/src/shimsWorkerd.ts and packages/client/src/shimsWorkerd.ts export CfWorkerJsonSchemaValidator from '@modelcontextprotocol/core'. packages/core/src/validators/cfWorkerProvider.ts line 11 contains a top-level static import: . The tsdown.config.ts for both client and server uses , which inlines core code directly into the built output bundles. However, @cfworker/json-schema is NOT in noExternal — the config comment explicitly states 'treat all other dependencies as external'. Therefore, the built dist/shimsWorkerd.mjs and dist/validators/cfWorker.mjs both contain a bare external ESM import statement at the top of the file. Why existing code doesn't prevent it packages/core/package.json does list @cfworker/json-schema as an optional peerDependency. However, core is and is never published to npm — its peerDependencies declaration is invisible to external consumers. The only package.json files that matter to npm consumers are packages/client/package.json and packages/server/package.json, and in both of those @cfworker/json-schema appears only in devDependencies (not installed for consumers, only for local development). Impact There are two affected populations: (1) Any Cloudflare Workers user of either package — the workerd export condition is automatically selected by CF Workers bundlers (Wrangler), so even users who never explicitly import from /validators/cf-worker will get shimsWorkerd.mjs loaded, which immediately fails with a top-level import error. This breaks ALL CF Workers integrations. (2) Users who explicitly import from '@modelcontextprotocol/server/validators/cf-worker' or '@modelcontextprotocol/client/validators/cf-worker' in any environment also get the same failure. No package manager will warn about the missing dependency because there is no peerDependencies declaration in the published packages. Step-by-step proof
How to fix Re-add @cfworker/json-schema as an optional peerDependency in both packages/client/package.json and packages/server/package.json, matching the pattern used before PR #1843: This ensures package managers warn CF Workers users to install the dependency and makes the runtime requirement explicit in the published package metadata.
Comment on lines
1
to
6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The server's Extended reasoning...Server browser export condition routes to CF Workers shim, missing required dependencyWhat the bug is and how it manifests
The specific code path
Why existing code doesn't prevent it The client package ( Addressing the refutation One verifier argued that the browser→shimsWorkerd routing is intentional because the server needs CfWorkerJsonSchemaValidator (AJV has Node.js dependencies and cannot run in browsers) and both environments need identical behavior — unlike the client which requires distinct Step-by-step proof
How to fix Option A (minimal): Add Option B (correct): Create a Option C (simplest safe fix): Remove the 🔬 also observed by 3035194589
claude[bot] marked this conversation as resolved.
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 PR #1875 (commit 9ed62fe) added a public
claims?: Record<string, unknown>option toPrivateKeyJwtProviderOptionsbut landed without a changeset, so this user-facing feature is absent from the@modelcontextprotocol/clientalpha.3 CHANGELOG even though it ships in this release. Either land a changeset onmainand let the bot regenerate this PR, or manually add a Minor-change entry crediting #1875 under 2.0.0-alpha.3 before merging.Extended reasoning...
PR #1875 custom-claims feature absent from alpha.3 CHANGELOG
What the bug is and how it manifests
PR #1875 (commit 9ed62fe, merged 2026-04-14 — after the most recent bot review at 10:29 UTC) added a new public
claims?: Record<string, unknown>option toPrivateKeyJwtProviderOptions, letting callers inject custom JWT claims into theprivate_key_jwtclient-assertion flow.PrivateKeyJwtProviderandPrivateKeyJwtProviderOptionsare both re-exported frompackages/client/src/index.ts(lines ~45–53), so this is a user-facing public-API addition. However, the commit touched onlypackages/client/src/client/authExtensions.tsand its test file — it created no.changeset/*.mdfile. As a result, the Changesets action generated no CHANGELOG entry for it.The specific code path
The Version Packages commit
91dceb0(this PR's HEAD) sits directly on top of9ed62feingit log, so theclaimsoption WILL be published as part of@modelcontextprotocol/client@2.0.0-alpha.3. Yet.changeset/pre.jsonin this PR adds only four new slugs (fix-streamable-close-reentrant,fix-validate-client-metadata-url,odd-forks-enjoy,zod-json-schema-compat) — none corresponding to #1875 — andpackages/client/CHANGELOG.mdlines 3–19 list only #1653 and #1655 under the alpha.3 section.Why existing checks don't catch it
There is no CI gate that diffs the set of merged commits against the set of changeset slugs. Changesets faithfully renders whatever
.changeset/*.mdfiles exist; commits that should have included one but did not pass through silently. This is the same root cause already flagged on this PR for #1842 (guard methods) and #1843 (CF Workers validator), but those comments do not cover #1875, which landed afterward.Impact
Documentation-only: the feature ships and works, but alpha users reading the npm release notes for
client@2.0.0-alpha.3have no way to discover thatPrivateKeyJwtProvidernow accepts custom claims. Alpha users actively track release notes to find new APIs, so undocumented additions reduce the value of the alpha program.Step-by-step proof
git show 9ed62fe --stat→ onlypackages/client/src/client/authExtensions.tsandpackages/client/src/client/authExtensions.test.tschanged.git show 9ed62fe -- .changeset/→ empty; no changeset file added.git log --oneline -2 91dceb0→91dceb0 Version Packages (alpha)followed by9ed62fe feat(client): support custom claims in PrivateKeyJwtProvider (#1875)— 9ed62fe is an ancestor of this release.grep -r "claims\|1875\|PrivateKeyJwt" .changeset/→ no matches.packages/client/CHANGELOG.mdlines 3–19 (alpha.3 section): only fix: validate clientMetadataUrl at construction time (fail-fast) #1653 and fix(client): preserve custom Accept headers in StreamableHTTPClientTransport #1655 listed; no mention ofclaims/PrivateKeyJwtProvider/ feat(client): support custom claims in PrivateKeyJwtProvider #1875.How to fix
Preferred: land a
minorchangeset onmaintargeting@modelcontextprotocol/clientand let the Changesets bot regenerate this PR. Alternatively, hand-editpackages/client/CHANGELOG.mdto add under### Minor Changesfor 2.0.0-alpha.3: