Skip to content

Bundle automatic validator defaults in client/server shims#2088

Open
mattzcarey wants to merge 2 commits into
mainfrom
fix/server-cfworker-json-schema-shim
Open

Bundle automatic validator defaults in client/server shims#2088
mattzcarey wants to merge 2 commits into
mainfrom
fix/server-cfworker-json-schema-shim

Conversation

@mattzcarey
Copy link
Copy Markdown
Contributor

@mattzcarey mattzcarey commented May 14, 2026

Summary

  • Bundle both validator backends selected by client/server runtime shims: AJV for Node defaults, @cfworker/json-schema for browser/workerd defaults.
  • Remove explicit client/server validators/cf-worker subpath exports. Validator selection is automatic for normal users; advanced users can provide their own jsonSchemaValidator implementation.
  • Mark AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator @internal; drop their type-only re-exports from core/public so the runtime classes and their TypeScript type handles are both unreachable from @modelcontextprotocol/client / @modelcontextprotocol/server.
  • Rewrite .examples.ts files and JSDoc snippets in packages/core/ so they no longer demonstrate end-user code (new AjvJsonSchemaValidator(), new CfWorkerJsonSchemaValidator()) that the new surface makes impossible. fromJsonSchema's example now uses a declared jsonSchemaValidator and notes that consumers importing from server/client omit the second arg.
  • Add regression tests that built client/server shims do not leave bare imports for ajv, ajv-formats, or @cfworker/json-schema for consumers to resolve.
  • Update migration docs to say users do not need to install or import validator packages; describe runtime selection by backend name (AJV / @cfworker/json-schema) rather than the now-internal class names.

Why

Client and server choose runtime defaults via conditional _shims:

  • Node shim: AJV-backed validator
  • Browser/workerd shim: @cfworker/json-schema-backed validator

Because client/server make those default choices, consumers should not need to know about or install validator implementation dependencies. Those backends are now bundled into the shim chunks that select them. The implementation classes are also no longer part of the public surface — neither as runtime constructors nor as TypeScript types — because exposing a handle to a constructor consumers can't reach is purely confusing.

Impact

  • Client/server users: no extra validator install or validator import is needed. Node gets the bundled AJV default through the Node shim; browser/workerd gets the bundled cfworker validator through the browser/workerd shim.
  • Advanced users: custom validation is still possible by passing jsonSchemaValidator: myCustomValidator with their own implementation of the jsonSchemaValidator interface.
  • Published packages: packed client/server tarballs do not depend on @modelcontextprotocol/core, ajv, ajv-formats, or @cfworker/json-schema; those implementations are bundled where client/server need them.
  • Public surface: explicit concrete validator subpaths are removed from client/server, the runtime classes are @internal, and core/public no longer re-exports them as types. The supported customisation path is the jsonSchemaValidator interface (still exported from core/public and re-exported by client/server).

Follow-up for codemod reviewers

If this validator packaging change ships, the v1-to-v2 codemod should remove redundant manual SDK validator imports/configuration for the built-in AJV and Cloudflare Workers validators. Those validators are no longer exported from client/server (not even as types), and normal migrations should rely on automatic runtime defaults instead.

Examples the codemod should simplify/remove when they refer to the SDK built-ins:

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

new McpServer(info, {
  jsonSchemaValidator: new CfWorkerJsonSchemaValidator()
});

For custom user validators, the codemod should preserve the override:

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

Reviewer note: this PR intentionally makes built-in validator selection automatic for client/server users; codemod output should not teach users to import SDK concrete validators for the default case.

@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: e8006c0

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

This PR includes changesets to release 7 packages
Name Type
@modelcontextprotocol/core Minor
@modelcontextprotocol/client Patch
@modelcontextprotocol/server Patch
@modelcontextprotocol/node Patch
@modelcontextprotocol/express Patch
@modelcontextprotocol/fastify Patch
@modelcontextprotocol/hono Patch

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/client@2088

@modelcontextprotocol/server

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

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

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: e8006c0

@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 Outdated
Comment thread packages/codemod/src/bin/batchTest.ts Outdated
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 Outdated
@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 on lines 28 to 31
"types": "./dist/stdio.d.mts",
"import": "./dist/stdio.mjs"
},
"./validators/cf-worker": {
"types": "./dist/validators/cfWorker.d.mts",
"import": "./dist/validators/cfWorker.mjs"
},
"./_shims": {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nit: a few prose references to the removed validator paths survive — .changeset/cfworker-out-of-barrel.md:6 still says the validator is "reachable only via … the explicit @modelcontextprotocol/{server,client}/validators/cf-worker subpath … No public API change", packages/core/src/validators/ajvProvider.ts:36's @see still points at those same removed subpaths (this JSDoc is bundled into the published .d.mts), and .changeset/support-standard-json-schema.md:24-27 still shows import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core' + new AjvJsonSchemaValidator(), which is now a type-only export. Worth grepping for validators/cf-worker and updating these alongside the migration-doc rewrites so the next CHANGELOG and IDE hovers don't advertise paths this PR deletes.

Extended reasoning...

What the issue is

This PR removes the ./validators/cf-worker subpath from packages/{client,server}/package.json (and deletes both src/validators/cfWorker.ts files), and demotes AjvJsonSchemaValidator from a runtime re-export to export type in both core barrels. The PR updates the migration docs, the new changeset, and the JSDoc in packages/core/src/index.ts to match — but three pre-existing prose references to the old form survive untouched:

  1. .changeset/cfworker-out-of-barrel.md:6 — still reads: "The validator is now reachable only via the _shims conditional (workerd/browser) and the explicit @modelcontextprotocol/{server,client}/validators/cf-worker subpath, so consumers that don't opt into it no longer ship that code. No public API change." This changeset is not in .changeset/pre.json's consumed changesets array, so it is unreleased and will land in the same CHANGELOG version as this PR's workerd-shim-vendors-cfworker.md.
  2. packages/core/src/validators/ajvProvider.ts:36@see CfWorkerJsonSchemaValidatorfor an edge-runtime-compatible alternative (import from@modelcontextprotocol/server/validators/cf-workeror@modelcontextprotocol/client/validators/cf-worker). This file is not in the PR's changed-files list.
  3. .changeset/support-standard-json-schema.md:24-27import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core'; followed by new AjvJsonSchemaValidator(). After packages/core/src/index.ts:22 becomes export type { AjvJsonSchemaValidator }, that example is a TS error ("cannot be used as a value because it was exported using 'export type'"). This changeset is in pre.json (already applied to an alpha CHANGELOG), but in changesets pre-mode the .md persists and is re-aggregated into the final 2.0.0 CHANGELOG on changeset pre exit.

A repo-wide grep for validators/cf-worker confirms (1) and (2) are the only two surviving references to the removed subpath.

Why existing review feedback doesn't cover it

The earlier inline comment on packages/core/src/exports/public/index.ts:145 enumerated four doc sites that pointed at @modelcontextprotocol/core/... (docs/migration.md, docs/migration-SKILL.md, .changeset/workerd-shim-vendors-cfworker.md, and the JSDoc in packages/core/src/index.ts). The current revision reworked all four. None of the three locations above were on that list, so they were missed in the same cleanup pass — this is the REVIEW.md "Completeness" recurring catch ("when a PR replaces a pattern, grep the package for surviving instances of the old form").

Step-by-step proof

  1. This PR deletes "./validators/cf-worker" from packages/server/package.json exports + typesVersions and from packages/client/package.json, removes both src/validators/cfWorker.ts files, and drops them from both tsdown.config.ts entry arrays.
  2. changesets version runs on the next release. cfworker-out-of-barrel.md is not in pre.json's changesets[], so it is consumed alongside workerd-shim-vendors-cfworker.md. The generated packages/server/CHANGELOG.md for that version contains both entries: one says "reachable only via … /validators/cf-worker subpath … No public API change", the other says explicit validator subpaths are removed. A user reading the release notes gets directly contradictory guidance.
  3. tsdown bundles ajvProvider.ts's class JSDoc into dist/shimsNode.d.mts (it's re-exported as DefaultJsonSchemaValidator) and into the root .d.mts (type-only). A consumer hovers DefaultJsonSchemaValidator or AjvJsonSchemaValidator in their IDE and sees @see … import from @modelcontextprotocol/server/validators/cf-worker. They try import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker'ERR_PACKAGE_PATH_NOT_EXPORTED.
  4. On changeset pre exit, support-standard-json-schema.md is re-emitted into the stable 2.0.0 CHANGELOG. A user copies the fromJsonSchema example, gets 'AjvJsonSchemaValidator' cannot be used as a value because it was exported using 'export type' (and @modelcontextprotocol/core is private: true, so the import path was already wrong for external consumers even before this PR).

Impact

Doc-only; no runtime effect. The cfworker-out-of-barrel.md case is the most concrete because it produces self-contradicting published release notes in the very next version bump. The ajvProvider.ts @see surfaces in end-user IDE tooltips. The support-standard-json-schema.md example was already broken for external users (private package), so this PR just makes it slightly more broken; still worth fixing while validator docs are being touched.

How to fix

  • .changeset/cfworker-out-of-barrel.md: either delete it (its purpose is subsumed by workerd-shim-vendors-cfworker.md) or rewrite line 6 to drop the /validators/cf-worker subpath reference and the "No public API change" claim.
  • packages/core/src/validators/ajvProvider.ts:36: change the @see to reference automatic runtime selection (matching the updated packages/core/src/index.ts JSDoc), or simply @see {@link CfWorkerJsonSchemaValidator} without an import path.
  • .changeset/support-standard-json-schema.md:23-28: rewrite the example to import { fromJsonSchema } from '@modelcontextprotocol/server' and drop the explicit new AjvJsonSchemaValidator() argument, matching the updated docs/migration.md guidance.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks — ajvProvider.ts:36's @see is now fixed. The two changeset files are still untouched, though:

  • .changeset/cfworker-out-of-barrel.md:6 still says the validator is "reachable only via … the explicit @modelcontextprotocol/{server,client}/validators/cf-worker subpath … No public API change". This changeset is unreleased and will land in the same CHANGELOG version as workerd-shim-vendors-cfworker.md, producing directly contradictory release notes. Easiest fix is to delete it (its purpose is now subsumed by the new changeset).
  • .changeset/support-standard-json-schema.md:24-27 still shows import { fromJsonSchema, AjvJsonSchemaValidator } from '@modelcontextprotocol/core' + new AjvJsonSchemaValidator(), which is now a type-only export. Suggest rewriting to import { fromJsonSchema } from '@modelcontextprotocol/server' and dropping the explicit validator arg, matching the updated docs/migration.md example.

(Repo-wide grep for validators/cf-worker now matches only cfworker-out-of-barrel.md, confirming the ajvProvider.ts reference is gone.)

@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 57c3a0b to a2b954b Compare May 14, 2026 11:46
Comment on lines 385 to 393
test('should register tool with raw JSON Schema input', async () => {
const inputSchema = fromJsonSchema<{ name: string }>(
{ type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
validator
);
const inputSchema = serverFromJsonSchema<{ name: string }>({
type: 'object',
properties: { name: { type: 'string' } },
required: ['name']
});

mcpServer.registerTool('greet', { inputSchema }, async ({ name }) => ({
content: [{ type: 'text', text: `Hello, ${name}!` }]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nit: this rewrite makes describe('Raw JSON Schema via fromJsonSchema') and describe('fromJsonSchema with default validator (server wrapper)') exercise the same code path — both now call serverFromJsonSchema(...) with no explicit validator on the same {name:string} / {count:number} schemas, so the second block is a strict subset of the first (the first additionally asserts the tools/list inputSchema shape). The explicit-validator coverage that block 1 used to provide moved to the new packages/{client,server}/test/**/jsonSchemaValidatorOverride.test.ts files, so the simplest cleanup is to delete the second describe block.

Extended reasoning...

What changed

Before this PR, the two adjacent describe blocks in standardSchema.test.ts covered distinct axes:

  • describe('Raw JSON Schema via fromJsonSchema') built schemas via core's fromJsonSchema(schema, new AjvJsonSchemaValidator()) — i.e. an explicit validator instance passed by the caller.
  • describe('fromJsonSchema with default validator (server wrapper)') built schemas via serverFromJsonSchema(schema) with no validator argument — i.e. the server wrapper's runtime-selected default.

This PR removes AjvJsonSchemaValidator and core fromJsonSchema from the file's imports and rewrites block 1 to use serverFromJsonSchema with no validator argument (and renames its second test from 'should reject invalid input via AJV validation''…via default validation'). After the rewrite, both blocks call exactly the same function with the same default-validator semantics.

Side-by-side after the diff

Block 1: "Raw JSON Schema via fromJsonSchema" Block 2: "fromJsonSchema with default validator (server wrapper)"
Test 1 schema serverFromJsonSchema<{name:string}>({…name…}) serverFromJsonSchema<{name:string}>({…name…})
Test 1 assertions tools/list inputSchema shape + tools/call returns Hello, World! tools/call returns Hello, World!
Test 2 schema serverFromJsonSchema({…count:number…}) serverFromJsonSchema({…count:number…})
Test 2 assertions count:'not a number'isError + 'Input validation error' identical

Block 2 is now a strict subset of block 1 — the only delta is block 1's extra tools/list toMatchObject assertion. The two "reject invalid input" tests are functionally identical.

Why nothing was actually lost (addressing the refutation)

One reviewer argued this isn't worth flagging because (a) the blocks aren't strictly identical and (b) the explicit-validator coverage didn't disappear. Both points are correct and are why this is a nit, not a defect:

  • The rewrite was forced by this PR's own change — AjvJsonSchemaValidator is no longer a runtime export from @modelcontextprotocol/core's root barrel, so new AjvJsonSchemaValidator() here would have required rewiring to the /validators/ajv subpath (as elicitation.test.ts does in this same diff).
  • The explicit-override path that block 1 used to cover did move, not vanish: this PR adds packages/server/test/server/jsonSchemaValidatorOverride.test.ts and packages/client/test/client/jsonSchemaValidatorOverride.test.ts, each containing a 'fromJsonSchema uses an explicitly supplied custom validator' test with a RecordingValidator that asserts the exact schema and value passed through. That's stronger coverage than the old AJV smoke test.

So no coverage regression — the only residue is that this file now contains two describe blocks doing the same thing, which is the kind of test-hygiene cleanup that's cheap to do while the file is already being touched.

Step-by-step proof

  1. Pre-PR line 8 imports AjvJsonSchemaValidator, fromJsonSchema from core; block 1 opens with const validator = new AjvJsonSchemaValidator() and calls fromJsonSchema(schema, validator).
  2. Diff replaces line 8 with import { InMemoryTransport } from '@modelcontextprotocol/core' (dropping both symbols), deletes the validator const, and rewrites both fromJsonSchema(schema, validator) calls to serverFromJsonSchema({...}).
  3. serverFromJsonSchema was already imported on line 9 and is what block 2 (lines ~431-467, untouched by this diff) already uses.
  4. Result: block 1 test 1 ≡ block 2 test 1 minus the tools/list assertion; block 1 test 2 ≡ block 2 test 2 (tool name 'double' vs 'double-default' is the only difference).

Suggested fix

Delete describe('fromJsonSchema with default validator (server wrapper)') (lines ~431-467) — its tests are now fully covered by the rewritten block above it. Alternatively, fold block 1's tools/list assertion into block 2 and delete block 1; either way one block goes.

Comment thread packages/core/src/index.ts Outdated
Comment on lines +58 to +69
test('runtime shims vendor default validator backends instead of requiring consumers to install them', () => {
for (const shim of ['shimsNode.mjs', 'shimsWorkerd.mjs']) {
const entry = join(distDir, shim);
expect(readFileSync(entry, 'utf8')).not.toMatch(VALIDATOR_BACKEND_IMPORT);

for (const chunk of chunkImportsOf(entry)) {
expect({ chunk, content: readFileSync(chunk, 'utf8') }).not.toEqual(
expect.objectContaining({ content: expect.stringMatching(VALIDATOR_BACKEND_IMPORT) })
);
}
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nit (pre-existing): this regression test only covers .mjs, but the published .d.mts still bare-imports ajv — building packages/server emits dist/ajvProvider-*.d.mts with import { Ajv } from "ajv"; (for constructor(ajv?: Ajv)), transitively pulled in by dist/index.d.mts and dist/shimsNode.d.mts, and dist/types-*.d.mts likewise has import { JSONSchema } from "json-schema-typed";. Neither ajv nor json-schema-typed is in server/client dependencies/peerDependencies, so a skipLibCheck: false consumer who follows the new docs/migration-SKILL.md:524 instruction "Do not install ajv, ajv-formats, or @cfworker/json-schema" gets TS2307: Cannot find module 'ajv'. Either extend the scan to dist/*.d.mts and replace the Ajv ctor-arg type with a local structural type (matching what cfWorkerProvider already does — its .d.mts leaks no @cfworker/json-schema import), or add a skipLibCheck caveat to the migration-SKILL line. Same applies to packages/client/test/client/barrelClean.test.ts.

Extended reasoning...

What the issue is

This PR adds a regression test asserting that the runtime shim .mjs files (and their .mjs chunk imports) contain no bare from 'ajv'|'ajv-formats'|'@cfworker/json-schema' import. That correctly enforces the runtime half of the "users do not need to install validator packages" goal. But the published type declarations still leak a bare ajv import that this test does not cover, and this PR's new migration-doc line tells users not to install ajv.

Building packages/server at this PR's HEAD produces:

  • dist/ajvProvider-BD030R9d.d.mts:2import { Ajv } from "ajv"; (needed for constructor(ajv?: Ajv) on line 39).
  • dist/index.d.mts:3 and dist/shimsNode.d.mts:1 both import that chunk, so any consumer importing anything from @modelcontextprotocol/server has TypeScript load a .d.mts that does import { Ajv } from "ajv".
  • dist/types-YaX0ZWcZ.d.mts:1import { JSONSchema } from "json-schema-typed";.

Neither ajv nor json-schema-typed appears in packages/server/package.json dependencies or peerDependenciesajv is added only to devDependencies in this PR, and json-schema-typed is only in private core's deps. By contrast, dist/cfWorkerProvider-*.d.mts leaks no @cfworker/json-schema import because its constructor uses a locally-declared CfWorkerSchemaDraft type — so the AJV side is asymmetrically worse and the fix pattern already exists in-tree.

Why existing code doesn't catch it

The new VALIDATOR_BACKEND_IMPORT check iterates only ['shimsNode.mjs', 'shimsWorkerd.mjs'], and chunkImportsOf() follows only ./*.mjs relative imports — .d.mts files are never visited. tsdown's noExternal bundles the runtime code but does not inline external type references in the DTS output, so the Ajv parameter type survives as a bare import.

Why this is worth a nit on this PR despite being pre-existing

The .d.mts leak itself is pre-existing — the parent commit 2c0c481 also emits from "ajv" in dist/index-*.d.mts — so it is not a regression. What this PR newly adds is docs/migration-SKILL.md:524: "Do not install ajv, ajv-formats, or @cfworker/json-schema; client/server bundle the runtime-selected defaults." That instruction, taken at face value by a consumer with "skipLibCheck": false, produces a compile error on the published artifacts. This PR also touches ajvProvider.ts directly (the @see line), so the file in question is in-diff. The new test gives a (mild) false sense that the "no validator install needed" goal is fully enforced — it covers runtime but not types.

This is not a duplicate of the open inline comments: #3241089399 covers stale prose referencing the removed /validators/cf-worker subpath, and #3241222796 covers stale @example blocks in core/src/index.ts. Neither mentions the .d.mts bare-import leak or the skipLibCheck interaction.

Step-by-step proof

  1. A consumer creates a fresh project with "skipLibCheck": false in tsconfig.json and runs npm install @modelcontextprotocol/server.
  2. Following the new docs/migration-SKILL.md:524 guidance, they do not install ajv, ajv-formats, or @cfworker/json-schema.
  3. They write import { McpServer } from '@modelcontextprotocol/server'; and run tsc.
  4. TypeScript resolves node_modules/@modelcontextprotocol/server/dist/index.d.mts, which on line 3 does import … from './ajvProvider-BD030R9d.mjs'; → resolves ajvProvider-BD030R9d.d.mts.
  5. Line 2 of that file is import { Ajv } from "ajv";. ajv is not in node_modules (only zod is a runtime dependency of @modelcontextprotocol/server).
  6. tsc fails with error TS2307: Cannot find module 'ajv' or its corresponding type declarations. (and likewise TS2307 for json-schema-typed via types-*.d.mts).
  7. The new barrelClean.test.ts regression test passes throughout because it never reads *.d.mts.

Impact

Low — most TypeScript projects set skipLibCheck: true (it's the tsc --init default), so the failure mode is narrow. Runtime behavior is correct: the bundled .mjs chunks contain the AJV/cfworker code and no consumer install is needed to run. The concrete harm is doc-vs-artifact contradiction for the skipLibCheck:false minority, plus a test that enforces only half of the stated goal. The json-schema-typed half is clearly out-of-scope for this PR; mentioned for completeness.

How to fix

Either of:

  1. Close the leak — in packages/core/src/validators/ajvProvider.ts, replace the constructor(ajv?: Ajv) parameter type with a locally-declared structural type (or unknown/an internal interface), mirroring cfWorkerProvider.ts's CfWorkerSchemaDraft approach so the emitted .d.mts no longer needs import { Ajv } from "ajv". Optionally extend this test (and the client twin) to also scan dist/*.d.mts for VALIDATOR_BACKEND_IMPORT so the invariant is enforced for types as well as runtime.
  2. Soften the doc — add a brief caveat to docs/migration-SKILL.md:524 (and the corresponding docs/migration.md paragraph) noting that projects with skipLibCheck: false may still need ajv installed for type resolution until the declaration leak is closed.

Comment on lines +7 to +11
Make validator backends symmetrical in core and bundle automatic defaults in client/server runtime shims.

Core no longer re-exports concrete validator providers as runtime values from the root/public barrels. AJV/AJV formats and `@cfworker/json-schema` are optional peer backends behind explicit core validator provider subpaths, used internally by client/server shims.

Client/server continue to select defaults automatically: Node shims use AJV, while browser/workerd shims use `@cfworker/json-schema`. Those backends are bundled into the shim chunks that select them, so users do not need to install validator packages or import explicit validators for default behavior. Advanced users can still pass their own `jsonSchemaValidator` implementation.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nit: this changeset describes the core barrel change and the shim bundling, but never says that the ./validators/cf-worker subpath export was removed from @modelcontextprotocol/{client,server} — line 11's "do not need to … import explicit validators" reads as a convenience, not a removal. Worth one explicit sentence here, especially since the open comment on packages/server/package.json:31 suggests deleting .changeset/cfworker-out-of-barrel.md, which would leave this as the only changeset covering the subpath and the removal entirely undocumented in the generated CHANGELOG.

Extended reasoning...

What the issue is

This PR removes a public subpath export from two published packages: ./validators/cf-worker is deleted from the exports and typesVersions maps in packages/{client,server}/package.json, both src/validators/cfWorker.ts re-export files are deleted, and the entry is dropped from both tsdown.config.ts arrays. The previously-documented pattern import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker' now resolves to ERR_PACKAGE_PATH_NOT_EXPORTED.

The PR's own changeset, .changeset/workerd-shim-vendors-cfworker.md, describes two things: (a) core no longer re-exporting concrete validator providers as runtime values from its barrels, and (b) client/server bundling default backends into their shim chunks. Line 11 says "users do not need to install validator packages or import explicit validators for default behavior" — but that frames explicit imports as no longer necessary, not as no longer possible. Nowhere does the changeset state that the ./validators/cf-worker subpath was removed from client/server.

Why this isn't covered by existing comments

The still-open inline comment on packages/server/package.json:31 is about other prose that still references the removed subpath (.changeset/cfworker-out-of-barrel.md, ajvProvider.ts:36's @see, .changeset/support-standard-json-schema.md). This finding is the inverse: the PR's own new changeset fails to announce the removal it introduces.

The two interact: that open comment's first suggested fix is "delete cfworker-out-of-barrel.md (its purpose is subsumed by workerd-shim-vendors-cfworker.md)". If the author follows that suggestion as-is, workerd-shim-vendors-cfworker.md becomes the only changeset touching this area — and it doesn't mention the subpath removal, so the generated CHANGELOG would contain no record that @modelcontextprotocol/{client,server}/validators/cf-worker ever went away.

The resolved comment on exports/public/index.ts:145 did raise the patch-vs-breaking concern, but for the earlier export type change. The author's resolution expanded the breaking surface (it removed the subpath entirely instead of adding a parallel one) without revisiting the changeset prose. The bump-level concern itself is muted by 2.0.0-alpha.2 pre-release status, so the actionable residue is just the missing prose.

Step-by-step proof

  1. A consumer on @modelcontextprotocol/server@2.0.0-alpha.2 has import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker' — the exact pattern the pre-PR docs/migration.md and docs/migration-SKILL.md documented.
  2. They upgrade to the next alpha containing this PR. packages/server/package.json no longer has "./validators/cf-worker" in exports; Node throws ERR_PACKAGE_PATH_NOT_EXPORTED.
  3. They open the generated packages/server/CHANGELOG.md for that version. The entry from workerd-shim-vendors-cfworker.md reads: "Client/server continue to select defaults automatically … users do not need to install validator packages or import explicit validators for default behavior. Advanced users can still pass their own jsonSchemaValidator implementation."
  4. Nothing in that text says the subpath was removed. The consumer has to infer the API removal from a sentence about defaults, or grep the diff.
  5. If .changeset/cfworker-out-of-barrel.md is also deleted per the open comment's suggestion, there is no CHANGELOG entry mentioning /validators/cf-worker at all.

Impact

Doc-only; no runtime effect. The PR description and updated migration guides do call this out ("Public surface: explicit concrete validator subpaths are removed from client/server"), so the gap is specifically in the changeset → CHANGELOG path. Filed as a nit given the alpha pre-release context and that three related doc nits are already open — but it's a one-line addition while the changeset is being touched anyway.

How to fix

Add one sentence to .changeset/workerd-shim-vendors-cfworker.md, e.g. after line 11:

The explicit ./validators/cf-worker subpath export has been removed from @modelcontextprotocol/client and @modelcontextprotocol/server; rely on automatic runtime selection or pass a custom jsonSchemaValidator.

(If .changeset/cfworker-out-of-barrel.md is kept and rewritten per the other open comment instead of deleted, that would also cover it — either location works as long as one changeset states the removal.)

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.
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.
* requests against the requested schema.
*
* @default {@linkcode DefaultJsonSchemaValidator} ({@linkcode index.AjvJsonSchemaValidator | AjvJsonSchemaValidator} on Node.js, `CfWorkerJsonSchemaValidator` on Cloudflare Workers)
* @default Runtime-selected validator (`AjvJsonSchemaValidator` on Node.js, `CfWorkerJsonSchemaValidator` on browser/workerd runtimes)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nit: commit 51f42cd reworded user-facing prose to "describe backends by name (AJV / @cfworker/json-schema) instead of the now-internal class names", but skipped the two @default lines this PR's earlier commit added — this one and the identical packages/client/src/client/client.ts:164 still say "AjvJsonSchemaValidator on Node.js, CfWorkerJsonSchemaValidator on browser/workerd". Both surface verbatim in the published .d.mts IDE hover for {Server,Client}Options.jsonSchemaValidator, naming classes the same commit just marked @internal and removed from core/public. Suggest matching the migration-doc phrasing, e.g. @default Runtime-selected validator (AJV-backed on Node.js, @cfworker/json-schema-backed on browser/workerd runtimes).

Extended reasoning...

What the issue is

Commit 51f42cd (the second commit in this PR) is an explicit doc-cleanup pass whose message says: "Reword the migration docs to describe backends by name (AJV / @cfworker/json-schema) instead of the now-internal class names." It applies that rewording to docs/migration.md:903-904 ("Node.js → AjvJsonSchemaValidator" → "Node.js → AJV"), docs/migration-SKILL.md:503-504, the @module validation JSDoc in packages/core/src/index.ts, the changeset, and the class JSDoc in both ajvProvider.ts and cfWorkerProvider.ts (where it also adds @internal and removes the classes from core/public entirely — "not even as types" per the changeset).

But git show --stat 51f42cd confirms it does not touch packages/server/src/server/server.ts or packages/client/src/client/client.ts. Those two files were last modified by this PR's earlier commit a2b954b, which rewrote both @default lines to:

@default Runtime-selected validator (AjvJsonSchemaValidatoron Node.js,CfWorkerJsonSchemaValidator on browser/workerd runtimes)

So the cleanup commit established a convention (refer to backends by library name, not by now-@internal class name) and applied it everywhere except two lines this same PR had just added. This is the REVIEW.md "Completeness" recurring catch — when a PR replaces a pattern, two surviving instances of the old form remain in lines the PR itself introduced.

Why existing comments don't cover it

None of the open inline comments mention the ServerOptions/ClientOptions @default JSDoc:

  • #3241089399 / #3241246611 on packages/server/package.json:31 cover .changeset/cfworker-out-of-barrel.md, .changeset/support-standard-json-schema.md, and the (now-fixed) ajvProvider.ts:36 @see.
  • #3241222796 on core/src/index.ts covered the (now-fixed) @example blocks below the @module validation prose.
  • #3241478258 on the changeset covers the missing subpath-removal announcement.
  • #3241478255 on barrelClean.test.ts covers the .d.mts ajv import leak.

The two @default lines contain neither validators/cf-worker nor an import path, so the greps suggested in those comments would not surface them.

Why it matters (and why it's only a nit)

These @default lines surface verbatim in the published dist/index.d.mts IDE hover for ServerOptions.jsonSchemaValidator / ClientOptions.jsonSchemaValidator — the primary user-facing override option this PR is documenting. After this PR, AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator are @internal, removed from core/public (exports/public/index.ts:144-146 now has only a comment where the exports used to be), and per the new ajvProvider.ts JSDoc "cannot [be] import[ed] from @modelcontextprotocol/client or @modelcontextprotocol/server". A user hovering the option therefore sees class names they cannot import, reference, or find documented anywhere.

The counter-argument is that these are plain backticks (descriptive prose, not {@link} references), so nothing is broken — and naming the concrete implementation in a @default tag is arguably useful for stack-trace recognition. That's fair, and is why this is at the low end of nit-worthiness. But the analogous purely-descriptive prose in docs/migration-SKILL.md:503-504 was changed by 51f42cd for exactly this reason, so these two lines are a straightforward miss in the same pass rather than a deliberate exception.

Step-by-step proof

  1. Commit a2b954b (this PR) rewrites packages/server/src/server/server.ts:86 and packages/client/src/client/client.ts:164 to @default Runtime-selected validator (AjvJsonSchemaValidatoron Node.js,CfWorkerJsonSchemaValidator on browser/workerd runtimes).
  2. Commit 51f42cd (this PR) marks both classes @internal, drops them from core/public, and rewrites every other user-facing reference from class names to backend names (AJV / @cfworker/json-schema). Its file list does not include server.ts or client.ts.
  3. tsdown bundles the ServerOptions/ClientOptions JSDoc into packages/{server,client}/dist/index.d.mts. A consumer hovers jsonSchemaValidator in their IDE and sees @default … AjvJsonSchemaValidator … CfWorkerJsonSchemaValidator ….
  4. They search the package surface for either name: @modelcontextprotocol/server exports neither (root barrel re-exports core/public, which dropped them; the /validators/cf-worker subpath is removed). The migration guide they consult says "AJV" / "@cfworker/json-schema", not the class names. Mild dead-end.

Impact

Doc-only; no runtime effect. Two-line fix in two files already in this PR's diff, cheap to fold into the same cleanup pass that addresses the other open doc nits.

How to fix

Reword both @default lines to match the convention 51f42cd applied elsewhere, e.g.:

* @default Runtime-selected validator (AJV-backed on Node.js, `@cfworker/json-schema`-backed on browser/workerd runtimes)

at packages/server/src/server/server.ts:86 and packages/client/src/client/client.ts:164.


Client/server continue to select defaults automatically: Node shims use AJV, while browser/workerd shims use `@cfworker/json-schema`. Those backends are bundled into the shim chunks that select them, so users do not need to install validator packages or import explicit validators for default behavior. Advanced users can still pass their own `jsonSchemaValidator` implementation.

`AjvJsonSchemaValidator` and `CfWorkerJsonSchemaValidator` are now `@internal` and no longer surface from `@modelcontextprotocol/core/public` (not even as types). The `jsonSchemaValidator` interface remains the public extension point for custom validators. Example JSDoc snippets no longer demonstrate direct validator instantiation.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 nit: this new sentence (and line 9's "root/public barrels") will be emitted into the published @modelcontextprotocol/{client,server} CHANGELOGs, but readers of those CHANGELOGs have never seen @modelcontextprotocol/core/public — core is private: true and the migration docs explicitly tell users not to import from it. Since this paragraph is already being reworked per the open comment on line 11, suggest phrasing it from the consumer's vantage point, e.g. "AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator are now @internal and no longer exported from @modelcontextprotocol/client or @modelcontextprotocol/server (not even as types)".

Extended reasoning...

What the issue is

Line 13 of .changeset/workerd-shim-vendors-cfworker.md was added in head commit 51f42cd (the docs-alignment pass) and reads:

AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator are now @internal and no longer surface from @modelcontextprotocol/core/public (not even as types).

The changeset front-matter lists '@modelcontextprotocol/client': patch and '@modelcontextprotocol/server': patch, so changesets will copy this prose verbatim into packages/client/CHANGELOG.md and packages/server/CHANGELOG.md on the next version bump. But @modelcontextprotocol/core/public is an internal curated-barrel subpath: packages/core/package.json:3 has "private": true, CLAUDE.md describes core as "only consumed by sibling packages within the monorepo", and docs/migration.md (updated in this same PR) tells users "Do not import from @modelcontextprotocol/core directly — it is an internal package." An external consumer reading the client or server CHANGELOG has no frame of reference for "core/public" — what they can observe is that these symbols are no longer exported from the package they actually installed. Line 9 has the same issue with "root/public barrels".

Why this isn't covered by existing open comments

The open inline comment #3241478258 on line 11 is about missing content — the changeset never states that the ./validators/cf-worker subpath was removed from client/server. This finding is about present content using internal terminology. Crucially, line 13 was added in commit 51f42cd after #3241478258 was posted (2026-05-14T12:57:53Z), so the author has not yet received feedback on it. The two issues live in adjacent sentences and combine naturally into one rewrite, which is why the suggested fix is framed as a fold-in rather than a standalone demand.

Addressing the counter-arguments

One reviewer argued this is subjective style, that line 9 already has the same jargon and survived review, and that with 5+ open comments a separate wording nit is noise. Taking each:

  • "Line 9 already says 'root/public barrels' and survived review" — line 9 has the same problem and is named in the fix. It "surviving" earlier rounds isn't an endorsement: the changeset has been substantially rewritten across this PR's revisions (it started as a server-only shim note), and the author is currently editing this exact paragraph in response to #3241478258. Now is the cheapest moment to flag both lines.
  • "Should be a sub-point of the line-11 thread, not a separate comment" — fair, and the comment is written to read that way ("since this paragraph is already being reworked per the open comment on line 11…"). But #3241478258 cannot literally cover line 13 because line 13 didn't exist when it was posted; anchoring on line 13 makes the new prose the subject.
  • "The statement is accurate, just unfamiliar terminology" — agreed it's accurate from the monorepo's perspective, which is exactly the mismatch: the CHANGELOG audience is outside the monorepo. The user-observable fact ("no longer exported from @modelcontextprotocol/{client,server}") is equally accurate and is what a reader can verify against their own node_modules.
  • "Not egregious" — agreed; hence nit, not a blocker.

Step-by-step proof

  1. Front-matter at .changeset/workerd-shim-vendors-cfworker.md:1-5 lists @modelcontextprotocol/client and @modelcontextprotocol/server. On changeset version, the body (lines 7-13) is appended to both packages/client/CHANGELOG.md and packages/server/CHANGELOG.md.
  2. A consumer on @modelcontextprotocol/server@2.0.0-alpha.2 who previously wrote import { AjvJsonSchemaValidator } from '@modelcontextprotocol/server' upgrades and gets a TS error.
  3. They open node_modules/@modelcontextprotocol/server/CHANGELOG.md and read: "…no longer surface from @modelcontextprotocol/core/public…".
  4. They have never imported from @modelcontextprotocol/core/public. npm ls @modelcontextprotocol/core shows nothing (it's private: true, bundled into server, not a dependency). The migration guide they were pointed at says not to import from core. The CHANGELOG line doesn't tell them what changed in the package they installed.
  5. The consumer-observable equivalent — "no longer exported from @modelcontextprotocol/client or @modelcontextprotocol/server" — is what packages/core/src/validators/ajvProvider.ts:28-29 and cfWorkerProvider.ts:26-27 (both rewritten in this PR) already say in their @internal JSDoc.

Impact

Doc-only; no runtime effect. Filed as a nit because (a) alpha pre-release, (b) the statement is technically true, just framed from the wrong vantage point, and (c) the fix is a one-clause reword in a file that's already being edited per #3241478258.

How to fix

Reword line 13 (and optionally tighten line 9) to speak in terms of the published packages, e.g.:

AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator are now @internal and no longer exported from @modelcontextprotocol/client or @modelcontextprotocol/server (not even as types). The jsonSchemaValidator interface remains the public extension point for custom validators.

This also dovetails with #3241478258's request to state the ./validators/cf-worker subpath removal — both edits land in the same paragraph.

@mattzcarey mattzcarey force-pushed the fix/server-cfworker-json-schema-shim branch from 51f42cd to e8006c0 Compare May 15, 2026 21:39
);
}
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Follow-up: after e8006c0 dropped AjvJsonSchemaValidator/CfWorkerJsonSchemaValidator from core/public entirely, rebuilt dist/index.d.mts no longer imports the ajvProvider-*.d.mts chunk — the from "ajv" leak is now reachable only via dist/shimsNode.d.mts (the underscore-prefixed internal _shims subpath, which the rewritten migration docs no longer tell users to import). So the headline failure mode above ("a skipLibCheck:false consumer who imports McpServer from the root entry gets TS2307: Cannot find module 'ajv'") no longer reproduces, and the suggested Ajv ctor-arg rewrite would now benefit essentially nobody. The only surviving root-entry .d.mts leak is json-schema-typed, which this comment already calls out-of-scope — so this thread can probably be resolved (or narrowed to json-schema-typed). Same applies to packages/client.

Extended reasoning...

What changed since this comment was posted

Inline comment #3241478255 (posted 2026-05-14T12:57) states that "dist/index.d.mts:3 and dist/shimsNode.d.mts:1 both import that chunk" (the ajvProvider-*.d.mts chunk containing import { Ajv } from "ajv"), and concludes that a skipLibCheck:false consumer who follows docs/migration-SKILL.md:524 and imports McpServer from @modelcontextprotocol/server will hit TS2307: Cannot find module 'ajv'. That was accurate at the revision the comment was filed against.

HEAD commit e8006c0 (the rebased 51f42cd referenced in the 15:09 comments) subsequently dropped AjvJsonSchemaValidator, CfWorkerJsonSchemaValidator, and CfWorkerSchemaDraft from core/public entirely — not even as types (packages/core/src/exports/public/index.ts:144-146 now contains only an explanatory comment where the exports were). packages/server/src/index.ts:52 re-exports core/public, and DefaultJsonSchemaValidator is consumed in server.ts only as a runtime value (never in an exported type signature), so tsdown's DTS bundler no longer has a reason to pull the ajvProvider chunk into the root entry's .d.mts graph.

Verified at HEAD

Rebuilding packages/server at e8006c0 and grepping the emitted declarations:

$ grep -l 'ajvProvider\|from "ajv"' packages/server/dist/*.d.mts
packages/server/dist/ajvProvider-ClUAHE10.d.mts
packages/server/dist/shimsNode.d.mts

dist/index.d.mts now imports only ./index-dAsK-dK1.mjs (whose .d.mts imports only zod/v4), ./types-YaX0ZWcZ.mjs (whose .d.mts imports json-schema-typed), and zod/v4. The ajvProvider-*.d.mts chunk is reachable only via dist/shimsNode.d.mts, which backs the ./_shims subpath. packages/client/dist shows the same pattern.

Why the open comment is now mostly stale

  • Headline failure no longer reproduces. TypeScript only loads .d.ts files reachable from the resolved entry. Since ajvProvider-*.d.mts is unreachable from index.d.mts, a skipLibCheck:false consumer who writes import { McpServer } from '@modelcontextprotocol/server' and follows the "do not install ajv" instruction at docs/migration-SKILL.md:524 no longer hits TS2307 for ajv.
  • The suggested fix is now near-zero-value. The comment recommends replacing the constructor(ajv?: Ajv) parameter type with a local structural type so the emitted .d.mts doesn't need import { Ajv } from "ajv". After e8006c0 that rewrite would benefit only consumers who import from @modelcontextprotocol/server/_shims — an underscore-prefixed internal export that this PR's migration-doc rewrite explicitly removed from the "Access validators explicitly" section (the old import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/server/_shims' line is gone).
  • The surviving root-entry leak is json-schema-typed (via types-*.d.mtsJsonSchemaType = JSONSchema.Interface), which #3241478255 already mentions but explicitly labels "clearly out-of-scope for this PR".

Step-by-step proof

  1. At the revision #3241478255 was posted against, core/public exported AjvJsonSchemaValidator (as a type) and CfWorkerSchemaDraft. Because the server root barrel re-exports core/public, tsdown emitted those types into dist/index.d.mts's graph, which transitively pulled in ajvProvider-*.d.mts and its bare import { Ajv } from "ajv".
  2. Commit e8006c0 replaces those exports with a comment (exports/public/index.ts:144-146). Nothing in the server root barrel now references ajvProvider.ts at the type level.
  3. Rebuild: dist/index.d.mts lines 1-3 import ./index-dAsK-dK1.mjs, ./types-YaX0ZWcZ.mjs, zod/v4. None of those reference ajvProvider.
  4. A consumer with "skipLibCheck": false runs npm i @modelcontextprotocol/server (no ajv), writes import { McpServer } from '@modelcontextprotocol/server', and runs tsc. TypeScript resolves dist/index.d.mtsindex-dAsK-dK1.d.mtstypes-YaX0ZWcZ.d.mts. ajvProvider-ClUAHE10.d.mts is never visited; no TS2307 for ajv. (They would still hit TS2307 for json-schema-typed — the out-of-scope half.)
  5. Only a consumer who explicitly writes import … from '@modelcontextprotocol/server/_shims' would resolve shimsNode.d.mtsajvProvider-*.d.mtsfrom "ajv". The migration docs no longer document that import.

Impact and suggested resolution

This is review-thread bookkeeping in the same vein as the existing #3241246611 reply ("Thanks — ajvProvider.ts:36's @see is now fixed. The two changeset files are still untouched…"). It prevents the author from doing the now-unnecessary Ajv ctor-arg-type rewrite in response to a partially-stale finding. The thread can be resolved (its primary user-facing concern was addressed by e8006c0), or narrowed to json-schema-typed if the author wants to track that residual leak — but per the original comment that's out-of-scope here. Filed as a nit since it's meta-feedback about review-comment staleness rather than a code defect.

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.

2 participants