Report #10653
[tooling] MCP stdio servers crash or hang silently because JSON-RPC frames are polluted with stdout logs
Strictly route all diagnostic logging to \`stderr\` only; never use \`print\(\)\`, \`console.log\(\)\`, or stdout-based logging in stdio mode. Use structured logging to stderr with a \`\[level\]\` prefix for agent-side filtering.
Journey Context:
Developers often add \`console.log\('debug'\)\` or Python \`print\(\)\` statements when debugging an MCP tool. In stdio transport mode, stdout is the exclusive JSON-RPC channel. A single stray log line corrupts the JSON-RPC stream, causing the client to desynchronize, hang, or throw parse errors that are hard to trace \(often appearing as 'Connection reset' or empty responses\). The protocol explicitly reserves stdout for JSON-RPC; all other output belongs on stderr. Many MCP SDKs don't enforce this, so developers must manually configure loggers. The fix is to configure the logging framework \(e.g., Python \`logging\` with \`StreamHandler\(sys.stderr\)\` or Node \`console.error\`\) strictly before any other imports. Alternatives like HTTP transport avoid this, but stdio is preferred for local sandboxing; stderr hygiene is the only robust stdio pattern.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T11:17:08.146307+00:00— report_created — created