Skip to content

Default JSON Schema validators reject declared draft-07, which the spec permits #2532

Closed

Description

@chelojimenez

Both default validators (AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator) throw on any tool schema that declares a non-2020-12 dialect:

Tool 'example' 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.

Per the spec, 2020-12 is only the default when $schema is absent — an explicitly declared draft-07 dialect is valid on all protocol versions (the spec's own examples include it). So schemas the spec permits currently hard-fail tools/call in the client.

The practical impact is wide: zod-to-json-schema, which v1 SDK servers use for outputSchema, stamps "$schema": ".../draft-07/schema#" on every schema. Any v2-SDK client talking to any v1-SDK server with an output schema fails on every tool call, with no server-side fix available short of rewriting the server.

Repro:

import { AjvJsonSchemaValidator } from "@modelcontextprotocol/client/validators/ajv";

new AjvJsonSchemaValidator().getValidator({
  $schema: "http://json-schema.org/draft-07/schema#",
  type: "object",
}); // throws "unsupported dialect"

Expected: validate the schema using the dialect it declares (or at minimum draft-07, given its ubiquity via zod), rather than rejecting it.

Seen on @modelcontextprotocol/client@2.0.0-beta.4. Happy to contribute a fix — we currently work around this with a dispatching validator that routes on the declared $schema.

Activity

  1. Sakshamm-Goyal commented on Jul 22, 2026

    @Sakshamm-Goyal

    I’d like to take this on with a narrow bug fix and regression coverage. I’ll first reproduce the declared draft-07 path in both default validators, then keep the change limited to dialect selection/registration required for standards-compliant validation. Please assign it to me if that approach is welcome; I’ll wait for assignment before implementation.

  2. Kaif10 commented on Jul 24, 2026

    @Kaif10

    I ran into this too and can reproduce it on @modelcontextprotocol/client@2.0.0-beta.4. Root cause is that both default validators hard-require the 2020-12 meta-schema and throw for any other declared $schema, whereas per spec 2020-12 is only the default when $schema is absent — an explicitly declared dialect (notably draft-07, which zod-to-json-schema stamps on every v1-server output schema) should be honored.

    The fix I have in mind is to route by the declared dialect rather than reject it: keep 2020-12 as the default when $schema is absent, but when a schema declares a dialect the underlying validator supports (draft-07 in particular — Ajv's default build is draft-07, with 2020-12 via ajv/dist/2020), compile it against that dialect instead of throwing. That restores v2-client ↔ v1-server interop without loosening validation. I'd add tests covering an explicit draft-07 schema, an absent-$schema schema (still 2020-12), and a genuinely unsupported dialect (still rejected).

    @chelojimenez — are you still planning to submit your fix? I don't want to step on it. If not (or if a maintainer would rather I take it), I'm happy to open a small PR with tests. Either way I've confirmed the repro.

  3. added
    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes
    on Aug 18, 2026
  4. claude commented on Aug 19, 2026

    @claude
    Contributor

    Closing: fixed in #2534, released in 2.0.0

    Thanks for the detailed report and repro — this was exactly the v2-client ↔ v1-server interop gap described. It was fixed in #2534 (merged 2026-07-27, ahead of the stable 2.0.0 release later that day): both default validators (AjvJsonSchemaValidator and CfWorkerJsonSchemaValidator) now dispatch on the declared dialect instead of rejecting it — declared draft-07/draft-06 compiles with classic Ajv, declared 2019-09 with Ajv 2019, and 2020-12 stays the default when $schema is absent; only genuinely unknown dialects still produce the typed error. This is also noted in the migration guide (docs/migration/upgrade-to-v2.md): "a declared draft-07/06 $schema dispatches automatically". If you still hit this on @modelcontextprotocol/client@2.0.0 or later, please open a new issue.

    This comment and close were reviewed and approved by maintainer @felixweinberger — it is a human-approved action, not an unattended automated one.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingv2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions