Skip to content

feat(client,server): bundle default validators, expose customisation via subpaths#2088

Merged
KKonstantinov merged 6 commits into
mainfrom
fix/server-cfworker-json-schema-shim
May 29, 2026
Merged

feat(client,server): bundle default validators, expose customisation via subpaths#2088
KKonstantinov merged 6 commits into
mainfrom
fix/server-cfworker-json-schema-shim

Conversation

@mattzcarey
Copy link
Copy Markdown
Contributor

@mattzcarey mattzcarey commented May 14, 2026

What this PR does

Makes the default JSON Schema validator a zero-install, zero-config experience that adapts to your runtime, and gives customisation users a single-import escape hatch with no package.json changes required.

Default usage — just import McpServer

import { McpServer } from '@modelcontextprotocol/server';

const server = new McpServer({ name: 'my-server', version: '1.0.0' }, { capabilities: { tools: {} } });

That's it. No installs, no config, no validator imports.

The package's _shims conditional export picks the right runtime shim for you, and the shim has the right validator backend bundled into it:

Runtime Resolved shim Bundled validator
Node (Express, Next.js server, plain node script.js, etc.) dist/shimsNode.mjs AJV + ajv-formats
Cloudflare Workers / wrangler dev dist/shimsWorkerd.mjs @cfworker/json-schema
Browser / Vite / esbuild --platform=browser dist/shimsWorkerd.mjs @cfworker/json-schema
Deno deploy (workerd condition) dist/shimsWorkerd.mjs @cfworker/json-schema

If you move the same code from Node to a Worker, the bundle just picks the right backend — your code doesn't change, your package.json doesn't change.

Customising the bundled validator

Want to add custom AJV formats, change the draft, pre-register schemas by $id? Import from the subpath. The subpath re-exports Ajv and addFormats from the SDK's vendored copy, so you don't need ajv or ajv-formats in your package.json:

import { Ajv, addFormats, AjvJsonSchemaValidator } from '@modelcontextprotocol/server/validators/ajv';

const ajv = new Ajv({ strict: true, allErrors: true });
addFormats(ajv);

new McpServer(info, {
    capabilities: { tools: {} },
    jsonSchemaValidator: new AjvJsonSchemaValidator(ajv),
});

Same idea for the workerd validator (its customisation surface is a plain options object — no third-party constructor to expose):

import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker';

new McpServer(info, {
    capabilities: { tools: {} },
    jsonSchemaValidator: new CfWorkerJsonSchemaValidator({ draft: '2020-12', shortcircuit: false }),
});

The same paths exist on @modelcontextprotocol/client/validators/{ajv,cf-worker}.

Important: importing from one of these subpaths pins your code to that backend. The default McpServer import would have picked the validator per runtime; the subpath explicitly chooses AJV (or cfworker) regardless of where you deploy. Use the subpath when you actually want that, not as a habit.

Replacing validation wholesale

Bring your own object implementing the jsonSchemaValidator interface:

new McpServer(info, {
    capabilities: { tools: {} },
    jsonSchemaValidator: myCustomValidator,
});

Why the named classes are subpath-only, not on the root barrel

Re-exporting AjvJsonSchemaValidator or CfWorkerJsonSchemaValidator from @modelcontextprotocol/server (root) would pull the corresponding backend's code into every consumer's root index chunk, including the 95% of users who never customise. Subpaths keep the default code path validator-overhead-free and let bundlers tree-shake cleanly. The structural type used for the AJV constructor parameter (AjvLike declared inside ajvProvider.ts) similarly removes the bare import { Ajv } from "ajv" from the chunk transitively reached by the root entry, so TS consumers don't hit TS2307 either.

Codemod (v1 → v2)

The v1-to-v2 codemod (@modelcontextprotocol/codemod) rewrites v1 validator imports to the new v2 subpaths automatically, picking client vs server per file based on sibling imports + the consumer's package.json:

v1 v2
@modelcontextprotocol/sdk/validation/{ajv,ajv-provider}[.js] @modelcontextprotocol/{client,server}/validators/ajv
@modelcontextprotocol/sdk/validation/{cfworker,cfworker-provider}[.js] @modelcontextprotocol/{client,server}/validators/cf-worker
@modelcontextprotocol/sdk/validation/{index,types}.js @modelcontextprotocol/{client,server} (type-only barrel)

Verified end-to-end against a real-world v1 caller this PR is unblocking.

Known limitations

The SDK's bundled AJV does not tree-shake away if the user passes their own. Server's constructor falls back to new DefaultJsonSchemaValidator() via a static ?? expression, so the bundler keeps the default validator's chunk reachable even when every call site at runtime supplies a custom jsonSchemaValidator. A user who imports Ajv directly from 'ajv' (instead of from our subpath) and passes their own instance ends up with two copies of AJV in their bundle — ours (vendored into the shim) + theirs (from their node_modules). ~30 KB gzipped overhead.

Workarounds for that user:

  • Import Ajv from our subpath (import { Ajv } from '@modelcontextprotocol/server/validators/ajv') so both the validator class and the AJV constructor come from the SDK's single vendored copy.
  • Use a bundler dedup pass (esbuild's dedupe, pnpm's dedupe, Webpack resolve.alias) if their AJV version matches the SDK's pin.

The default case — just McpServer with no custom validator — is unaffected: one copy of AJV (or @cfworker/json-schema), exactly the one the runtime needs. The duplication only shows up for the customisation path with a third-party AJV install.

Properly fixing the tree-shake would require an API change (e.g. dynamic import() of the default, which propagates async into validation; or making the default opt-in, which removes the zero-config story). Left as a future follow-up if real complaints come in.

Migration

For users who never customised the validator: nothing to do.

For users who customised it manually:

- import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/cfworker-provider.js';
+ import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker';

For AJV specifically, the new subpath now serves Ajv and addFormats too, so you can drop ajv / ajv-formats from package.json:

- import { Ajv } from 'ajv';
- import addFormats from 'ajv-formats';
- import { AjvJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/ajv-provider.js';
+ import { Ajv, addFormats, AjvJsonSchemaValidator } from '@modelcontextprotocol/server/validators/ajv';

The codemod handles the path rewrite. Folding the ajv / ajv-formats imports into the new subpath, and removing them from package.json, is a follow-up.

@mattzcarey mattzcarey requested a review from a team as a code owner May 14, 2026 10:46
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 14, 2026

🦋 Changeset detected

Latest commit: 99cf12f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/core Minor

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

Comment thread packages/codemod/src/bin/batchTest.ts Fixed
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 14, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@2088

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2088

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@2088

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@2088

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2088

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@2088

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@2088

commit: 99cf12f

@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 54c18d7 to ba08235 Compare May 14, 2026 11:02
@mattzcarey mattzcarey changed the title Bundle workerd JSON schema validator in server shim Make validator backends optional in core and bundle client/server defaults May 14, 2026
Comment thread packages/codemod/package.json
Comment thread packages/codemod/src/bin/batchTest.ts
Comment thread packages/codemod/src/bin/batchTest.ts Outdated
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch 2 times, most recently from c7601a2 to 5db154c Compare May 14, 2026 11:14
@mattzcarey mattzcarey changed the title Make validator backends optional in core and bundle client/server defaults Bundle automatic validator defaults in client/server shims May 14, 2026
@mattzcarey mattzcarey changed the base branch from main to feature/v2-codemode-draft May 14, 2026 11:16
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 5db154c to 78bd6c2 Compare May 14, 2026 11:18
@mattzcarey mattzcarey changed the base branch from feature/v2-codemode-draft to main May 14, 2026 11:18
Comment thread packages/core/src/exports/public/index.ts
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch 5 times, most recently from 9c5c541 to 57c3a0b Compare May 14, 2026 11:36
Comment thread packages/server/package.json
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 57c3a0b to a2b954b Compare May 14, 2026 11:46
Comment thread test/integration/test/standardSchema.test.ts
Comment thread packages/core/src/index.ts Outdated
Comment thread packages/server/test/server/barrelClean.test.ts
Comment thread .changeset/workerd-shim-vendors-cfworker.md Outdated
mattzcarey added a commit that referenced this pull request May 15, 2026
After PR #2088, end users can no longer import or construct
AjvJsonSchemaValidator / CfWorkerJsonSchemaValidator — client/server
bundle them via the runtime shim and expose only the jsonSchemaValidator
interface as the public extension point.

- Strip impossible `new AjvJsonSchemaValidator()` / `new CfWorkerJsonSchemaValidator()`
  snippets from JSDoc on the validation module, ajvProvider, cfWorkerProvider,
  and fromJsonSchema; mark the provider classes @internal.
- fromJsonSchema example now declares `validator: jsonSchemaValidator` and
  notes that consumers importing from server/client omit the second arg.
- Drop the type-only re-exports of AjvJsonSchemaValidator,
  CfWorkerJsonSchemaValidator, and CfWorkerSchemaDraft from core/public —
  with the runtime classes unreachable, a type-only handle is dead surface.
- Reword the migration docs to describe backends by name (AJV /
  @cfworker/json-schema) instead of the now-internal class names.
Comment thread packages/server/src/server/server.ts Outdated
Comment thread .changeset/workerd-shim-vendors-cfworker.md Outdated
mattzcarey added a commit that referenced this pull request May 15, 2026
After PR #2088, end users can no longer import or construct
AjvJsonSchemaValidator / CfWorkerJsonSchemaValidator — client/server
bundle them via the runtime shim and expose only the jsonSchemaValidator
interface as the public extension point.

- Strip impossible `new AjvJsonSchemaValidator()` / `new CfWorkerJsonSchemaValidator()`
  snippets from JSDoc on the validation module, ajvProvider, cfWorkerProvider,
  and fromJsonSchema; mark the provider classes @internal.
- fromJsonSchema example now declares `validator: jsonSchemaValidator` and
  notes that consumers importing from server/client omit the second arg.
- Drop the type-only re-exports of AjvJsonSchemaValidator,
  CfWorkerJsonSchemaValidator, and CfWorkerSchemaDraft from core/public —
  with the runtime classes unreachable, a type-only handle is dead surface.
- Reword the migration docs to describe backends by name (AJV /
  @cfworker/json-schema) instead of the now-internal class names.
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 51f42cd to e8006c0 Compare May 15, 2026 21:39
Comment thread packages/server/test/server/barrelClean.test.ts
mattzcarey added a commit that referenced this pull request May 19, 2026
- Update `.changeset/cfworker-out-of-barrel.md` to say the `./validators/cf-worker` subpath was removed (was: "reachable only via" that subpath, which is no longer true).
- Replace the impossible `import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core'` sample in `.changeset/support-standard-json-schema.md` with `fromJsonSchema` from `@modelcontextprotocol/server` and no explicit validator.
- Reword `@default` JSDoc on `ServerOptions`/`ClientOptions` `jsonSchemaValidator` from internal class names to backend names (AJV-backed / `@cfworker/json-schema`-backed) — these lines surface in published `.d.mts` IDE hover.
- Rework `.changeset/workerd-shim-vendors-cfworker.md` from a consumer vantage point: drop `core/public` references, state explicitly that the `./validators/cf-worker` subpath was removed and that the validator classes are no longer exported from client/server (not even as types).
- Delete the duplicate `describe('fromJsonSchema with default validator (server wrapper)')` block in `test/integration/test/standardSchema.test.ts`; its two tests are strict subsets of the preceding `Raw JSON Schema via fromJsonSchema` block (explicit-validator coverage already lives in the new `jsonSchemaValidatorOverride.test.ts` files).
- Document the `./validators/cf-worker` subpath removal in `docs/migration.md` and `docs/migration-SKILL.md` per repo policy for breaking changes.
Comment thread docs/migration-SKILL.md Outdated
Comment thread docs/migration.md
After PR #2088, end users can no longer import or construct
AjvJsonSchemaValidator / CfWorkerJsonSchemaValidator — client/server
bundle them via the runtime shim and expose only the jsonSchemaValidator
interface as the public extension point.

- Strip impossible `new AjvJsonSchemaValidator()` / `new CfWorkerJsonSchemaValidator()`
  snippets from JSDoc on the validation module, ajvProvider, cfWorkerProvider,
  and fromJsonSchema; mark the provider classes @internal.
- fromJsonSchema example now declares `validator: jsonSchemaValidator` and
  notes that consumers importing from server/client omit the second arg.
- Drop the type-only re-exports of AjvJsonSchemaValidator,
  CfWorkerJsonSchemaValidator, and CfWorkerSchemaDraft from core/public —
  with the runtime classes unreachable, a type-only handle is dead surface.
- Reword the migration docs to describe backends by name (AJV /
  @cfworker/json-schema) instead of the now-internal class names.
- Update `.changeset/cfworker-out-of-barrel.md` to say the `./validators/cf-worker` subpath was removed (was: "reachable only via" that subpath, which is no longer true).
- Replace the impossible `import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core'` sample in `.changeset/support-standard-json-schema.md` with `fromJsonSchema` from `@modelcontextprotocol/server` and no explicit validator.
- Reword `@default` JSDoc on `ServerOptions`/`ClientOptions` `jsonSchemaValidator` from internal class names to backend names (AJV-backed / `@cfworker/json-schema`-backed) — these lines surface in published `.d.mts` IDE hover.
- Rework `.changeset/workerd-shim-vendors-cfworker.md` from a consumer vantage point: drop `core/public` references, state explicitly that the `./validators/cf-worker` subpath was removed and that the validator classes are no longer exported from client/server (not even as types).
- Delete the duplicate `describe('fromJsonSchema with default validator (server wrapper)')` block in `test/integration/test/standardSchema.test.ts`; its two tests are strict subsets of the preceding `Raw JSON Schema via fromJsonSchema` block (explicit-validator coverage already lives in the new `jsonSchemaValidatorOverride.test.ts` files).
- Document the `./validators/cf-worker` subpath removal in `docs/migration.md` and `docs/migration-SKILL.md` per repo policy for breaking changes.
mattzcarey added a commit that referenced this pull request May 29, 2026
…orkers test

PR #2088 adds @cfworker/json-schema to noExternal so the validator is
bundled into the published @modelcontextprotocol/server tarball. The
Cloudflare Workers integration test was still installing the package
as a direct dep in the generated consumer package.json, which masked
any future re-externalization regression — wrangler would resolve the
bare import from the test's own install instead of failing.

Removing the dep turns the test into a true regression guard that the
bundle is genuinely self-contained, matching the migration docs.

Closes the last open review thread on #2088.
mattzcarey added a commit that referenced this pull request May 29, 2026
Restore the public entry points for the built-in JSON Schema validator
classes via symmetric subpaths so consumers can customize the bundled
backends without having to reimplement the entire 'jsonSchemaValidator'
interface:

- @modelcontextprotocol/{client,server}/validators/ajv
    exports AjvJsonSchemaValidator (was unreachable since #2088)
- @modelcontextprotocol/{client,server}/validators/cf-worker
    exports CfWorkerJsonSchemaValidator (was reachable on main, removed
    by #2088; restored here)

The named classes are intentionally NOT re-exported from the root barrel
(@modelcontextprotocol/server / @modelcontextprotocol/client). Re-exporting
either as a runtime value would pull the corresponding peer dep ('ajv'
or '@cfworker/json-schema') into every consumer's root index chunk,
defeating the purpose of the runtime shim's pay-only-for-what-you-use
default. Consumers who never customize get the validator transparently
via the shim; consumers who customize import from the subpath and
install the peer dep themselves.

The shim continues to bundle 'ajv' + 'ajv-formats' (Node) and
'@cfworker/json-schema' (workerd/browser) via tsdown noExternal so the
default code path remains zero-install. The barrel-clean regression
tests are tightened to match top-of-line bare imports only, so JSDoc
examples that reference 'from "ajv"' inside vendored chunks do not
trigger false positives.

The migration docs and changesets are rewritten to document the new
customization path.
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from f7b60a2 to ea0d8e0 Compare May 29, 2026 16:31
mattzcarey added a commit that referenced this pull request May 29, 2026
…orkers test

PR #2088 adds @cfworker/json-schema to noExternal so the validator is
bundled into the published @modelcontextprotocol/server tarball. The
Cloudflare Workers integration test was still installing the package
as a direct dep in the generated consumer package.json, which masked
any future re-externalization regression — wrangler would resolve the
bare import from the test's own install instead of failing.

Removing the dep turns the test into a true regression guard that the
bundle is genuinely self-contained, matching the migration docs.

Closes the last open review thread on #2088.
mattzcarey added a commit that referenced this pull request May 29, 2026
Restore the public entry points for the built-in JSON Schema validator
classes via symmetric subpaths so consumers can customize the bundled
backends without having to reimplement the entire 'jsonSchemaValidator'
interface:

- @modelcontextprotocol/{client,server}/validators/ajv
    exports AjvJsonSchemaValidator (was unreachable since #2088)
- @modelcontextprotocol/{client,server}/validators/cf-worker
    exports CfWorkerJsonSchemaValidator (was reachable on main, removed
    by #2088; restored here)

The named classes are intentionally NOT re-exported from the root barrel
(@modelcontextprotocol/server / @modelcontextprotocol/client). Re-exporting
either as a runtime value would pull the corresponding peer dep ('ajv'
or '@cfworker/json-schema') into every consumer's root index chunk,
defeating the purpose of the runtime shim's pay-only-for-what-you-use
default. Consumers who never customize get the validator transparently
via the shim; consumers who customize import from the subpath and
install the peer dep themselves.

The shim continues to bundle 'ajv' + 'ajv-formats' (Node) and
'@cfworker/json-schema' (workerd/browser) via tsdown noExternal so the
default code path remains zero-install. The barrel-clean regression
tests are tightened to match top-of-line bare imports only, so JSDoc
examples that reference 'from "ajv"' inside vendored chunks do not
trigger false positives.

The migration docs and changesets are rewritten to document the new
customization path.
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from ea0d8e0 to e6e3d33 Compare May 29, 2026 16:39
mattzcarey added a commit that referenced this pull request May 29, 2026
…orkers test

PR #2088 adds @cfworker/json-schema to noExternal so the validator is
bundled into the published @modelcontextprotocol/server tarball. The
Cloudflare Workers integration test was still installing the package
as a direct dep in the generated consumer package.json, which masked
any future re-externalization regression — wrangler would resolve the
bare import from the test's own install instead of failing.

Removing the dep turns the test into a true regression guard that the
bundle is genuinely self-contained, matching the migration docs.

Closes the last open review thread on #2088.
mattzcarey added a commit that referenced this pull request May 29, 2026
Restore the public entry points for the built-in JSON Schema validator
classes via symmetric subpaths so consumers can customize the bundled
backends without having to reimplement the entire 'jsonSchemaValidator'
interface:

- @modelcontextprotocol/{client,server}/validators/ajv
    exports AjvJsonSchemaValidator (was unreachable since #2088)
- @modelcontextprotocol/{client,server}/validators/cf-worker
    exports CfWorkerJsonSchemaValidator (was reachable on main, removed
    by #2088; restored here)

The named classes are intentionally NOT re-exported from the root barrel
(@modelcontextprotocol/server / @modelcontextprotocol/client). Re-exporting
either as a runtime value would pull the corresponding peer dep ('ajv'
or '@cfworker/json-schema') into every consumer's root index chunk,
defeating the purpose of the runtime shim's pay-only-for-what-you-use
default. Consumers who never customize get the validator transparently
via the shim; consumers who customize import from the subpath and
install the peer dep themselves.

The shim continues to bundle 'ajv' + 'ajv-formats' (Node) and
'@cfworker/json-schema' (workerd/browser) via tsdown noExternal so the
default code path remains zero-install. The barrel-clean regression
tests are tightened to match top-of-line bare imports only, so JSDoc
examples that reference 'from "ajv"' inside vendored chunks do not
trigger false positives.

The migration docs and changesets are rewritten to document the new
customization path.
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from e6e3d33 to 917cd4a Compare May 29, 2026 16:54
…orkers test

PR #2088 adds @cfworker/json-schema to noExternal so the validator is
bundled into the published @modelcontextprotocol/server tarball. The
Cloudflare Workers integration test was still installing the package
as a direct dep in the generated consumer package.json, which masked
any future re-externalization regression — wrangler would resolve the
bare import from the test's own install instead of failing.

Removing the dep turns the test into a true regression guard that the
bundle is genuinely self-contained, matching the migration docs.

Closes the last open review thread on #2088.
@mattzcarey
Copy link
Copy Markdown
Contributor Author

@claude review pls

Restore the public entry points for the built-in JSON Schema validator
classes via symmetric subpaths so consumers can customize the bundled
backends without having to reimplement the entire 'jsonSchemaValidator'
interface:

- @modelcontextprotocol/{client,server}/validators/ajv
    exports AjvJsonSchemaValidator (was unreachable since #2088)
- @modelcontextprotocol/{client,server}/validators/cf-worker
    exports CfWorkerJsonSchemaValidator (was reachable on main, removed
    by #2088; restored here)

The named classes are intentionally NOT re-exported from the root barrel
(@modelcontextprotocol/server / @modelcontextprotocol/client). Re-exporting
either as a runtime value would pull the corresponding peer dep ('ajv'
or '@cfworker/json-schema') into every consumer's root index chunk,
defeating the purpose of the runtime shim's pay-only-for-what-you-use
default. Consumers who never customize get the validator transparently
via the shim; consumers who customize import from the subpath and
install the peer dep themselves.

The shim continues to bundle 'ajv' + 'ajv-formats' (Node) and
'@cfworker/json-schema' (workerd/browser) via tsdown noExternal so the
default code path remains zero-install. The barrel-clean regression
tests are tightened to match top-of-line bare imports only, so JSDoc
examples that reference 'from "ajv"' inside vendored chunks do not
trigger false positives.

The migration docs and changesets are rewritten to document the new
customization path.
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 917cd4a to 0768977 Compare May 29, 2026 17:05
Comment thread packages/codemod/src/migrations/v1-to-v2/mappings/importMap.ts
v1 source code that imports built-in validators looks like:

  import { CfWorkerJsonSchemaValidator } from
    '@modelcontextprotocol/sdk/validation/cfworker-provider.js';

The v1-to-v2 codemod now rewrites this to the v2 subpath that ships
the named class, picking the right base package per file:

  import { CfWorkerJsonSchemaValidator } from
    '@modelcontextprotocol/{client,server}/validators/cf-worker';

Covers all six v1 paths users wrote in the wild:
  validation/ajv-provider.js, validation/ajv.js, validation/ajv
  validation/cfworker-provider.js, validation/cfworker.js, validation/cfworker
plus the (rarer) validation/index.js and validation/types.js barrels
which carry only the jsonSchemaValidator interface — those route to
the base client/server package, which already re-exports those types.

Resolution uses the same sibling-import + project-type heuristic as
the rest of the importPaths transform: if the file already imports
from sdk/client/* it routes to /client/validators/..., otherwise it
routes to /server/validators/..., otherwise it falls back to the
project type from package.json.

Adds a subpathSuffix field to ImportMapping so the existing
RESOLVE_BY_CONTEXT logic can append a subpath after picking the base.
Eight new tests cover all six v1 paths, both base packages, and the
usedPackages output. Verified against the agents repo (the real-world
v1 caller this PR is unblocking).
@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 0768977 to 99cf12f Compare May 29, 2026 18:22
@KKonstantinov KKonstantinov merged commit 16d13ab into main May 29, 2026
19 checks passed
@KKonstantinov KKonstantinov deleted the fix/server-cfworker-json-schema-shim branch May 29, 2026 18:39
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Thanks for the follow-up commits — the mockPaths transform now appends subpathSuffix (with test coverage), the validator subpaths are re-exposed on client/server, and the CF Workers integration test no longer pre-installs @cfworker/json-schema, which together address my earlier findings, and I found no new issues in this revision. That said, this PR reshapes the public validator API surface (new subpath exports, bundling/dts config, codemod mappings, migration docs), so it still warrants a maintainer's design-level sign-off rather than auto-approval.

Extended reasoning...

Overview

This revision (head 99cf12f) of PR #2088 spans 46 files: it bundles the default JSON Schema validator backends (AJV for Node, @cfworker/json-schema for workerd/browser) into the client/server runtime shims via noExternal, exposes customisation through new ./validators/{ajv,cf-worker} subpath exports that re-export the vendored Ajv/addFormats, demotes the validator classes to type-only on the core barrels, adds codemod mappings (subpathSuffix) for the v1 validation/* paths, and rewrites the migration docs, changesets, tests, and tsconfig path maps accordingly.

Changes since my last review

The latest commits respond directly to prior review threads: mockPaths.ts now appends mapping.subpathSuffix in its RESOLVE_BY_CONTEXT branch (mirroring importPaths.ts) and mockPaths.test.ts adds vi.mock / vi.doMock / jest.mock / dynamic-import coverage for the validator specifiers; the ./validators/ajv and ./validators/cf-worker subpaths exist on both published packages with matching exports/typesVersions/tsdown entries; and cloudflareWorkers.test.ts no longer pre-installs @cfworker/json-schema, so it now genuinely guards the bundling invariant. The bug-hunting pass on this revision surfaced no new findings.

Security risks

No security-sensitive surface is touched — no auth, crypto, or transport-session logic changes. The main risks are supply-chain/bundling-shaped (vendoring ajv/ajv-formats/@cfworker/json-schema into published dist chunks) and API-compatibility-shaped (root barrels now export the validator classes type-only), neither of which is a vulnerability per se.

Level of scrutiny

This is exactly the kind of PR the repo's review conventions reserve for human judgment: it adds new public subpath exports, changes what the root barrels export, alters the published bundle contents, and ships a migration story (docs + codemod) whose prose has already gone through several correction rounds (one previously-flagged docs/changeset thread about the peer-dep wording was resolved by a maintainer and I have not re-raised it). Minimalism and API-surface trade-offs here are maintainer calls, not something to shadow-approve.

Other factors

Test coverage for the new behavior is reasonable: barrel-cleanliness regression tests for the shims, validator-override tests on client and server, codemod transform tests for both import and mock paths, and the workerd end-to-end test. The maintainer is actively engaged on the PR, so this defer is primarily a confirmation that the latest round of fixes checks out from my side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants