Skip to content

deps: upgrade zod to v4 and drop deprecated zod-to-json-schema#10535

Open
xtazz wants to merge 1 commit into
firebase:mainfrom
xtazz:zod-v4-migration
Open

deps: upgrade zod to v4 and drop deprecated zod-to-json-schema#10535
xtazz wants to merge 1 commit into
firebase:mainfrom
xtazz:zod-v4-migration

Conversation

@xtazz
Copy link
Copy Markdown

@xtazz xtazz commented May 20, 2026

Summary

  • Upgrades zod from ^3.24.3 to ^4.0.0 and drops the now-deprecated zod-to-json-schema dependency in favor of zod v4's built-in z.toJSONSchema().
  • zod-to-json-schema was deprecated in November 2025; its README explicitly recommends migrating to v4 (https://www.npmjs.com/package/zod-to-json-schema).
  • Designed to be wire-compatible with the previous JSON Schema output that MCP clients consume.

Changes

src/mcp/tool.ts — Replace zodToJsonSchema(schema) with z.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 constructs cleanSchema() doesn't normalize).
  • io: "input" preserves the prior required[] semantics — without it, fields with .default() would be reported as required to MCP clients (v4 default mode is io: "output").
  • ServerTool default generic changed from ZodTypeAny to z.ZodAny so z.infer<> still resolves to any (v4 made ZodTypeAny's output unknown, which broke heterogeneous ServerTool[] arrays).

src/mcp/index.tsmcpCallTool 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. 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 existing cleanSchema() post-processor produces equivalent JSON Schema output to the previous zodToJsonSchema() 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 — clean
  • npm run lint:changed-files — 0 errors (2 pre-existing warnings in tool.ts)
  • npm run mocha — all 4382 tests passing
  • npm test (lint:quiet + test:compile + mocha) — green
  • Manually verified io: "input" semantics with a standalone script against node_modules/zod to confirm defaulted fields stay out of required[]
  • CI integration tests will run on PR

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.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

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.

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