modelcontextprotocol / modelcontextprotocol/typescript-sdk
[MCP-SDK] stdio client crashes with "MCP error -32000: Connection closed" when spawned server exits unexpectedly
Nobody has claimed this yet.
- 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
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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