fix(core): inline reused Zod subschemas in tools/list JSON Schema#2119
Open
abdulmunimj wants to merge 1 commit into
Open
fix(core): inline reused Zod subschemas in tools/list JSON Schema#2119abdulmunimj wants to merge 1 commit into
abdulmunimj wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 9150754 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/server
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
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.
Fixes #2100.
Problem
McpServer.registerTool()accepts a Zod input schema and advertises it undertools/listviastandardSchemaToJsonSchema()inpackages/core/src/util/standardSchema.ts.When that schema reuses a subschema (the same
z.object({...})referenced in twoplaces, or once inside an array), zod's JSON Schema converter may dedupe the
reused instance into a
$refpointer. Strict MCP clients (issue #2100 reportskimi) reject any
$refform other than#/$defs/..., sotools/listfailswith errors like
references must start with #/$defs/.Zod's
to-json-schemaexposes areusedoption whose value flipped between'ref'and'inline'across 4.x minors; the SDK pinszod ^4.2.0, so users onolder 4.2.x are exposed to the buggy default. Even on the current default,
relying on zod's choice is fragile.
Fix
Pass
reused: 'inline'fromstandardSchemaToJsonSchemaon both code paths:StandardJSONSchemaV1(zod >= 4.2.0, ArkType, Valibot via
toStandardJsonSchema). The option isthreaded through
libraryOptions, which zod's standard-schema entrypointforwards to the converter (verified against
zod/v4/core/to-json-schema.ts:createStandardJSONSchemaMethod). TheSDK's
StandardJSONSchemaV1.Optionsalready permitslibraryOptions?: Record<string, unknown>, so the change is type-safe.~standard.jsonSchema).Pass
reused: 'inline'directly toz.toJSONSchema. This matches theexact site the issue text points at.
Editing only the fallback path (as the issue text suggests) would have zero
effect for the SDK's stated minimum zod (
^4.2.0), where the primary path isthe live one. The maintainer-affiliated commenter on #2100 outlined the same
approach.
Tests
packages/core/test/util/standardSchema.test.ts— newdescribe('$ref behavior for reused schemas (issue #2100)')block:$refkeys.$refkeys.$refkeys.~standard.jsonSchemawithlibraryOptions.reused: 'ref'directly to witness that ref-mode isreachable (proving zod still honours the knob), then call the SDK and
assert it still inlines. This defends against zod silently dropping the
option or flipping its default in either direction.
packages/core/test/util/standardSchema.zodFallback.test.ts— adds an inlineassertion for the zod 4.0/4.1 fallback path, by stripping
~standard.jsonSchemafrom a real zod schema and asserting
$refkeys are absent in the result.All 557 core tests pass; full repo
pnpm test:allis green except an unrelated,environment-flaky integration test (
test/server/cloudflareWorkers.test.tsfails with
spawnSync /bin/sh ETIMEDOUTrunning a nestednpm install,reproducible on clean
main).Changeset
.changeset/inline-reused-zod-schemas.md(@modelcontextprotocol/core: patch).Out of scope
Per-tool override knob for
reusedmode — can land in a follow-up if anyoneever needs ref-mode output for a non-strict client.