Body:
Environment
OS: Windows 11 (native, not WSL)
Python: 3.12.10
Atlas: 0.1.0a1, installed via pip install -e ".[dev]"
Bug
_stdio_loop() in atlas_core/adapters/claude_code.py calls:
python
await loop.connect_read_pipe(lambda: transport_protocol, sys.stdin)
This raises NotImplementedError on native Windows Python, under both ProactorEventLoop and SelectorEventLoop. connect_read_pipe() for stdin has never been implemented on Windows — this is a long-standing CPython limitation (see bpo-26832, migrated to python/cpython#71019 and python/cpython#87694).
Repro
powershell
echo {"jsonrpc":"2.0","id":1,"method":"initialize","params":{}} | python -m atlas_core.adapters.claude_code
File "...\atlas_core\adapters\claude_code.py", line 137, in _stdio_loop
await loop.connect_read_pipe(lambda: transport_protocol, sys.stdin)
...
NotImplementedError
Practical effect: claude mcp add for this server succeeds, but Claude Code reports Failed to connect — MCP server "atlas" connection timed out after 30000ms, since the subprocess crashes on startup before completing the MCP handshake.
Fix
Replace the connect_read_pipe()-based reader with a background thread feeding an asyncio.Queue, which works identically on Windows, macOS, and Linux:
python
async def _stdio_loop() -> None:
"""Read JSON-RPC requests from stdin, dispatch, write responses to stdout.
Windows note: uses a background thread + asyncio.Queue instead of
loop.connect_read_pipe(), since that call is unimplemented on Windows
for stdin under both ProactorEventLoop and SelectorEventLoop.
Spec: 05 - Atlas Architecture & Schema § 2 (API Layer).
"""
server, driver = await _build_server()
loop = asyncio.get_running_loop()
queue: asyncio.Queue = asyncio.Queue()
def _read_stdin() -> None:
try:
for raw_line in sys.stdin.buffer:
loop.call_soon_threadsafe(queue.put_nowait, raw_line)
finally:
loop.call_soon_threadsafe(queue.put_nowait, None)
reader_thread = threading.Thread(target=_read_stdin, daemon=True)
reader_thread.start()
try:
while True:
line = await queue.get()
if line is None:
break
line_str = line.decode("utf-8").strip()
if not line_str:
continue
try:
req = json.loads(line_str)
except json.JSONDecodeError as exc:
sys.stdout.write(json.dumps(_err(None, -32700, str(exc))) + "\n")
sys.stdout.flush()
continue
try:
response = await _handle(server, req)
except Exception as exc:
log.exception("dispatch failed")
response = _err(req.get("id"), -32603, f"{type(exc).__name__}: {exc}")
if response is not None:
sys.stdout.write(json.dumps(response) + "\n")
sys.stdout.flush()
finally:
await driver.close()
(needs import threading added at the top). Confirmed working on Windows after this change — claude mcp list shows atlas as connected, and manual initialize requests return a correct response. No behavior change on Unix, since the thread-based reader works there too.
Body:
Environment
OS: Windows 11 (native, not WSL)
Python: 3.12.10
Atlas: 0.1.0a1, installed via pip install -e ".[dev]"
Bug
_stdio_loop() in atlas_core/adapters/claude_code.py calls:
python
await loop.connect_read_pipe(lambda: transport_protocol, sys.stdin)
This raises NotImplementedError on native Windows Python, under both ProactorEventLoop and SelectorEventLoop. connect_read_pipe() for stdin has never been implemented on Windows — this is a long-standing CPython limitation (see bpo-26832, migrated to python/cpython#71019 and python/cpython#87694).
Repro
powershell
echo {"jsonrpc":"2.0","id":1,"method":"initialize","params":{}} | python -m atlas_core.adapters.claude_code
File "...\atlas_core\adapters\claude_code.py", line 137, in _stdio_loop
await loop.connect_read_pipe(lambda: transport_protocol, sys.stdin)
...
NotImplementedError
Practical effect: claude mcp add for this server succeeds, but Claude Code reports Failed to connect — MCP server "atlas" connection timed out after 30000ms, since the subprocess crashes on startup before completing the MCP handshake.
Fix
Replace the connect_read_pipe()-based reader with a background thread feeding an asyncio.Queue, which works identically on Windows, macOS, and Linux:
python
async def _stdio_loop() -> None:
"""Read JSON-RPC requests from stdin, dispatch, write responses to stdout.
(needs import threading added at the top). Confirmed working on Windows after this change — claude mcp list shows atlas as connected, and manual initialize requests return a correct response. No behavior change on Unix, since the thread-based reader works there too.