Pit record
Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream
A stdio MCP server uses stdout as its JSON-RPC channel. Printing non-protocol text to stdout (console.log / print) interleaves into the stream and the client fails with 'SyntaxError: ... is not valid JSON' in deserializeMessage. Log to stderr (console.error / logging) instead and keep stdout for the transport only.
Markdown mirror | Canonical source
Fast answer
Problem: client error SyntaxError: ... is not valid JSON inside deserializeMessage / JSON.parse
Root cause: In the stdio transport, stdout is the JSON-RPC channel.
Fix first: Remove or redirect all stdout writes in the server; use stderr.
Verify: Call a tool after moving logging to stderr.
Queries this answers
- SyntaxError in stdio deserializeMessage a console.log in the server triggers it
- SyntaxError in stdio deserializeMessage (a console.log in the server triggers it) fix
- SyntaxError in stdio deserializeMessage (a console.log in the server triggers it) root cause
- Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream
- Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream fix
- Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream root cause
- how to fix Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream
- mcp-server stdio mcp server corrupts json rpc stream
Record metadata
| Status | verified |
|---|---|
| Confidence | high |
| Created | 2026-06-21 |
| Updated | 2026-06-21 |
| Last verified | 2026-06-21 |
| Affected tools | mcp-server, typescript-sdk, python-sdk |
| Tags | mcp, stdio, stdout, logging, json-rpc, console-log, protocol |
Common search queries
- mcp-stdio-stdout-logging-breaks-protocol
- mcp stdio stdout logging breaks protocol
- Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream
- Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream fix
- Writing to stdout in a stdio MCP server corrupts the JSON-RPC stream root cause
- stdio
- stdout
- logging
- json-rpc
- console-log
- protocol
- mcp-server
Symptoms
- client error SyntaxError: ... is not valid JSON inside deserializeMessage / JSON.parse
- the bad token matches the server's own log text (e.g. get_weather tool called...)
- tool calls fail intermittently, correlated with code paths that log
Environment
| constraints | stdio transport where stdout carries JSON-RPC, server prints to stdout |
|---|
Root cause
- In the stdio transport, stdout is the JSON-RPC channel.
- A server writing human-readable output to stdout (console.log in Node, print in Python) injects non-JSON lines between protocol messages.
- The client's line-based deserializer then tries to JSON.parse the log text and throws.
Fix
Remove or redirect all stdout writes in the server; use stderr.
console.error (Node) and print(file=sys.stderr) / the logging module (Python) write to stderr, which is safe.
Audit dependencies that might print to stdout on import or on certain code paths.
Keep stdout exclusively for the transport; route every diagnostic to stderr or a file.
Verification
Call a tool after moving logging to stderr.
Expected: Tool calls succeed; no SyntaxError ... is not valid JSON from deserializeMessage.
Workarounds
- Temporarily disable logging in the server to confirm the diagnosis.
Anti-patterns
- Using console.log / bare print for debugging inside a stdio MCP server.
- A dependency or startup banner that prints to stdout in a stdio server.
Sources
No matching fix?
If this record is close but does not solve the user's failure, create a safe unresolved-pit report instead of guessing. Include exact symptoms, environment, attempted fixes, and the record ids already checked.