diff --git a/src/skillspector/mcp_server.py b/src/skillspector/mcp_server.py index e377d972..a27845a3 100644 --- a/src/skillspector/mcp_server.py +++ b/src/skillspector/mcp_server.py @@ -176,6 +176,11 @@ def build_server(name: str = "skillspector", *, allow_local_targets: bool = Fals try: from mcp.server.fastmcp import FastMCP except ModuleNotFoundError as exc: + if exc.name != "mcp": + raise ModuleNotFoundError( + "The installed 'mcp' package is incompatible with the SkillSpector " + "MCP server. Reinstall with: pip install 'skillspector[mcp]'" + ) from exc raise ModuleNotFoundError( "The MCP server requires the optional 'mcp' dependency. " "Install it with: pip install 'skillspector[mcp]'" diff --git a/tests/unit/test_mcp_server.py b/tests/unit/test_mcp_server.py index 3e7243c3..bccc9f4f 100644 --- a/tests/unit/test_mcp_server.py +++ b/tests/unit/test_mcp_server.py @@ -441,6 +441,23 @@ async def test_build_server_disables_local_targets_by_default( assert graph_ainvoke.await_count == 0 +def test_build_server_reports_incompatible_mcp(monkeypatch: pytest.MonkeyPatch) -> None: + """An installed package without FastMCP must not be reported as missing.""" + import builtins + + original_import = builtins.__import__ + + def import_without_fastmcp(name: str, *args: object, **kwargs: object) -> object: + if name == "mcp.server.fastmcp": + raise ModuleNotFoundError("No module named 'mcp.server.fastmcp'", name=name) + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", import_without_fastmcp) + + with pytest.raises(ModuleNotFoundError, match="installed 'mcp' package is incompatible"): + mcp_server.build_server() + + async def test_mcp_stdio_initialize_registers_scan_skill() -> None: """The real stdio CLI must initialize and expose the scan_skill tool.""" pytest.importorskip("mcp") diff --git a/uv.lock b/uv.lock index c4f6b6a8..b79cedaa 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.12, <3.15" resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'win32'",