From 1ee9ca8603599365f1f4124f62bd33fefa126ff7 Mon Sep 17 00:00:00 2001 From: guptaishaan Date: Tue, 4 Aug 2026 13:53:24 -0700 Subject: [PATCH] fix(fetch): cap mcp dependency below 2.0 mcp>=1.1.3 had no upper bound, so a fresh `uvx mcp-server-fetch` resolved mcp 2.0.0. That release renamed McpError to MCPError and removed the low-level Server decorators, so server.py raised ImportError at line 6 and exited before writing an initialize response. Clients reported "connection closed: initialize response". Cap the requirement at mcp>=1.1.3,<2 and refresh uv.lock to match. The lock already pinned mcp 1.28.1, so CI was unaffected; only fresh resolves broke. Not a port to mcp 2.0: list_tools, list_prompts, call_tool, and get_prompt are all gone from the low-level Server and server.py uses all four. Verified with a real stdio handshake on Python 3.12. The published 2026.7.10 returns no initialize response; a wheel built from this change resolves mcp 1.29.0 and answers tools/list with ['fetch']. tests/test_dependencies.py covers the specifier. --- src/fetch/pyproject.toml | 2 +- src/fetch/tests/test_dependencies.py | 20 ++++++++++++++++++++ src/fetch/uv.lock | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/fetch/tests/test_dependencies.py diff --git a/src/fetch/pyproject.toml b/src/fetch/pyproject.toml index 84735f278a..4cbf1e0b2c 100644 --- a/src/fetch/pyproject.toml +++ b/src/fetch/pyproject.toml @@ -18,7 +18,7 @@ classifiers = [ dependencies = [ "httpx>=0.27", "markdownify>=0.13.1", - "mcp>=1.1.3", + "mcp>=1.1.3,<2", "protego>=0.3.1", "pydantic>=2.0.0", "readabilipy>=0.2.0", diff --git a/src/fetch/tests/test_dependencies.py b/src/fetch/tests/test_dependencies.py new file mode 100644 index 0000000000..affd85ebec --- /dev/null +++ b/src/fetch/tests/test_dependencies.py @@ -0,0 +1,20 @@ +"""Tests for the fetch MCP server's declared dependencies.""" + +import tomllib +from pathlib import Path + +from packaging.requirements import Requirement +from packaging.version import Version + +PYPROJECT = Path(__file__).parent.parent / "pyproject.toml" + + +def test_mcp_requirement_excludes_2_x(): + """The server uses the mcp 1.x low-level API, which mcp 2.0 removed. + + Without an upper bound, `uvx mcp-server-fetch` resolves mcp 2.x and the + server dies on import. + """ + dependencies = tomllib.loads(PYPROJECT.read_text())["project"]["dependencies"] + mcp = next(r for r in map(Requirement, dependencies) if r.name == "mcp") + assert not mcp.specifier.contains(Version("2.0.0")) diff --git a/src/fetch/uv.lock b/src/fetch/uv.lock index d79e776d42..95a8ac4006 100644 --- a/src/fetch/uv.lock +++ b/src/fetch/uv.lock @@ -588,7 +588,7 @@ dev = [ requires-dist = [ { name = "httpx", specifier = ">=0.27" }, { name = "markdownify", specifier = ">=0.13.1" }, - { name = "mcp", specifier = ">=1.1.3" }, + { name = "mcp", specifier = ">=1.1.3,<2" }, { name = "protego", specifier = ">=0.3.1" }, { name = "pydantic", specifier = ">=2.0.0" }, { name = "readabilipy", specifier = ">=0.2.0" },