Skip to content

Bug: outputSchema defaults to empty object, breaking tool output validation #2327

@viktormarinho

Description

@viktormarinho

Summary

When tools don't define an outputSchema, the runtime defaults to z.object({}).shape instead of undefined. This causes the MCP SDK to validate tool outputs against an empty schema, failing with:

MCP error -32602: Structured content does not match the tool's output schema: 
data must NOT have additional properties, data must NOT have additional properties

Affected Versions

  • Broken: 1.2.0, 1.2.1, 1.2.2, 1.2.3, 1.2.4 (all tested)

Location

packages/runtime/src/tools.ts - line ~685 (in v1.2.4)

Current Code (Broken)

outputSchema: isStreamableTool(tool)
  ? z.object({ bytes: z.record(z.string(), z.number()) }).shape
  : tool.outputSchema &&
      typeof tool.outputSchema === "object" &&
      "shape" in tool.outputSchema
    ? (tool.outputSchema.shape as ZodRawShape)
    : z.object({}).shape,  // ← BUG: Should be undefined

Problem

The MCP SDK's validateToolOutput() function skips validation when outputSchema is undefined:

async validateToolOutput(tool, result, toolName) {
    if (!tool.outputSchema) {
        return;  // ← Skips validation when undefined
    }
    // ... validates against schema
}

But when defaulting to z.object({}).shape, validation runs against an empty schema and fails for any tool that returns data with properties.

Suggested Fix

Change line ~685 from:

: z.object({}).shape,

To:

: undefined,

Reproduction

Any tool without explicit outputSchema that returns an object with properties:

createTool({
  id: "my_tool",
  inputSchema: z.object({}),
  // No outputSchema defined
  execute: async () => {
    return { foo: "bar" };  // ← Fails validation against empty schema
  },
});

Workaround

Postinstall patch to change the default to undefined.

Related

Discovered alongside #2326 (transport.close SSE bug)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions