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 workingneeds reproneeds additional information to be able to reproduce bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions