PrefectHQ/fastmcp · error · ImportError

MCP configs that use FastMCP-specific tool transforms or tag

Error message

MCP configs that use FastMCP-specific tool transforms or tag filters

What it means

_to_server_and_underlying_transport builds a FastMCP proxy server, which needs the full fastmcp package (Client, create_proxy, ToolTransform). When those imports fail — typically because only the slim/core package is installed — it raises ImportError with an install hint naming the feature that requires the full package.

Source

Thrown at fastmcp_slim/fastmcp/mcp_config.py:134

            has_exclude = values.get("exclude_tags") is not None
            if not (has_tools or has_include or has_exclude):
                raise ValueError(
                    "At least one of 'tools', 'include_tags', or 'exclude_tags' is required"
                )
        return values

    def _to_server_and_underlying_transport(
        self,
        server_name: str | None = None,
        client_name: str | None = None,
    ) -> tuple[Any, ClientTransport]:
        """Turn the transforming server into a FastMCP proxy and return its transport."""
        try:
            from fastmcp import Client
            from fastmcp.server import create_proxy
            from fastmcp.server.transforms import ToolTransform
        except ImportError as exc:
            raise ImportError(
                _install_hints.full_package(
                    "MCP configs that use FastMCP-specific tool transforms or tag filters"
                )
            ) from exc

        transport = cast("ClientTransport", super().to_transport())  # ty: ignore[unresolved-attribute]
        # The proxy that wraps this client forwards the initialize handshake and
        # server-initiated features, which require the legacy era.
        client = Client(transport=transport, name=client_name, mode="legacy")
        wrapped_mcp_server = create_proxy(client, name=server_name)

        if self.include_tags is not None:
            wrapped_mcp_server.enable(tags=self.include_tags, only=True)
        if self.exclude_tags is not None:
            wrapped_mcp_server.disable(tags=self.exclude_tags)
        if self.tools:
            wrapped_mcp_server.add_transform(
                ToolTransform(_coerce_tool_transform_configs(self.tools))

View on GitHub (pinned to 1f02114297)

Solutions

  1. Install the full package: pip/uv install fastmcp (not the slim variant)
  2. Remove tools/include_tags/exclude_tags from the config so the transforming path is not used
  3. Verify with 'python -c "from fastmcp import Client"' that the import works in the active environment

Example fix

// before
uv pip install fastmcp-slim
// after
uv pip install fastmcp
Defensive patterns

Strategy: try-catch

Validate before calling

try:
    from fastmcp import Client  # noqa
    FULL_FASTMCP = True
except ImportError:
    FULL_FASTMCP = False

Try / catch

try:
    transport = cfg.to_transport()
except ImportError as e:
    raise RuntimeError("Install the full fastmcp package: pip install fastmcp") from e

Prevention

When it happens

Trigger: Calling _to_server_and_underlying_transport (directly or via to_transport) on a transforming MCP config while fastmcp's client/server modules are not importable, e.g. running under 'fastmcp-slim' or a partial install.

Common situations: Projects that installed a slim distribution for server-only use but then load an MCP config that uses tool transforms or tag filters; CI environments with trimmed dependencies.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/5248b08f9f13a8f2. Report an issue: GitHub.