Skip to content

Tool output validation fails when outputSchema is a Zod schema other than ZodObject #1308

@joshjg

Description

@joshjg

Describe the bug

Tool output validation fails with the following error when the tool's outputSchema is an optional, nullable, nullish, or union schema (or, most likely anything besides a plain object schema).

Cannot read properties of undefined (reading '_zod')

When validating output the SDK attempts to use normalizeObjectSchema, which returns undefined for anything besides object schemas.

To Reproduce
Steps to reproduce the behavior:

  1. Define an outputSchema with something other than a plain object or z.object schema.
  2. Implement the tool so that it returns structuredContent that conforms to this schema.
  3. Invoke the tool.
// Works:
outputSchema: z.object({ data: z.string() })

// Fails:
outputSchema: z.object({ data: z.string() }).optional()
outputSchema: z.object({ data: z.string() }).nullable()
outputSchema: z.object({ data: z.string() }).nullish()
outputSchema: z.union([z.object({ data: z.string() }), z.object({ value: z.string() })])

Expected behavior
The SDK should be able to validate output based on Zod schemas which represent a JSON object, even if it is optional or a union of possible object schemas. Based on the spec, null is not a valid value for structuredContent, so nullable and nullish schemas should not be allowed, either through more restrictive typing of outputSchema or runtime validation with a clear error message.

Logs

    at isZ4Schema ($PROJECT/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js:46:21)
    at safeParseAsync ($PROJECT/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js:80:9)
    at McpServer.validateToolOutput ($PROJECT/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js:205:70)
    at $PROJECT/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js:135:28
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async wrappedHandler ($PROJECT/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js:131:32)

Additional context

"@modelcontextprotocol/sdk": "1.24.3",
"zod": "4.1.13"

I was expecting this to work based on #816 but it has possibly regressed with #1040

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Moderate issues affecting some users, edge cases, potentially valuable featurebugSomething isn't workingfix proposedBot has a verified fix diff in the commentready for workEnough information for someone to start working on

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions