PrefectHQ/fastmcp · error · ValueError
At least one of 'tools', 'include_tags', or 'exclude_tags' i
Error message
At least one of 'tools', 'include_tags', or 'exclude_tags' is required
What it means
MCPConfig's transforming-server variant requires at least one FastMCP-specific filter to be meaningful: a 'tools' whitelist, 'include_tags', or 'exclude_tags'. Pydantic model validation raises ValueError when values is a dict with none of these set, because such a config would proxy everything unchanged.
Source
Thrown at fastmcp_slim/fastmcp/mcp_config.py:118
)
@model_validator(mode="before")
@classmethod
def _require_at_least_one_transform_field(
cls, values: dict[str, Any]
) -> dict[str, Any]:
"""Reject if none of the transforming fields are set.
This ensures that plain server configs (without tools, include_tags,
or exclude_tags) fall through to the base server types during union
validation, avoiding unnecessary proxy wrapping.
"""
if isinstance(values, dict):
has_tools = bool(values.get("tools"))
has_include = values.get("include_tags") is not None
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"View on GitHub (pinned to 1f02114297)
Solutions
- Add the tools you want to expose: tools=["tool_a","tool_b"]
- Set include_tags to the tags of components to include
- Set exclude_tags to filter out unwanted components
- If no filtering is wanted, use the plain canonical MCPConfig format instead of the transforming one
Example fix
// before
config = MCPConfig.from_dict({"mcpServers": {"srv": {"url": "https://x/mcp", "tools": [], "include_tags": null, "exclude_tags": null}}})
// after
config = MCPConfig.from_dict({"mcpServers": {"srv": {"url": "https://x/mcp", "tools": ["search"]}}}) Defensive patterns
Strategy: validation
Validate before calling
def transforming_config_ok(srv: dict) -> bool:
return bool(srv.get("tools")) or srv.get("include_tags") is not None or srv.get("exclude_tags") is not None Try / catch
from pydantic import ValidationError
try:
cfg = MCPConfig.from_dict(data)
except ValidationError as e:
... # surface which field is missing to the user Prevention
- Always specify at least one of tools/include_tags/exclude_tags in transforming configs
- Don't serialize empty lists/nulls for these fields; omit them or fill them
- Use the canonical config format when no filtering is needed
When it happens
Trigger: Constructing MCPConfig.from_dict / model_validate with a server dict that has transform-related keys present but all empty/None (e.g. tools: [], include_tags: null, exclude_tags: null), or omitting all three entirely while using the transforming config path.
Common situations: Copy-pasting a transforming-config example and clearing the example values; programmatically generating config where empty lists are serialized as falsy; a template leaving tags blank.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Invalid URL: {url}
- No MCP servers defined in the config: {file_path}
- identity_assertion.trusted_issuers must not be empty
- trusted_issuers entries must be non-empty strings
- The API key is empty
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/c940d404bbc6f8d7.
Report an issue: GitHub.