fix(mcp): raise ImportError instead of NameError when stdio SDK missing (#31450)
When the 'mcp' Python SDK isn't installed, _run_stdio leaked a bare 'NameError: name StdioServerParameters is not defined' because the top-level 'from mcp import ...' fails inside try/except ImportError, leaving the names unbound at module scope. Mirror the _MCP_HTTP_AVAILABLE gate that _run_http already had: raise a clear ImportError with install instructions instead. Fixes #30904
This commit is contained in:
@@ -1462,6 +1462,27 @@ class TestHTTPConfig:
|
|||||||
|
|
||||||
asyncio.run(_test())
|
asyncio.run(_test())
|
||||||
|
|
||||||
|
def test_stdio_unavailable_raises_importerror_not_nameerror(self):
|
||||||
|
"""Regression test for #30904.
|
||||||
|
|
||||||
|
When the mcp SDK isn't installed, ``_run_stdio`` previously leaked a
|
||||||
|
bare ``NameError: name 'StdioServerParameters' is not defined``. The
|
||||||
|
gate now raises a clear ``ImportError`` with install instructions,
|
||||||
|
mirroring ``_run_http``'s behaviour when the HTTP transport is
|
||||||
|
unavailable.
|
||||||
|
"""
|
||||||
|
from tools.mcp_tool import MCPServerTask
|
||||||
|
|
||||||
|
server = MCPServerTask("local")
|
||||||
|
config = {"command": "python3", "args": ["/tmp/echo.py"]}
|
||||||
|
|
||||||
|
async def _test():
|
||||||
|
with patch("tools.mcp_tool._MCP_AVAILABLE", False):
|
||||||
|
with pytest.raises(ImportError, match=r"mcp.*SDK"):
|
||||||
|
await server._run_stdio(config)
|
||||||
|
|
||||||
|
asyncio.run(_test())
|
||||||
|
|
||||||
def test_http_seeds_initial_protocol_header(self):
|
def test_http_seeds_initial_protocol_header(self):
|
||||||
from tools.mcp_tool import LATEST_PROTOCOL_VERSION, MCPServerTask
|
from tools.mcp_tool import LATEST_PROTOCOL_VERSION, MCPServerTask
|
||||||
|
|
||||||
|
|||||||
@@ -1255,6 +1255,15 @@ class MCPServerTask:
|
|||||||
|
|
||||||
async def _run_stdio(self, config: dict):
|
async def _run_stdio(self, config: dict):
|
||||||
"""Run the server using stdio transport."""
|
"""Run the server using stdio transport."""
|
||||||
|
if not _MCP_AVAILABLE:
|
||||||
|
raise ImportError(
|
||||||
|
f"MCP server '{self.name}' requires the 'mcp' Python SDK, but "
|
||||||
|
"it is not installed. Install with:\n"
|
||||||
|
" pip install 'hermes-agent[mcp]'\n"
|
||||||
|
"or (full install):\n"
|
||||||
|
" pip install 'hermes-agent[all]'"
|
||||||
|
)
|
||||||
|
|
||||||
command = config.get("command")
|
command = config.get("command")
|
||||||
args = config.get("args", [])
|
args = config.get("args", [])
|
||||||
user_env = config.get("env")
|
user_env = config.get("env")
|
||||||
|
|||||||
Reference in New Issue
Block a user