Skip to content

Commit d743152

Browse files
Merge branch 'main' into fweinberger/content-type-media-type-validation
2 parents c3e32b8 + e8de519 commit d743152

6 files changed

Lines changed: 46 additions & 10 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@modelcontextprotocol/client': patch
3+
'@modelcontextprotocol/server': patch
4+
---
5+
6+
Stop advertising validator provider classes from the root client/server type declarations. The provider classes remain available from the explicit validator subpaths.

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const requireDist = createRequire(join(pkgDir, 'package.json'));
1212
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
1313
// Anchored at start-of-line so JSDoc-example `from 'ajv'` strings in vendored chunks don't match.
1414
const VALIDATOR_BACKEND_IMPORT = /^import[^\n]*?from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/m;
15+
const ROOT_VALIDATOR_EXPORTS = ['AjvJsonSchemaValidator', 'CfWorkerJsonSchemaValidator', 'CfWorkerSchemaDraft'];
1516

1617
function chunkImportsOf(entryPath: string): string[] {
1718
const visited = new Set<string>();
@@ -29,6 +30,12 @@ function chunkImportsOf(entryPath: string): string[] {
2930
return [...visited];
3031
}
3132

33+
function rootExportBlockOf(content: string): string {
34+
const blocks = content.match(/(?:^|\n)export \{[\s\S]*?\};/g);
35+
expect(blocks).toBeTruthy();
36+
return blocks!.at(-1)!;
37+
}
38+
3239
describe('@modelcontextprotocol/client root entry is browser-safe', () => {
3340
beforeAll(() => {
3441
if (!existsSync(join(distDir, 'index.mjs')) || !existsSync(join(distDir, 'stdio.mjs'))) {
@@ -80,4 +87,13 @@ describe('@modelcontextprotocol/client root entry is browser-safe', () => {
8087

8188
expect(new AjvJsonSchemaValidator(ajv)).toBeInstanceOf(AjvJsonSchemaValidator);
8289
});
90+
91+
test('root declarations do not advertise validator provider classes', () => {
92+
for (const declaration of ['index.d.mts', 'index.d.cts']) {
93+
const rootExportBlock = rootExportBlockOf(readFileSync(join(distDir, declaration), 'utf8'));
94+
for (const symbol of ROOT_VALIDATOR_EXPORTS) {
95+
expect(rootExportBlock).not.toMatch(new RegExp(`\\b(?:type\\s+)?${symbol}\\b`));
96+
}
97+
}
98+
});
8399
});

packages/core-internal/src/exports/public/index.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,9 @@ export {
134134
export type { SpecTypeName, SpecTypes } from '../../types/specTypeSchema';
135135
export { isSpecType, specTypeSchemas } from '../../types/specTypeSchema';
136136
export type { StandardSchemaV1, StandardSchemaV1Sync, StandardSchemaWithJSON } from '../../util/standardSchema';
137-
// Validator providers are type-only here — import the runtime classes from the explicit
138-
// `@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}` subpaths to customise.
139-
export type { AjvJsonSchemaValidator } from '../../validators/ajvProvider';
140-
export type { CfWorkerJsonSchemaValidator, CfWorkerSchemaDraft } from '../../validators/cfWorkerProvider';
137+
// Validator provider classes stay subpath-only. Re-exporting them here, even as
138+
// `type`, can make generated root declarations advertise runtime-shaped root
139+
// exports that the package root does not provide.
141140
// fromJsonSchema is intentionally NOT exported here — the server and client packages
142141
// provide runtime-aware wrappers that default to the appropriate validator via _shims.
143142
export type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator, JsonSchemaValidatorResult } from '../../validators/types';

packages/core-internal/src/index.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ export * from './util/standardSchema';
3434
export * from './util/zodCompat';
3535
export { codecForVersion, MODERN_WIRE_REVISION } from './wire/codec';
3636

37-
// Validator providers are type-only here — import the runtime classes from the explicit
38-
// `@modelcontextprotocol/{client,server}/validators/{ajv,cf-worker}` subpaths to customise.
39-
export type { AjvJsonSchemaValidator } from './validators/ajvProvider';
40-
export type { CfWorkerJsonSchemaValidator, CfWorkerSchemaDraft } from './validators/cfWorkerProvider';
37+
// Validator provider classes stay subpath-only. Re-exporting them here, even as
38+
// `type`, can make generated client/server root declarations advertise
39+
// runtime-shaped root exports that the package root does not provide.
4140
export * from './validators/fromJsonSchema';
4241
export type { JsonSchemaType, JsonSchemaValidator, jsonSchemaValidator, JsonSchemaValidatorResult } from './validators/types';

packages/server/test/server/barrelClean.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const requireDist = createRequire(join(pkgDir, 'package.json'));
1212
const NODE_ONLY = /\b(child_process|cross-spawn|node:stream|node:child_process)\b/;
1313
// Anchored at start-of-line so JSDoc-example `from 'ajv'` strings in vendored chunks don't match.
1414
const VALIDATOR_BACKEND_IMPORT = /^import[^\n]*?from\s+["'](?:ajv|ajv-formats|@cfworker\/json-schema)["']/m;
15+
const ROOT_VALIDATOR_EXPORTS = ['AjvJsonSchemaValidator', 'CfWorkerJsonSchemaValidator', 'CfWorkerSchemaDraft'];
1516

1617
function chunkImportsOf(entryPath: string): string[] {
1718
const visited = new Set<string>();
@@ -29,6 +30,12 @@ function chunkImportsOf(entryPath: string): string[] {
2930
return [...visited];
3031
}
3132

33+
function rootExportBlockOf(content: string): string {
34+
const blocks = content.match(/(?:^|\n)export \{[\s\S]*?\};/g);
35+
expect(blocks).toBeTruthy();
36+
return blocks!.at(-1)!;
37+
}
38+
3239
describe('@modelcontextprotocol/server root entry is browser-safe', () => {
3340
beforeAll(() => {
3441
if (!existsSync(join(distDir, 'index.mjs')) || !existsSync(join(distDir, 'stdio.mjs'))) {
@@ -81,4 +88,13 @@ describe('@modelcontextprotocol/server root entry is browser-safe', () => {
8188

8289
expect(new AjvJsonSchemaValidator(ajv)).toBeInstanceOf(AjvJsonSchemaValidator);
8390
});
91+
92+
test('root declarations do not advertise validator provider classes', () => {
93+
for (const declaration of ['index.d.mts', 'index.d.cts']) {
94+
const rootExportBlock = rootExportBlockOf(readFileSync(join(distDir, declaration), 'utf8'));
95+
for (const symbol of ROOT_VALIDATOR_EXPORTS) {
96+
expect(rootExportBlock).not.toMatch(new RegExp(`\\b(?:type\\s+)?${symbol}\\b`));
97+
}
98+
}
99+
});
84100
});

scripts/smoke-dist-types.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ try {
1414
path.join(dir, 'consumer.ts'),
1515
[
1616
"import { Client } from '@modelcontextprotocol/client';",
17-
"import type { AjvJsonSchemaValidator as ClientAjv } from '@modelcontextprotocol/client';",
17+
"import type { JsonSchemaType as ClientSchema } from '@modelcontextprotocol/client';",
1818
"import { AjvJsonSchemaValidator } from '@modelcontextprotocol/client/validators/ajv';",
1919
"import { CfWorkerJsonSchemaValidator as ClientCf } from '@modelcontextprotocol/client/validators/cf-worker';",
2020
"import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';",
@@ -24,7 +24,7 @@ try {
2424
"import { StdioServerTransport } from '@modelcontextprotocol/server/stdio';",
2525
"export const c = new Client({ name: 'smoke', version: '1.0.0' });",
2626
"export const s = new McpServer({ name: 'smoke', version: '1.0.0' });",
27-
'export type T = ClientAjv;',
27+
'export type T = ClientSchema;',
2828
'export { AjvJsonSchemaValidator, ServerAjv, ClientCf, ServerCf, StdioClientTransport, StdioServerTransport };',
2929
''
3030
].join('\n')

0 commit comments

Comments
 (0)