docs/python-sdk/fastmcp-server-transforms-search-base.mdx
fastmcp.server.transforms.search.baseBase class for search transforms.
Search transforms replace list_tools() output with a small set of
synthetic tools — a search tool and a call-tool proxy — so LLMs can
discover tools on demand instead of receiving the full catalog.
All concrete search transforms (RegexSearchTransform,
BM25SearchTransform, etc.) inherit from BaseSearchTransform and
implement _make_search_tool() and _search() to provide their
specific search strategy.
Example::
from fastmcp import FastMCP
from fastmcp.server.transforms.search import RegexSearchTransform
mcp = FastMCP("Server")
@mcp.tool
def add(a: int, b: int) -> int: ...
@mcp.tool
def multiply(x: float, y: float) -> float: ...
# Clients now see only ``search_tools`` and ``call_tool``.
# The original tools are discoverable via search.
mcp.add_transform(RegexSearchTransform())
serialize_tools_for_output_json <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/transforms/search/base.py#L60" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>serialize_tools_for_output_json(tools: Sequence[Tool]) -> list[dict[str, Any]]
Serialize tools to the same dict format as list_tools output.
serialize_tools_for_output_markdown <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/transforms/search/base.py#L138" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>serialize_tools_for_output_markdown(tools: Sequence[Tool]) -> str
Serialize tools to compact markdown, using ~65-70% fewer tokens than JSON.
BaseSearchTransform <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/transforms/search/base.py#L154" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>Replace the tool listing with a search interface.
When this transform is active, list_tools() returns only:
always_visible (pinned).Hidden tools remain callable — get_tool() delegates unknown
names downstream, so direct calls and the call-tool proxy both work.
Search results respect the full auth pipeline: middleware, visibility transforms, and component-level auth checks all apply.
Args:
max_results: Maximum number of tools returned per search.always_visible: Tool names that stay in the list_tools
output alongside the synthetic search/call tools.search_tool_name: Name of the generated search tool.call_tool_name: Name of the generated call-tool proxy.Methods:
transform_tools <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/transforms/search/base.py#L199" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>transform_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]
Replace the catalog with pinned + synthetic search/call tools.
get_tool <sup><a href="https://github.com/PrefectHQ/fastmcp/blob/main/src/fastmcp/server/transforms/search/base.py#L204" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>get_tool(self, name: str, call_next: GetToolNext) -> Tool | None
Intercept synthetic tool names; delegate everything else.