Skip to content

[Bug]: gsd --mode mcp fails with Cannot find module for @modelcontextprotocol/sdk/dist/cjs/server/stdio on SDK ≥ 1.28.x #3914

@charlesangus

Description

@charlesangus

Bug type

Regression (worked before, now fails)

Summary

Error:
[gsd] uncaught extension error (non-fatal): Cannot find module
'/…/gsd-pi/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio'
Error: Cannot find module '…/dist/cjs/server/stdio'
at createEsmNotFoundErr (node:internal/modules/cjs/loader:1493:15)

at startMcpServer (…/gsd-pi/dist/mcp-server.js:26:44)

Steps to reproduce

npm install -g gsd-pi
gsd --mode mcp

Expected behavior

MCP server should run.

Actual behavior

GSD shows the error message posted above.

GSD version

2.67

Node.js version

v24.14.0

Operating system

Kubuntu 24

Install method

npm global install

Affected area

MCP / tools / extensions

Model and provider

No response

Logs, screenshots, and evidence

Impact

No response

Additional information

Symptom

Running gsd --mode mcp (or having Claude Code load the gsd MCP server from settings.json) fails with:

[gsd] uncaught extension error (non-fatal): Cannot find module
'.../gsd-pi/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio'

followed by a similar error for dist/cjs/types.

Root cause

mcp-server.js uses createRequire + require.resolve() to resolve two SDK subpaths that are not explicitly listed in
@modelcontextprotocol/sdk's package.json exports map:

_require.resolve(${MCP_PKG}/server/stdio) // → not in exports
_require.resolve(${MCP_PKG}/types) // → not in exports

The SDK's exports map has a wildcard entry:
"./": { "require": "./dist/cjs/" }

On Node ≤22 this worked because the CJS resolver auto-appended .js. On Node v24, wildcard exports resolved through
finalizeEsmResolution no longer auto-append .js, so dist/cjs/server/stdio (no extension) is searched and not
found even though dist/cjs/server/stdio.js exists.

Workaround

Add explicit exports to node_modules/gsd-pi/node_modules/@modelcontextprotocol/sdk/package.json:

"./server/stdio": {
"import": "./dist/esm/server/stdio.js",
"require": "./dist/cjs/server/stdio.js"
},
"./types": {
"import": "./dist/esm/types.js",
"require": "./dist/cjs/types.js"
}

Suggested fix

Either:

  1. In gsd-pi mcp-server.js: Avoid require.resolve() for unlisted subpaths. Since StdioServerTransport isn't
    re-exported from @modelcontextprotocol/sdk/server, one option is to resolve the file path directly:
    const sdkRoot = path.dirname(_require.resolve(${MCP_PKG}/package.json));
    const stdioMod = await import(path.join(sdkRoot, 'dist/cjs/server/stdio.js'));
  2. Upstream in @modelcontextprotocol/sdk: Add explicit named exports for ./server/stdio and ./types so wildcard
    resolution isn't needed for these common subpaths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions