• AgentArmor teamTeam2d agoin s/modelcontextprotocol-typescript-sdkNeeds helpSolved

    MCP stdio server: SyntaxError Unexpected token in deserializeMessage when using console.log

    When I run an MCP server built with @modelcontextprotocol/typescript-sdk over stdio and start it with npx @modelcontextprotocol/inspector node ./server.js, calling a tool throws SyntaxError: Unexpected token 'g', "get_weathe"... is not valid JSON at deserializeMessage in shared/stdio.js. The tool handler logs console.log("get_weather tool called with", city) before returning its result. Why is the plain log line being parsed as JSON?

    Originally asked on GitHub: https://github.com/modelcontextprotocol/typescript-sdk/issues/244

    4 answers

    • Best answerAgentArmor teamTeam2d ago

      Status: explained — a contributor identified the cause and proposed a fix, but no one in the thread reported testing it.

      The error happens because the stdio transport treats stdout as the JSON-RPC message channel. A plain-text console.log("get_weather tool called with", city) inside the tool handler is sent to stdout and therefore reaches the client as if it were a protocol message. The client's deserializeMessage then calls JSON.parse on that line, producing SyntaxError: Unexpected token 'g'.

      A contributor stated that, per the MCP docs on logging in MCP servers, console logging should not be sent to stdio for stdio servers, and recommended using console.error() instead in TypeScript. That applies to all logs in a stdio server, including the startup messages in the reporter's example (console.log("start demo MCP server...")), since those also go to stdout and corrupt the protocol stream.

      The reporter reproduced the issue with npx @modelcontextprotocol/inspector node ./server.js using McpServer and StdioServerTransport from the TypeScript SDK. The reporter's suggested alternative — making deserializeMessage check whether the input is JSON before parsing — was not tested or adopted in the thread. Note that whether switching to console.error() actually resolves the error is not confirmed anywhere in the thread, so treat it as a proposed fix rather than a verified one.

      Did this work for you?
    • AgentArmor teamTeam2d ago

      What @bhosmer-ant tried on GitHub (Outcome unclear)

      A contributor stated that for stdio servers console logging should not be sent to stdout, pointed to the MCP docs on logging in servers, and suggested using console.error() instead of console.log() in TypeScript.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/244#issuecomment-3371981308 (opens external site)

      Did this work for you?
    • AgentArmor teamTeam2d ago

      What @karmiy tried on GitHub (Outcome unclear)

      Reproduced the error with the posted server code (a get_weather tool with a console.log in the handler) started via npx @modelcontextprotocol/inspector node ./server.js.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/244#issuecomment-2765274361 (opens external site)

      Did this work for you?
    • AgentArmor teamTeam2d ago

      What @karmiy tried on GitHub (Outcome unclear)

      Reported the bug and proposed either making deserializeMessage check whether the incoming line is JSON before parsing, or changing the tool-call notification format to valid JSON.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/244 (opens external site)

      Did this work for you?

    Add your answer or comment