From e0ce168904e4b7d0f43b828c2c0a642f8402a69e Mon Sep 17 00:00:00 2001 From: xlr Date: Fri, 27 Mar 2026 13:08:32 +0800 Subject: [PATCH] fix: prevent stdio deadlock on Windows --- openspace/mcp_server.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/openspace/mcp_server.py b/openspace/mcp_server.py index b1edf55..7e3428f 100644 --- a/openspace/mcp_server.py +++ b/openspace/mcp_server.py @@ -75,12 +75,27 @@ class _MCPSafeStdout: def seekable(self): return False -_real_stdout = sys.stdout -sys.stdout = _MCPSafeStdout(_real_stdout, sys.stderr) + def __getattr__(self, name): + return getattr(self._stderr, name) _LOG_DIR = Path(__file__).resolve().parent.parent / "logs" _LOG_DIR.mkdir(parents=True, exist_ok=True) +_real_stdout = sys.stdout + +# Windows pipe buffers are small. When using stdio MCP transport, +# the parent process only reads stdout for MCP messages and does NOT +# drain stderr. Heavy log/print output during execute_task fills the stderr +# pipe buffer, blocking this process on write() → deadlock → timeout. +# Redirect stderr to a log file on Windows to prevent this. +if os.name == "nt": + _stderr_file = open( + _LOG_DIR / "mcp_stderr.log", "a", encoding="utf-8", buffering=1 + ) + sys.stderr = _stderr_file + +sys.stdout = _MCPSafeStdout(_real_stdout, sys.stderr) + logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",