modelcontextprotocol / modelcontextprotocol/typescript-sdk

onerror and other listener not remove after client close (stdio)

Open
#780 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug fix proposed 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

This is my first time using MCP. I noticed that after closing the MCP client, there's an issue with JSON parsing failure. I'm not entirely sure whether the problem lies with the server or the SDK, and I hope to get some assistance. thanks~

To Reproduce

create a new mcp client

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

function createTransport() {
  let transport: StdioClientTransport;

  transport = new StdioClientTransport({
    command: "uvx",
    args: ["docker-mcp"],
    stderr: "pipe",
  });
  transport.onerror = async (error) => {
    console.log("error", error);
  };
  transport.onclose = async () => {
    console.log("close");
  };

  return transport;
}

const client = new Client(
  { name: "shellRaining", version: "1.0.0" },
  { capabilities: {} },
);

const transport = createTransport();
client.connect(transport);

await new Promise((resolve) => {
  setTimeout(resolve, 1000);
});

await transport.close()
await client.close()

then run this project, it will show below error message

close
error 21 |     clear() {
22 |         this._buffer = undefined;
23 |     }
24 | }
25 | export function deserializeMessage(line) {
26 |     return JSONRPCMessageSchema.parse(JSON.parse(line));
                                                ^
SyntaxError: JSON Parse error: Unexpected identifier "Shutting"
      at deserializeMessage (/Users/shellraining/Documents/playground/mcp/typescript-sdk/dist/esm/shared/stdio.js:26:44)
      at processReadBuffer (/Users/shellraining/Documents/playground/mcp/typescript-sdk/dist/esm/client/stdio.js:141:50)
      at <anonymous> (/Users/shellraining/Documents/playground/mcp/typescript-sdk/dist/esm/client/stdio.js:103:22)
      at emit (node:events:95:22)
      at addChunk (internal:streams/readable:265:47)
      at readableAddChunkPushByteMode (internal:streams/readable:243:18)
      at handleNumberResult (internal:streams/native-readable:69:18)
      at <anonymous> (internal:streams/native-readable:43:68)

Expected behavior

not occur error message

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 issue with the provided TypeScript client and start at the processReadBuffer path in dist/esm/client/stdio.js, then inspect deserializeMessage in dist/esm/shared/stdio.js. Check how close affects the stdio listeners and buffered input. Done means closing the client does not emit the reported JSON parsing error or leave the error and other listeners active.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
devtools
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.