From 176e6aef792ff30f667106203325140d670c1e94 Mon Sep 17 00:00:00 2001 From: Duy Le Huu Date: Sun, 23 Aug 2026 13:13:42 +0900 Subject: [PATCH] fix(ci): guard the MCP SDK import so pytest can collect the suite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `tests/test_project_context_mcp_template.py` imported `mcp` at module scope, but the SDK is a runtime dependency (requirements.txt) and is deliberately absent from requirements-test.txt — the only thing CI installs. Collection therefore aborted for the ENTIRE suite before a single test ran. The guard now sits inside the one test that touches the SDK, so the other cases in the file (pure-Python contract checks) keep running on CI instead of being skipped along with it. Unrelated to the R04 refactor; kept as its own commit so it can be cherry- picked to main on its own. Co-Authored-By: Claude Opus 5 --- tests/test_project_context_mcp_template.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_project_context_mcp_template.py b/tests/test_project_context_mcp_template.py index d5f0ae2..b88f435 100644 --- a/tests/test_project_context_mcp_template.py +++ b/tests/test_project_context_mcp_template.py @@ -14,7 +14,6 @@ from cowork_local.mcp_servers.project_context.registry import ( ) from cowork_local.mcp_servers.project_context.runtime import require_supported_python from cowork_local.mcp_servers.project_context.server import dispatch -from mcp import types EXPECTED_TOOLS = { "get_project_issue_context", @@ -88,6 +87,14 @@ def source() -> dict[str, str]: def test_template_exposes_exactly_three_provider_neutral_tools() -> None: + # The MCP SDK is a RUNTIME dependency (requirements.txt) and is deliberately + # absent from requirements-test.txt, which is all CI installs. Importing it at + # module scope aborted collection for the ENTIRE suite, so the guard lives here, + # inside the only test that touches the SDK. Guarding per-test rather than + # per-module keeps the other cases -- pure-Python contract checks that need no + # SDK -- running on CI instead of silently skipping with it. + types = pytest.importorskip("mcp.types") + assert set(TOOL_NAMES) == EXPECTED_TOOLS declarations = tool_declarations() assert {item["name"] for item in declarations} == EXPECTED_TOOLS