Skip to content

outputSchema always emitted as JSON Schema draft-07, breaking clients that only accept 2020-12 #2721

Description

@papayet

Package: @modelcontextprotocol/sdk 1.30.0
Affects: any server built with McpServer that declares an outputSchema (e.g. @modelcontextprotocol/server-filesystem 2026.7.10), consumed by a client with a strict output-schema validator.

Bug

In src/server/zod-json-schema-compat.ts (compiled to dist/{cjs,esm}/server/zod-json-schema-compat.js), mapMiniTarget() falls back to 'draft-7' whenever no explicit target is passed:

function mapMiniTarget(t) {
    if (!t) return 'draft-7';   // <-- always hit in practice
    ...
}

McpServer's tool-listing handler (src/server/mcp.ts) never passes a target when calling toJsonSchemaCompat() for either inputSchema or outputSchema:

toolDefinition.outputSchema = toJsonSchemaCompat(obj, {
    strictUnions: true,
    pipeStrategy: 'output'
});

So every registered tool's outputSchema (Zod v4 branch, via zod/v4-mini's toJSONSchema) is emitted with "$schema": "http://json-schema.org/draft-07/schema#", with no way for the server author to opt into 2020-12.

Impact

A client that validates outputSchema strictly against JSON Schema 2020-12 rejects every tool from every SDK-based server that declares an outputSchema, e.g. (observed in Claude Desktop 1.37937.1):

Tool 'list_directory' has an invalid outputSchema: JSON Schema declares an unsupported dialect
("$schema": "http://json-schema.org/draft-07/schema#"). The default validator supports JSON Schema 2020-12 only.

This breaks @modelcontextprotocol/server-filesystem entirely — every tool call fails client-side before even reaching the server.

Suggested fix

Default mapMiniTarget's fallback to 'draft-2020-12' instead of 'draft-7' (2020-12 is a superset-compatible, more current dialect and z4mini.toJSONSchema already supports it via the existing branch), or have McpServer pass target: 'draft-2020-12' explicitly.

Confirmed locally that swapping the fallback produces "$schema": "https://json-schema.org/draft/2020-12/schema" and resolves the client-side rejection with no other code changes needed.

Repro

  1. Any MCP server built with McpServer + outputSchema (e.g. server-filesystem@2026.7.10).
  2. A client validating outputSchema strictly against 2020-12 (e.g. Claude Desktop 1.37937.1+).
  3. Every tool call fails with the "unsupported dialect" error above.

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