Compare commits

...

3 commits

Author SHA1 Message Date
Jeremiah Lowin
615fdf80fd
Avoid duplicate fastmcp console script 2026-05-22 18:41:19 -04:00
Jeremiah Lowin
f800c75842
Configure ty fastmcp source path 2026-05-22 18:31:10 -04:00
Jeremiah Lowin
b3f00d01e7
Fix fastmcp slim upgrade layout 2026-05-22 18:25:05 -04:00
6 changed files with 66 additions and 12 deletions

View file

@ -145,7 +145,7 @@ jobs:
import fastmcp
import fastmcp.settings
assert any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts"))
assert not any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts"))
try:
from fastmcp.cli import app
@ -174,7 +174,7 @@ jobs:
from fastmcp.client.transports import StdioTransport, StreamableHttpTransport
from fastmcp.mcp_config import MCPConfig
assert any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts"))
assert not any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts"))
try:
from fastmcp.cli import app
@ -207,10 +207,7 @@ jobs:
from fastmcp import FastMCP
from fastmcp.cli import app
assert any(
ep.name == "fastmcp" and ep.value == "fastmcp.cli:app"
for ep in entry_points(group="console_scripts")
)
assert not any(ep.name == "fastmcp" for ep in entry_points(group="console_scripts"))
mcp = FastMCP("smoke")
assert app is not None
@ -235,7 +232,9 @@ jobs:
assert not any("fastmcp-slim[full" in req for req in fastmcp_reqs)
assert any(
ep.name == "fastmcp" and ep.value == "fastmcp.cli:app"
ep.name == "fastmcp"
and ep.value == "fastmcp.cli:app"
and ep.dist.name == "fastmcp"
for ep in entry_points(group="console_scripts")
)

View file

@ -62,6 +62,23 @@ Alternatively, wait for the stable v5 release. See [this issue](https://github.c
</Info>
## Upgrading
### From FastMCP 3.3.0 or 3.3.1
FastMCP 3.3.2 repairs a package split issue that could affect environments upgraded from FastMCP 3.2.x with pip. Upgrade to the latest release to restore both the `fastmcp` import package and the `fastmcp` CLI:
```bash
python -m pip install --upgrade fastmcp
uv pip install --upgrade fastmcp
uv sync --upgrade-package fastmcp
```
For an environment that still has missing package files after upgrading, reinstall the paired packages:
```bash
python -m pip install --upgrade --force-reinstall fastmcp fastmcp-slim
uv pip install --upgrade --reinstall-package fastmcp --reinstall-package fastmcp-slim fastmcp
```
### From FastMCP 2.0
See the [Upgrade Guide](/getting-started/upgrading/from-fastmcp-2) for a complete list of breaking changes and migration steps.

View file

@ -0,0 +1 @@
fastmcp_slim

View file

@ -41,9 +41,6 @@ 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"
@ -55,7 +52,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"

View file

@ -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"
@ -138,6 +141,7 @@ exclude = ["**/node_modules", "**/__pycache__", ".venv", ".git", "dist"]
[tool.ty.environment]
python-version = "3.10"
extra-paths = ["fastmcp_slim"]
[tool.ty.rules]
division-by-zero = "warn"

View file

@ -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,32 @@ 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 "[project.scripts]" not in pyproject
assert 'fastmcp = "fastmcp.cli:app"' not in pyproject
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"