From b3f00d01e7539fe2c3a731be73738be7e23d8d36 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Fri, 22 May 2026 18:25:05 -0400 Subject: [PATCH] Fix fastmcp slim upgrade layout --- fastmcp_slim/fastmcp_slim.pth | 1 + fastmcp_slim/pyproject.toml | 7 ++++- pyproject.toml | 3 ++ tests/client/test_slim_package_boundaries.py | 31 +++++++++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 fastmcp_slim/fastmcp_slim.pth diff --git a/fastmcp_slim/fastmcp_slim.pth b/fastmcp_slim/fastmcp_slim.pth new file mode 100644 index 000000000..a0e6d7a00 --- /dev/null +++ b/fastmcp_slim/fastmcp_slim.pth @@ -0,0 +1 @@ +fastmcp_slim diff --git a/fastmcp_slim/pyproject.toml b/fastmcp_slim/pyproject.toml index 61b9e163c..c628b71ec 100644 --- a/fastmcp_slim/pyproject.toml +++ b/fastmcp_slim/pyproject.toml @@ -55,7 +55,12 @@ source = "uv-dynamic-versioning" allow-direct-references = true [tool.hatch.build.targets.wheel] -packages = ["fastmcp"] +bypass-selection = true +only-include = [] + +[tool.hatch.build.targets.wheel.force-include] +fastmcp = "fastmcp_slim/fastmcp" +"fastmcp_slim.pth" = "fastmcp_slim.pth" [tool.uv-dynamic-versioning] vcs = "git" diff --git a/pyproject.toml b/pyproject.toml index 1813bf0e7..8e7600d72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,9 @@ Homepage = "https://gofastmcp.com" Repository = "https://github.com/PrefectHQ/fastmcp" Documentation = "https://gofastmcp.com" +[project.scripts] +fastmcp = "fastmcp.cli:app" + [build-system] requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"] build-backend = "hatchling.build" diff --git a/tests/client/test_slim_package_boundaries.py b/tests/client/test_slim_package_boundaries.py index 5c6a4b073..3c2187765 100644 --- a/tests/client/test_slim_package_boundaries.py +++ b/tests/client/test_slim_package_boundaries.py @@ -4,10 +4,13 @@ import builtins import contextlib import types from collections.abc import Mapping, Sequence +from pathlib import Path from typing import Any, cast import pytest +PROJECT_ROOT = Path(__file__).resolve().parents[2] + @contextlib.contextmanager def block_server_imports(): @@ -40,7 +43,6 @@ def test_client_http_headers_do_not_require_server() -> None: assert get_http_headers(include_all=True) == {} -@pytest.mark.asyncio async def test_multiserver_config_requires_server_for_now() -> None: from fastmcp.client.transports import MCPConfigTransport @@ -59,3 +61,30 @@ async def test_multiserver_config_requires_server_for_now() -> None: ): async with transport.connect_session(): pass + + +def test_fastmcp_metapackage_delegates_to_slim() -> None: + pyproject = (PROJECT_ROOT / "pyproject.toml").read_text() + + assert 'dynamic = ["version", "dependencies", "optional-dependencies"]' in pyproject + assert "[project.scripts]" in pyproject + assert 'fastmcp = "fastmcp.cli:app"' in pyproject + assert "[tool.hatch.build.targets.wheel]" in pyproject + assert "bypass-selection = true" in pyproject + assert "only-include = []" in pyproject + assert 'exclude = ["/*"]' in pyproject + assert '"fastmcp-slim[client,server]=={{ version }}"' in pyproject + + +def test_fastmcp_slim_installs_private_import_root() -> None: + pyproject = (PROJECT_ROOT / "fastmcp_slim" / "pyproject.toml").read_text() + + assert "[tool.hatch.build.targets.wheel]" in pyproject + assert "bypass-selection = true" in pyproject + assert "only-include = []" in pyproject + assert "[tool.hatch.build.targets.wheel.force-include]" in pyproject + assert 'fastmcp = "fastmcp_slim/fastmcp"' in pyproject + assert '"fastmcp_slim.pth" = "fastmcp_slim.pth"' in pyproject + + pth_file = PROJECT_ROOT / "fastmcp_slim" / "fastmcp_slim.pth" + assert pth_file.read_text().strip() == "fastmcp_slim"