Skip to content

v2 alpha: @modelcontextprotocol/server has @cfworker/json-schema as optional peer but imports it unconditionally #2093

Closed

Description

@thkim-us

Summary

In @modelcontextprotocol/server@2.0.0-alpha.2, @cfworker/json-schema is declared as an optional peer dependency, but it is imported unconditionally at module-init time. Any consumer that doesn't install @cfworker/json-schema gets ERR_MODULE_NOT_FOUND the moment they import { McpServer } — even if they only use Standard Schema (Zod) inputs and never touch the JSON-Schema validator.

Repro

mkdir repro && cd repro
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/server@2.0.0-alpha.2
echo 'import { McpServer } from "@modelcontextprotocol/server"; new McpServer({ name: "x", version: "0" });' > index.mjs
node index.mjs

Result:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@cfworker/json-schema' imported from .../node_modules/@modelcontextprotocol/server/dist/src-IKPjmxu7.mjs

@cfworker/json-schema is not installed (it's peerDependenciesMeta.optional: true), and yet the failing import is at line 2 of the chunk:

// node_modules/@modelcontextprotocol/server/dist/src-IKPjmxu7.mjs:2
import { Validator } from "@cfworker/json-schema";

Why this is a bug

The peer is declared optional precisely because Standard Schema users (Zod / ArkType / Valibot) shouldn't need it — only fromJsonSchema() / CfWorkerJsonSchemaValidator consumers do. But because the import is at the top of a bundled chunk that's pulled in by McpServer itself, the optionality is unenforceable: every consumer must install it.

This effectively makes @cfworker/json-schema a hard dependency. The peerDependenciesMeta declaration is misleading.

Suggestions

  1. Lazy import — load @cfworker/json-schema only inside CfWorkerJsonSchemaValidator / fromJsonSchema() via dynamic import(). The validator is only constructed at user request, not at SDK init.
  2. Move to a sub-export — e.g. @modelcontextprotocol/server/cfworker, importable only by users who opt in.
  3. Promote to a hard dependency — if lazy loading is rejected, drop the optional flag and make it a regular dep so npm install @modelcontextprotocol/server always works.

Option 1 preserves the original intent of the optional peer.

Environment

  • Node v25.8.1
  • @modelcontextprotocol/server@2.0.0-alpha.2
  • npm v11.x

Related

Activity

  1. furkankoykiran commented on May 16, 2026

    @furkankoykiran

    #1897 (merged 2026-04-28) ended up taking your option 2: moved the cfworker validator to the /validators/cf-worker subpath instead of doing the lazy import(). The published 2.0.0-alpha.2 was cut before that landed, which is why the repro still trips on it.

    Built from current main to confirm, and the bundle no longer reaches @cfworker/json-schema from the main entry:

    $ grep -l "@cfworker/json-schema" packages/server/dist/*.mjs
    cfWorkerProvider-D9WQ-Wyc.mjs    # isolated chunk, not reached from index.mjs
    
    $ grep -E '^import ' packages/server/dist/index.mjs
    import { ... } from "./src-DRh9R4uC.mjs";
    import { DefaultJsonSchemaValidator } from "@modelcontextprotocol/server/_shims";
    

    Node consumers resolve /_shims to shimsNode.mjs (which pulls AjvJsonSchemaValidator), so cfworker only loads if you're in workerd/browser or import the /validators/cf-worker subpath directly.

    Should clear up on the next alpha.

  2. added
    triageQueued for automated analysis — bot will process and remove this label
    on Jul 9, 2026
  3. ghost added
    v2Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes
    on Jul 9, 2026
  4. ghost added
    potentially closeBot recommends closing — needs maintainer review
    on Jul 9, 2026
  5. ghost removed
    triageQueued for automated analysis — bot will process and remove this label
    on Jul 9, 2026
  6. mattzcarey commented on Sep 11, 2026

    @mattzcarey
    Member

    Closed as already fixed in PR #1897: CfWorkerJsonSchemaValidator moved out of the core barrel into the opt-in ./validators/cf-worker subpath, and the default Node shim resolves to the bundled Ajv validator, so nothing loads @cfworker/json-schema at init. Guarded by the barrel test. Verified on the published 2.0.0 with @cfworker/json-schema absent.

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

    potentially closeBot recommends closing — needs maintainer reviewv2Ideas, 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