Skip to content

[v2] @modelcontextprotocol/node: optional hono peer is unmet under strict package managers, and becomes a runtime crash with @hono/node-server 2.x (#2574) #2882

Description

@unrevised6419

What happened?

@modelcontextprotocol/node declares hono as an optional peer (#1896), but its dependency @hono/node-server declares hono: ^4 as a required peer. An optional peer upstream does not satisfy a required peer downstream, so strict package managers report the same unmet peer #1504 fixed for #1425 — now against @hono/node-server.

With strictPeerDependencies: true in pnpm (reached transitively through @strapi/core@5.54.0):

$ pnpm dedupe --check
[ERR_PNPM_PEER_DEP_ISSUES] Unmet peer dependencies

✕ missing peer hono
  Wanted:
    ^4:
      @hono/node-server@1.19.17
    ^4.11.4:
      @modelcontextprotocol/node@2.0.0

Today this is install-time only: #1896's evidence holds on 1.x, where the @hono/node-server root entry (getRequestListener, the only import in packages/middleware/node/src/streamableHttp.ts) never loads hono.

It becomes a runtime failure with #2574. From @hono/node-server@2.0.5 — the floor of the ^1.19.9 || ^2.0.5 range #2574 introduces — the root entry imports hono/ws at module load in both builds:

  • dist/index.mjs: import { defineWebSocketHelper } from "hono/ws";
  • dist/index.cjs: let hono_ws = require("hono/ws");

So once a consumer resolves 2.x without hono installed (which the optional peer explicitly allows), importing @modelcontextprotocol/node throws Cannot find module 'hono/ws'. Inside this monorepo hono is present for the Hono middleware package, which would keep the workspace build and tests green.

What did you expect?

@modelcontextprotocol/node's manifest to describe what it needs at runtime, so installs are clean under strict peer checking and a @hono/node-server bump cannot break consumers at import time.

Possible fixes, smallest first:

  1. Make hono a required peer again (revert fix(node): make hono an optional peer dependency #1896), or a direct dependency. One line; correct under every package manager and for both 1.x and 2.x. Costs a hono install for Node-middleware users.
  2. Drop @hono/node-server altogether. The package already ships its own hono-free Node ↔ Fetch bridge: toWebRequest / toNodeHandler (same dist/index.mjs) convert the request, stream the response with drain backpressure, and abort on client disconnect. NodeStreamableHTTPServerTransport is the only remaining getRequestListener caller; moving it onto that code would remove both @hono/node-server and the hono peer from the package (in the spirit of Optional install of HTTP/SSE transport deps (express, hono) for stdio-only servers #1924), and would make fix(node): widen @hono/node-server past GHSA-frvp-7c67-39w9 #2574 unnecessary for this package. It needs a check that the transport's SSE paths behave the same through it.

(1) is the quick, safe fix and should probably land with or before #2574; (2) is the cleaner end state.

Code to reproduce

// Clean project, pnpm, no `hono` installed.
// pnpm-workspace.yaml: strictPeerDependencies: true
// pnpm add @modelcontextprotocol/node @modelcontextprotocol/server
//   -> ERR_PNPM_PEER_DEP_ISSUES: missing peer hono (wanted by @hono/node-server)
//
// With @hono/node-server resolved to >= 2.0.5 (e.g. via #2574, or an override):
import { NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';
// -> Error: Cannot find module 'hono/ws'

SDK version

@modelcontextprotocol/node@2.0.0 (2.1.0 ships the same dependencies / peerDependencies); @hono/node-server@1.19.17 today, 2.0.5–2.1.1 checked for the hono/ws import.

Related: #1425, #1504, #1896, #1924, #1964, #2531, #2548, #2574.

Activity

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

    v2Ideas, 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