Windows 上 stderr 太吵会堵死 stdio MCP
stdout 已经是干净 JSON-RPC,Windows 上 Codex 仍 Transport closed。约 4KB 的 stderr 管道没人读就会堵死子进程。把 stderr 重定向到日志文件,不要默认丢进 NUL。
stdout 探测第一行已经是 { 开头的 JSON,手工 printf 管道也能握手,Claude / Copilot / Cursor 都正常,只有 原生 Windows 上的 Codex 报 Transport closed:先查 stderr,不要先换服务器实现。
Windows 给子进程的 stderr 管道大约 4KB。MCP 服务器启动时把依赖树、SQL 警告、框架横幅打到 stderr,没人读就会把写端堵住,进程看起来像立刻断连。这和 stdout 混了非 JSON 不是同一条坑;也不是 Python 握手字节到不了客户端——Node 服务器往往还能被别的客户端正常调用。
权宜是让 cmd 把 stderr 重定向到文件,并给够启动超时:
[mcp_servers.docs]
command = "cmd"
args = ["/c", "node C:\\Users\\you\\mcp-server\\index.js 2>C:\\temp\\mcp-stderr.log"]
startup_timeout_sec = 60
enabled = true
优先写日志文件,不要一上来 2>NUL:管道不堵了,启动失败也看不见。改完必须新开会话,旧线程不会重拉 MCP。
这条只针对原生 Windows。桌面开了 WSL 代理时,不要把 command = "cmd" 抄进 Linux 侧 config——那会变成另一条 invalid transport。WSL 里用 bash 重定向:args = ["-lc", "node ./server.js 2>/tmp/mcp-stderr.log"]。HTTP MCP 走 url,不受这条管道限制。