Skip to content

v1.18.8 strict AjvJsonSchemaValidator rejects MCP servers emitting draft-07 schemas (n8n, Dokploy, any MCP TypeScript SDK server) #39333

Description

@WayneSimpson

Problem

OpenCode 1.18.8 introduced a strict AjvJsonSchemaValidator (from the MCP TypeScript SDK) that rejects any tool schema declaring a $schema dialect other than JSON Schema 2020-12. This breaks compatibility with MCP servers that emit http://json-schema.org/draft-07/schema#.

Affected MCP Servers

Any server built on the MCP TypeScript SDK (@modelcontextprotocol/sdk) is affected, because the SDK's zod-to-json-schema defaults to draft-07 (typescript-sdk#2084).

Confirmed affected:

  • n8n MCP Server v1.1.0 — all 33 tools declare draft-07 in both inputSchema and outputSchema
  • Dokploy MCP — Dokploy/mcp#36
  • Any server using @modelcontextprotocol/sdk < 2.0.0 with Zod schemas

Error Message

Tool 'get_workflow_details' 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; pass a pre-configured Ajv instance to AjvJsonSchemaValidator(ajv) to validate other dialects.

Reproduction

  1. Install OpenCode 1.18.8
  2. Configure a remote MCP server that emits draft-07 schemas (e.g., n8n MCP at https://n8n.nccio.co.uk/mcp-server/http)
  3. Attempt to use any tool from that server
  4. Observe the error above — all tools from the server are rejected

Expected Behaviour

OpenCode should either:

  • Accept draft-07 schemas by configuring Ajv with Ajv2020 (which is backwards-compatible with draft-07), or
  • Strip $schema before validation so schemas without an explicit dialect default to 2020-12, or
  • Warn instead of reject — log the dialect mismatch but still register the tool

Workaround

Downgrade to 1.18.7 (last version without the strict validator). This loses the MCP reconnection and OAuth improvements from 1.18.8.

Environment

  • OpenCode: 1.18.8 (installed via npm, WSL2 Linux)
  • n8n MCP Server: v1.1.0 (remote, https://n8n.nccio.co.uk/mcp-server/http)
  • MCP TypeScript SDK: @modelcontextprotocol/sdk (the version bundled in OpenCode 1.18.8)

Related Issues

Context

The MCP TypeScript SDK was supposed to default to 2020-12 per SEP-1613, but as of SDK v1.29.0 the target: 'draft-2020-12' option is not passed at the call sites in mcp.js, so mapMiniTarget(undefined) falls back to 'draft-7'. This means every server built on the SDK emits draft-07, and strict clients like OpenCode 1.18.8 reject them all.

Activity

  1. argszero commented on Jul 28, 2026

    @argszero
    Contributor

    Technical analysis from a Contributor:

    I traced the validation path in the opencode codebase.

    How the validation happens

    The AjvJsonSchemaValidator error originates from inside the MCP TypeScript SDK v2.0.0-beta.5 (@modelcontextprotocol/client), not from opencode's own code. The chain is:

    index.ts:78 → new Client(...)          // no custom Ajv passed
    catalog.ts:39 → listTools(client, ...)  // SDK validates all tools here
    catalog.ts:42 → convertTool(tool)       // called per-tool after validation
    

    The ClientOptions (index.ts:39-52) does not pass a custom Ajv instance, so the SDK uses its default AjvJsonSchemaValidator which only accepts 2020-12.

    Possible fix approaches

    1. Patch tool schemas after listing (opencode-side, simplest)

    After listTools returns, strip $schema from each tool's inputSchema before calling convertTool. The schema body is valid 2020-12 in practice (only the $schema URI differs). This would go in catalog.ts around line 43:

    const inputSchema: JSONSchema7 = {
      ...({ ...tool.def.inputSchema, $schema: undefined } as JSONSchema7),
      type: object,
      ...
    }

    Caveat: This approach fails if the validation happens inside listTools() before control returns to opencode. The error message format suggests this is the case — the SDK validates during tool listing, not after.

    2. Pass a custom Ajv instance (opencode-side, more robust)

    Create an Ajv2020 instance configured to accept draft-07 (which is backwards-compatible in most cases), and pass it through ClientOptions. The MCP SDK's ClientOptions type may or may not expose this — needs SDK inspection.

    3. Strip $schema in SDK consumer code (patch the SDK)

    The MCP SDK's validateSchema / AjvJsonSchemaValidator could be configured to strip or ignore the $schema field before validation, since the schemas are de facto 2020-12 compatible (they just carry the wrong URI). This would be a PR against modelcontextprotocol/typescript-sdk.

    4. SDK upstream fix

    The root cause is the MCP TypeScript SDK emitting draft-07 by default (typescript-sdk#2084). If the SDK fixes this, both OpenCode and all affected servers are resolved globally.

    Recommendation

    The most pragmatic fix for opencode is option 2 (custom Ajv with draft-07 support) or, if that's not possible through the current SDK API, a combination of option 3 (patches the bundled SDK via a local patch — opencode already has a patches directory, e.g., patches/@modelcontextprotocol%[email protected]).

    The patches/ directory already contains SDK patches; adding a schema-dialect tolerance patch there would be the lowest-risk fix that doesn't require waiting for an SDK release.

  2. rekram1-node commented on Jul 28, 2026

    @rekram1-node
    Collaborator

    looking

  3. rekram1-node commented on Jul 28, 2026

    @rekram1-node
    Collaborator

    we downgraded the sdk and released the fix, latest mcp sdk had some bugs in it so we were forced to downgrade

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

Metadata

Metadata

Assignees

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