fix(server): auto-unwrap z.object() schemas in server.tool()#1603
Open
giulio-leone wants to merge 3 commits intomodelcontextprotocol:v1.xfrom
Open
fix(server): auto-unwrap z.object() schemas in server.tool()#1603giulio-leone wants to merge 3 commits intomodelcontextprotocol:v1.xfrom
giulio-leone wants to merge 3 commits intomodelcontextprotocol:v1.xfrom
Conversation
🦋 Changeset detectedLatest commit: d280069 The changes in this PR will be included in the next version bump. 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 |
commit: |
When z.object({...}) is passed as inputSchema, the SDK would silently
interpret it as ToolAnnotations instead of an input schema, resulting in
the tool being registered with empty parameters. Arguments passed to the
tool would be silently stripped.
Added extractZodObjectShape() that detects ZodObject schemas (both Zod
v3 and v4) via their .shape property and extracts the raw shape for
proper registration.
Fixes modelcontextprotocol#1291
5f16615 to
4f3ac37
Compare
The z.object() tests intentionally pass ZodObject schemas (instead of raw shapes) to verify runtime auto-unwrapping. Since TypeScript's type system doesn't support ZodObject as a valid argument, use 'as any' casts and explicit callback parameter types to satisfy the type checker while preserving the test's intent.
Author
|
Friendly ping — CI is green and this is ready for review. Happy to address any feedback. Thanks! |
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.
Problem
When
z.object({...})is passed asinputSchematoserver.tool(), the SDK silently interprets it asToolAnnotationsinstead of an input schema. The tool registers with empty parameters and arguments are stripped without any error.This is because
isZodRawShapeCompat()correctly identifies ZodObject instances as not raw shapes (they have internal_def/_zodproperties, not field schemas as values). But the fallback branch at line 1026 unconditionally treats any remaining object asToolAnnotations.Root Cause
Fix
Added
extractZodObjectShape()that detects ZodObject schemas (both Zod v3 and v4) by checking for a.shapeproperty whose values are Zod type instances. When detected, the raw shape is extracted and used asinputSchema.Both forms now work identically:
Tests
z.object()auto-unwrap with schema verification and argument passingz.object()combined with annotationsFixes #1291