Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions scripts/generate-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
*
* ts-to-zod is a powerful tool but has limitations that require post-processing:
*
* ### 1. Zod Import Path (keep standard `"zod"` for version agnosticism)
* ### 1. Zod Import Path (`"zod"` → `"zod/v4"`)
*
* ts-to-zod generates `import { z } from "zod"` which works with both
* Zod v3.25+ and v4. We keep this standard import to support both versions.
* ts-to-zod generates `import { z } from "zod"`. We rewrite this to
* `import { z } from "zod/v4"` because the generated schemas compose with
* schemas imported from `@modelcontextprotocol/sdk/types.js`, which the SDK
* constructs via `zod/v4`. Mixing schemas from the v3 and v4 APIs at runtime
* fails with errors like `keyValidator._parse is not a function` (v3 internals
* calling into v4 objects, or vice versa). The `zod/v4` subpath is exported by
* both zod 3.25+ and zod 4.x, so the peerDependency range is preserved.
*
* ### 2. External Type References (`z.any()` → actual schemas)
*
Expand Down Expand Up @@ -179,11 +184,13 @@ async function generateJsonSchema() {
* Post-process generated schemas for project compatibility.
*/
function postProcess(content: string): string {
// 1. Add MCP SDK schema imports (keep standard zod import for v3/v4 compatibility)
// 1. Rewrite to zod/v4 and add MCP SDK schema imports.
// zod/v4 aligns with the SDK's own zod import — composing v3 and v4
// schema instances throws at parse time. See header comment for details.
const mcpImports = EXTERNAL_TYPE_SCHEMAS.join(",\n ");
content = content.replace(
'import { z } from "zod";',
`import { z } from "zod";
`import { z } from "zod/v4";
import {
${mcpImports},
} from "@modelcontextprotocol/sdk/types.js";`,
Expand Down Expand Up @@ -257,7 +264,12 @@ function replaceRecordAndWithPassthrough(content: string): string {
* Post-process generated integration tests.
*/
function postProcessTests(content: string): string {
// Keep standard zod import for v3/v4 compatibility
// Rewrite to zod/v4 so z.infer matches the v4 schemas in schema.ts.
content = content.replace(
'import { z } from "zod";',
'import { z } from "zod/v4";',
);

content = content.replace(
"// Generated by ts-to-zod",
`// Generated by ts-to-zod
Expand Down
2 changes: 1 addition & 1 deletion src/generated/schema.test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/generated/schema.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading