modelcontextprotocol / modelcontextprotocol/typescript-sdk

[MCP-SDK] stdio client crashes with "MCP error -32000: Connection closed" when spawned server exits unexpectedly

Open
#1,049 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P2 ready for work
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

Describe the bug
A clear and concise description of what the bug is.

🐛 Bug description

When using @modelcontextprotocol/sdk in stdio mode, the child server process exits almost immediately after spawn.
The client then receives MCP error -32000: Connection closed and the whole Node.js process terminates via triggerUncaughtException because the rejection is not handled.

📋 Reproduction steps

  1. Clone demo repo
   git clone https://github.com/masx200/mcp-demo-streamable-http-bridge.git
   cd mcp-demo-streamable-http-bridge
   npm i
Build / start the server bundle

npm run build   # outputs dist/server.js
Run the client (stdio mode)

npm run dev     # spawns `node dist/server.js` internally
Observe crash within 1 s.
✅ Expected behavior
Client should either:
keep the connection alive, or
emit a catch-able error instead of killing the entire process.
❌ Actual behavior

McpError: MCP error -32000: Connection closed
    at Client._onclose (file:///D:/github/…/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:130:23)
    …
    at ChildProcess._handle.onexit (node:internal/child_process:305:5)
Node.js v24.10.0 then calls triggerUncaughtException and exits with code 1.

To Reproduce
Steps to reproduce the behavior:
1.

pnpx cross-env "NODE_OPTIONS=--trace-warnings --trace-uncaught" node  D:\github\mcp-demo-streamable-http-bridge\main.js --config "F:\projects\test\settings.json" --port 41111

Expected behavior
A clear and concise description of what you expected to happen.

Logs
If applicable, add logs to help explain your problem.

file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:109
        const error = new McpError(ErrorCode.ConnectionClosed, 'Connection closed');
                      ^

McpError: MCP error -32000: Connection closed
    at Client._onclose (file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:109:23)
    at _transport.onclose (file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:76:18)
    at ChildProcess.<anonymous> (file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js:95:77)
    at ChildProcess.emit (node:events:508:28)
    at cp.emit (D:\github\mcp-demo-streamable-http-bridge\node_modules\.store\cross-spawn@7.0.6\node_modules\cross-spawn\lib\enoent.js:34:29)
    at maybeClose (node:internal/child_process:1101:16)
    at ChildProcess._handle.onexit (node:internal/child_process:305:5) {
  code: -32000,
  data: undefined
}
Thrown at:
    at _onclose (file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:109:23)
    at _transport.onclose (file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js:76:18)
    at file:///D:/github/mcp-demo-streamable-http-bridge/node_modules/.store/@modelcontextprotocol+sdk@1.20.2/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js:95:77
    at emit (node:events:508:28)
    at cp.emit (D:\github\mcp-demo-streamable-http-bridge\node_modules\.store\cross-spawn@7.0.6\node_modules\cross-spawn\lib\enoent.js:34:29)
    at maybeClose (node:internal/child_process:1101:16)
    at ChildProcess._handle.onexit (node:internal/child_process:305:5)


Node.js v24.10.0

Additional context
Add any other context about the problem here.

 process.on("uncaughtException", (error) => {
   console.error("Uncaught exception:", error);
})

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the linked demo commands, then inspect the close path in dist/esm/shared/protocol.js and dist/esm/client/stdio.js shown in the stack trace. Compare the child-process exit handling with the expected catchable-error behavior, and verify the result by rerunning the stdio client without an uncaught process termination.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.