Skip to content

Commit a64fd08

Browse files
committed
fix(mcp): support stdio transport on Windows
Windows asyncio event loops do not implement add_signal_handler, causing the stdio server to exit before serving requests. Treat signal registration as optional and cover the unsupported-loop path with a regression test.
1 parent ebee248 commit a64fd08

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

openbb_platform/extensions/mcp_server/openbb_mcp_server/app/app.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,12 @@ def signal_handler():
942942
os._exit(0) # pylint: disable=protected-access
943943

944944
for sig in (signal.SIGINT, signal.SIGTERM):
945-
loop.add_signal_handler(sig, signal_handler)
945+
try:
946+
loop.add_signal_handler(sig, signal_handler)
947+
except NotImplementedError:
948+
# Windows event loops do not support signal handlers. The MCP client
949+
# owns the stdio child process and closes it directly.
950+
break
946951

947952
logger.info("Starting OpenBB MCP Server in STDIO mode. Press Ctrl+C to stop.")
948953

openbb_platform/extensions/mcp_server/tests/app/test_app.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Unit tests for app module."""
22

3+
import asyncio
34
from unittest.mock import MagicMock, patch
45

56
import pytest
@@ -13,6 +14,7 @@
1314
_read_system_prompt_file,
1415
_strip_api_prefix,
1516
create_mcp_server,
17+
stdio_main,
1618
)
1719
from openbb_mcp_server.models.settings import MCPSettings
1820

@@ -56,6 +58,18 @@ def test_read_system_prompt_file(tmp_path):
5658
assert _read_system_prompt_file("nonexistent.txt") is None
5759

5860

61+
@pytest.mark.asyncio
62+
async def test_stdio_main_runs_when_signal_handlers_are_unsupported():
63+
"""Windows event loops can serve stdio without registering signal handlers."""
64+
loop = asyncio.get_running_loop()
65+
mcp_server = MagicMock()
66+
67+
with patch.object(loop, "add_signal_handler", side_effect=NotImplementedError):
68+
await stdio_main(mcp_server)
69+
70+
mcp_server.run.assert_called_once_with("stdio")
71+
72+
5973
@patch("openbb_mcp_server.app.app.process_fastapi_routes_for_mcp")
6074
@patch("openbb_mcp_server.app.app.CategoryIndex")
6175
@patch("openbb_mcp_server.app.app.FastMCP.from_fastapi")

0 commit comments

Comments
 (0)