Modify tool schemas - rename, reshape arguments, and customize behavior
New in version 3.0.0Tool transformation lets you modify tool schemas - renaming tools, changing descriptions, adjusting tags, and reshaping argument schemas. FastMCP provides two mechanisms that share the same configuration options but differ in timing.Deferred transformation with ToolTransform applies modifications when tools flow through a transform chain. Use this for tools from mounted servers, proxies, or other providers where you don’t control the source directly.Immediate transformation with Tool.from_tool() creates a modified tool object right away. Use this when you have direct access to a tool and want to transform it before registration.
The ToolTransform class is a transform that modifies tools as they flow through a provider. Provide a dictionary mapping original tool names to their transformation configuration.
Copy
from fastmcp import FastMCPfrom fastmcp.server.transforms import ToolTransformfrom fastmcp.tools.tool_transform import ToolTransformConfigmcp = FastMCP("Server")@mcp.tooldef verbose_internal_data_fetcher(query: str) -> str: """Fetches data from the internal database.""" return f"Results for: {query}"# Rename the tool to something simplermcp.add_transform(ToolTransform({ "verbose_internal_data_fetcher": ToolTransformConfig( name="search", description="Search the database.", )}))# Clients see "search" with the cleaner description
ToolTransform is useful when you want to modify tools from mounted or proxied servers without changing the original source.
Use Tool.from_tool() when you have the tool object and want to create a transformed version for registration.
Copy
from fastmcp import FastMCPfrom fastmcp.tools import Tool, toolfrom fastmcp.tools.tool_transform import ArgTransform# Create a tool without registering it@tooldef search(q: str, limit: int = 10) -> list[str]: """Search for items.""" return [f"Result {i} for {q}" for i in range(limit)]# Transform it before registrationbetter_search = Tool.from_tool( search, name="find_items", description="Find items matching your search query.", transform_args={ "q": ArgTransform( name="query", description="The search terms to look for.", ), },)mcp = FastMCP("Server")mcp.add_tool(better_search)
The standalone @tool decorator (from fastmcp.tools) creates a Tool object without registering it to any server. This separates creation from registration, letting you transform tools before deciding where they go.
For advanced scenarios, provide a transform_fn that intercepts tool execution. The function can validate inputs, modify outputs, or add custom logic while still calling the original tool via forward().
Copy
from fastmcp import FastMCPfrom fastmcp.tools import Tool, toolfrom fastmcp.tools.tool_transform import forward, ArgTransform@tooldef divide(a: float, b: float) -> float: """Divide a by b.""" return a / basync def safe_divide(numerator: float, denominator: float) -> float: if denominator == 0: raise ValueError("Cannot divide by zero") return await forward(numerator=numerator, denominator=denominator)safe_division = Tool.from_tool( divide, name="safe_divide", transform_fn=safe_divide, transform_args={ "a": ArgTransform(name="numerator"), "b": ArgTransform(name="denominator"), },)mcp = FastMCP("Server")mcp.add_tool(safe_division)
The forward() function handles argument mapping automatically. Call it with the transformed argument names, and it maps them back to the original function’s parameters.For direct access to the original function without mapping, use forward_raw() with the original parameter names.