Skip to content

Commit 9c5c541

Browse files
committed
Bundle automatic validator defaults in client and server shims
1 parent 2c0c481 commit 9c5c541

24 files changed

Lines changed: 145 additions & 90 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@modelcontextprotocol/core': minor
3+
'@modelcontextprotocol/client': patch
4+
'@modelcontextprotocol/server': patch
5+
---
6+
7+
Make validator backends symmetrical in core and bundle automatic defaults in client/server runtime shims.
8+
9+
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.
10+
11+
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.

docs/migration-SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,11 +518,11 @@ new McpServer(
518518
new McpServer({ name: 'server', version: '1.0.0' }, {});
519519
```
520520

521-
Access validators explicitly:
521+
Validator behavior:
522522

523-
- Runtime-aware default: `import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/server/_shims';`
524-
- AJV (Node.js): `import { AjvJsonSchemaValidator } from '@modelcontextprotocol/server';`
525-
- CF Worker: `import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker';`
523+
- Do not add validator imports for normal migrations.
524+
- Do not install `ajv`, `ajv-formats`, or `@cfworker/json-schema`; client/server bundle the runtime-selected defaults.
525+
- Advanced users may pass `jsonSchemaValidator: myCustomValidator` with their own validator implementation.
526526

527527
## 15. Migration Steps (apply in this order)
528528

docs/migration.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -932,15 +932,18 @@ const server = new McpServer(
932932
);
933933
```
934934

935-
You can still explicitly override the validator if needed:
935+
You do not need to install or import validator packages for the default behavior. The client and server packages bundle the validator backend selected by the runtime shim.
936936

937-
```typescript
938-
// Runtime-aware default (auto-selects AjvJsonSchemaValidator or CfWorkerJsonSchemaValidator)
939-
import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/server/_shims';
937+
Advanced users can still override validation by passing an object that implements the SDK's JSON Schema validator interface:
940938

941-
// Specific validators
942-
import { AjvJsonSchemaValidator } from '@modelcontextprotocol/server';
943-
import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/server/validators/cf-worker';
939+
```typescript
940+
const server = new McpServer(
941+
{ name: 'my-server', version: '1.0.0' },
942+
{
943+
capabilities: { tools: {} },
944+
jsonSchemaValidator: myCustomValidator
945+
}
946+
);
944947
```
945948

946949
## Unchanged APIs

packages/client/package.json

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@
2828
"types": "./dist/stdio.d.mts",
2929
"import": "./dist/stdio.mjs"
3030
},
31-
"./validators/cf-worker": {
32-
"types": "./dist/validators/cfWorker.d.mts",
33-
"import": "./dist/validators/cfWorker.mjs"
34-
},
3531
"./_shims": {
3632
"workerd": {
3733
"types": "./dist/shimsWorkerd.d.mts",
@@ -54,9 +50,6 @@
5450
"types": "./dist/index.d.mts",
5551
"typesVersions": {
5652
"*": {
57-
"validators/cf-worker": [
58-
"dist/validators/cfWorker.d.mts"
59-
],
6053
"stdio": [
6154
"dist/stdio.d.mts"
6255
]
@@ -93,6 +86,8 @@
9386
"@modelcontextprotocol/eslint-config": "workspace:^",
9487
"@modelcontextprotocol/test-helpers": "workspace:^",
9588
"@cfworker/json-schema": "catalog:runtimeShared",
89+
"ajv": "catalog:runtimeShared",
90+
"ajv-formats": "catalog:runtimeShared",
9691
"@types/content-type": "catalog:devTools",
9792
"@types/cross-spawn": "catalog:devTools",
9893
"@types/eventsource": "catalog:devTools",

packages/client/src/client/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export type ClientOptions = ProtocolOptions & {
161161
* The validator is used to validate structured content returned by tools
162162
* against their declared output schemas.
163163
*
164-
* @default {@linkcode DefaultJsonSchemaValidator} ({@linkcode index.AjvJsonSchemaValidator | AjvJsonSchemaValidator} on Node.js, `CfWorkerJsonSchemaValidator` on Cloudflare Workers)
164+
* @default Runtime-selected validator (`AjvJsonSchemaValidator` on Node.js, `CfWorkerJsonSchemaValidator` on browser/workerd runtimes)
165165
*/
166166
jsonSchemaValidator?: jsonSchemaValidator;
167167

packages/client/src/shimsNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* This file is selected via package.json export conditions when running in Node.js.
55
*/
6-
export { AjvJsonSchemaValidator as DefaultJsonSchemaValidator } from '@modelcontextprotocol/core';
6+
export { AjvJsonSchemaValidator as DefaultJsonSchemaValidator } from '@modelcontextprotocol/core/validators/ajv';
77

88
/**
99
* Whether `fetch()` may throw `TypeError` due to CORS. CORS is a browser-only concept —

packages/client/src/validators/cfWorker.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

packages/client/test/client/barrelClean.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { beforeAll, describe, expect, test } from 'vitest';
88
const pkgDir = join(dirname(fileURLToPath(import.meta.url)), '../..');
99
const distDir = join(pkgDir, 'dist');
1010
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
11+
const VALIDATOR_BACKEND_IMPORT = /from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/;
1112

1213
function chunkImportsOf(entryPath: string): string[] {
1314
const visited = new Set<string>();
@@ -52,4 +53,17 @@ describe('@modelcontextprotocol/client root entry is browser-safe', () => {
5253
expect(stdio).toMatch(/\bgetDefaultEnvironment\b/);
5354
expect(stdio).toMatch(/\bDEFAULT_INHERITED_ENV_VARS\b/);
5455
});
56+
57+
test('runtime shims vendor default validator backends instead of requiring consumers to install them', () => {
58+
for (const shim of ['shimsNode.mjs', 'shimsWorkerd.mjs', 'shimsBrowser.mjs']) {
59+
const entry = join(distDir, shim);
60+
expect(readFileSync(entry, 'utf8')).not.toMatch(VALIDATOR_BACKEND_IMPORT);
61+
62+
for (const chunk of chunkImportsOf(entry)) {
63+
expect({ chunk, content: readFileSync(chunk, 'utf8') }).not.toEqual(
64+
expect.objectContaining({ content: expect.stringMatching(VALIDATOR_BACKEND_IMPORT) })
65+
);
66+
}
67+
}
68+
});
5569
});

packages/client/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"*": ["./*"],
88
"@modelcontextprotocol/core": ["./node_modules/@modelcontextprotocol/core/src/index.ts"],
99
"@modelcontextprotocol/core/public": ["./node_modules/@modelcontextprotocol/core/src/exports/public/index.ts"],
10+
"@modelcontextprotocol/core/validators/ajv": ["./node_modules/@modelcontextprotocol/core/src/validators/ajvProvider.ts"],
1011
"@modelcontextprotocol/core/validators/cfWorker": [
1112
"./node_modules/@modelcontextprotocol/core/src/validators/cfWorkerProvider.ts"
1213
],

packages/client/tsdown.config.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default defineConfig({
44
failOnWarn: 'ci-only',
55
// 1. Entry Points
66
// Directly matches package.json include/exclude globs
7-
entry: ['src/index.ts', 'src/stdio.ts', 'src/shimsNode.ts', 'src/shimsWorkerd.ts', 'src/shimsBrowser.ts', 'src/validators/cfWorker.ts'],
7+
entry: ['src/index.ts', 'src/stdio.ts', 'src/shimsNode.ts', 'src/shimsWorkerd.ts', 'src/shimsBrowser.ts'],
88

99
// 2. Output Configuration
1010
format: ['esm'],
@@ -27,13 +27,19 @@ export default defineConfig({
2727
paths: {
2828
'@modelcontextprotocol/core': ['../core/src/index.ts'],
2929
'@modelcontextprotocol/core/public': ['../core/src/exports/public/index.ts'],
30+
'@modelcontextprotocol/core/validators/ajv': ['../core/src/validators/ajvProvider.ts'],
3031
'@modelcontextprotocol/core/validators/cfWorker': ['../core/src/validators/cfWorkerProvider.ts']
3132
}
3233
}
3334
},
34-
// 5. Vendoring Strategy - Bundle the code for this specific package into the output,
35-
// but treat all other dependencies as external (require/import).
36-
noExternal: ['@modelcontextprotocol/core'],
35+
// 5. Vendoring Strategy - Bundle this package's core implementation into the output,
36+
// but treat most dependencies as external (require/import).
37+
//
38+
// The runtime `_shims` entries choose default JSON Schema validators: AJV on Node and
39+
// @cfworker/json-schema on workerd/browser. Client users should not have to install a
40+
// validator backend just to use the runtime default, so bundle the default backends into
41+
// the shim chunks that select them.
42+
noExternal: ['@modelcontextprotocol/core', 'ajv', 'ajv-formats', '@cfworker/json-schema'],
3743

3844
// 6. External packages - keep self-reference imports external for runtime resolution
3945
external: ['@modelcontextprotocol/client/_shims']

0 commit comments

Comments
 (0)