deps: upgrade zod to v4 and drop deprecated zod-to-json-schema#10535
Open
xtazz wants to merge 1 commit into
Open
deps: upgrade zod to v4 and drop deprecated zod-to-json-schema#10535xtazz wants to merge 1 commit into
xtazz wants to merge 1 commit into
Conversation
zod-to-json-schema was deprecated in November 2025; its README points
users at v4's built-in z.toJSONSchema(). Switch the MCP tool factory
to use the built-in with target: "draft-7" (preserves the JSON Schema
shape that cleanSchema() is tuned for) and io: "input" (preserves the
prior required[] semantics: fields with .default() do NOT appear in
required, matching what zod-to-json-schema emitted).
The ServerTool default generic parameter is changed from ZodTypeAny
to z.ZodAny so that z.infer<> still resolves to any (zod v4 made
ZodTypeAny's output unknown), keeping ServerTool[] arrays of
heterogeneous tool types assignable as before.
mcpCallTool now coalesces request.params.arguments to {} before
invoking tool.fn. The MCP protocol allows clients to omit the
arguments field, and v4's stricter input typing made it impossible
to keep the existing per-tool '= {}' destructuring defaults under
schemas with required fields. The two App Hosting handlers that
carried that defensive default are simplified accordingly.
Contributor
There was a problem hiding this comment.
Code Review
This pull request upgrades the zod dependency to version 4 and removes the zod-to-json-schema package, opting instead for the native z.toJSONSchema() method. The changes include updating package.json, CHANGELOG.md, and refactoring src/mcp/tool.ts to use the new schema generation logic. Additionally, src/mcp/index.ts now provides a default empty object for tool arguments, and several tool implementations in the apphosting directory have been updated to remove redundant default parameter assignments. I have no feedback to provide.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
zodfrom^3.24.3to^4.0.0and drops the now-deprecatedzod-to-json-schemadependency in favor of zod v4's built-inz.toJSONSchema().zod-to-json-schemawas deprecated in November 2025; its README explicitly recommends migrating to v4 (https://www.npmjs.com/package/zod-to-json-schema).Changes
src/mcp/tool.ts— ReplacezodToJsonSchema(schema)withz.toJSONSchema(schema, { target: "draft-7", io: "input" }):target: "draft-7"keeps the previous JSON Schema dialect (zod v4's default is draft-2020-12, which uses constructscleanSchema()doesn't normalize).io: "input"preserves the priorrequired[]semantics — without it, fields with.default()would be reported as required to MCP clients (v4 default mode isio: "output").ServerTooldefault generic changed fromZodTypeAnytoz.ZodAnysoz.infer<>still resolves toany(v4 madeZodTypeAny's outputunknown, which broke heterogeneousServerTool[]arrays).src/mcp/index.ts—mcpCallToolnow coalescesrequest.params.argumentsto{}before invokingtool.fn. The MCP protocol allows clients to omit theargumentsfield, and v4's stricter input typing made it impossible to keep the existing per-tool= {}destructuring defaults under schemas with required fields. Centralizing the fallback at the dispatcher is equivalent for the two tools that had it and now also guards every other tool against the same runtime hazard.src/mcp/tools/apphosting/{fetch_logs,list_backends}.ts— Drop the now-redundant= {}parameter defaults (replaced by the dispatcher fallback above).package.json/npm-shrinkwrap.json— bump zod, remove zod-to-json-schema.CHANGELOG.md— release note entry.Verified wire-format compatibility
The combination of
target: "draft-7"+io: "input"+ the existingcleanSchema()post-processor produces equivalent JSON Schema output to the previouszodToJsonSchema()for the schema patterns used in this repo (z.object,z.string,z.number,z.boolean,z.array,z.enum,z.union,z.literal,.optional,.default,.describe,z.infer, one.refine). No tool uses.nullable(),z.coerce,.brand,z.discriminatedUnion, or other patterns that change shape between emitters.Test plan
npm run build— cleannpm run lint:changed-files— 0 errors (2 pre-existing warnings intool.ts)npm run mocha— all 4382 tests passingnpm test(lint:quiet + test:compile + mocha) — greenio: "input"semantics with a standalone script againstnode_modules/zodto confirm defaulted fields stay out ofrequired[]