--- title: Transforms Overview sidebarTitle: Overview description: Modify components as they flow through your server icon: wand-magic-sparkles --- import { VersionBadge } from '/snippets/version-badge.mdx' Transforms modify components as they flow from providers to clients. When a client asks "what tools do you have?", the request passes through each transform in the chain. Each transform can modify the components before passing them along. ## Mental Model Think of transforms as filters in a pipeline. Components flow from providers through transforms to reach clients: ``` Provider → [Transform A] → [Transform B] → Client ``` When listing components, transforms receive sequences and return transformed sequences—a pure function pattern. When getting a specific component by name, transforms use a middleware pattern with `call_next`, working in reverse: mapping the client's requested name back to the original, then transforming the result. ## Built-in Transforms FastMCP provides several transforms for common use cases: - **[Namespace](/servers/transforms/namespace)** - Prefix component names to prevent conflicts when composing servers - **[Tool Transformation](/servers/transforms/tool-transformation)** - Rename tools, modify descriptions, reshape arguments - **[Enabled](/servers/visibility)** - Control which components are visible at runtime - **[Tool Search](/servers/transforms/tool-search)** - Replace large tool catalogs with on-demand search - **[Resources as Tools](/servers/transforms/resources-as-tools)** - Expose resources to tool-only clients - **[Prompts as Tools](/servers/transforms/prompts-as-tools)** - Expose prompts to tool-only clients - **[Code Mode (Experimental)](/servers/transforms/code-mode)** - Replace many tools with programmable `search` + `execute` ## Server vs Provider Transforms Transforms can be added at two levels, each serving different purposes. ### Provider-Level Transforms Provider transforms apply to components from a specific provider. They run first, modifying components before they reach the server level. ```python from fastmcp import FastMCP from fastmcp.server.providers import FastMCPProvider from fastmcp.server.transforms import Namespace, ToolTransform from fastmcp.tools.tool_transform import ToolTransformConfig sub_server = FastMCP("Sub") @sub_server.tool def process(data: str) -> str: return f"Processed: {data}" # Create provider and add transforms provider = FastMCPProvider(sub_server) provider.add_transform(Namespace("api")) provider.add_transform(ToolTransform({ "api_process": ToolTransformConfig(description="Process data through the API"), })) main = FastMCP("Main", providers=[provider]) # Tool is now: api_process with updated description ``` When using `mount()`, the returned provider reference lets you add transforms directly. ```python main = FastMCP("Main") mount = main.mount(sub_server, namespace="api") mount.add_transform(ToolTransform({...})) ``` ### Server-Level Transforms Server transforms apply to all components from all providers. They run after provider transforms, seeing the already-transformed names. ```python from fastmcp import FastMCP from fastmcp.server.transforms import Namespace mcp = FastMCP("Server", transforms=[Namespace("v1")]) @mcp.tool def greet(name: str) -> str: return f"Hello, {name}!" # All tools become v1_toolname ``` Server-level transforms are useful for API versioning or applying consistent naming across your entire server. ### Transform Order Transforms stack in the order they're added. The first transform added is innermost (closest to the provider), and subsequent transforms wrap it. ```python from fastmcp.server.providers import FastMCPProvider from fastmcp.server.transforms import Namespace, ToolTransform from fastmcp.tools.tool_transform import ToolTransformConfig provider = FastMCPProvider(server) provider.add_transform(Namespace("api")) # Applied first provider.add_transform(ToolTransform({ # Sees namespaced names "api_verbose_name": ToolTransformConfig(name="short"), })) # Flow: "verbose_name" -> "api_verbose_name" -> "short" ``` When a client requests "short", the transforms reverse the mapping: ToolTransform maps "short" to "api_verbose_name", then Namespace strips the prefix to find "verbose_name" in the provider. ## Custom Transforms Create custom transforms by subclassing `Transform` and overriding the methods you need. ```python from collections.abc import Sequence from fastmcp.server.transforms import Transform, GetToolNext from fastmcp.tools.tool import Tool class TagFilter(Transform): """Filter tools to only those with specific tags.""" def __init__(self, required_tags: set[str]): self.required_tags = required_tags async def list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]: return [t for t in tools if t.tags & self.required_tags] async def get_tool(self, name: str, call_next: GetToolNext) -> Tool | None: tool = await call_next(name) if tool and tool.tags & self.required_tags: return tool return None ``` The `Transform` base class provides default implementations that pass through unchanged. Override only the methods relevant to your transform. Each component type has two methods with different patterns: | Method | Pattern | Purpose | |--------|---------|---------| | `list_tools(tools)` | Pure function | Transform the sequence of tools | | `get_tool(name, call_next)` | Middleware | Transform lookup by name | | `list_resources(resources)` | Pure function | Transform the sequence of resources | | `get_resource(uri, call_next)` | Middleware | Transform lookup by URI | | `list_resource_templates(templates)` | Pure function | Transform the sequence of templates | | `get_resource_template(uri, call_next)` | Middleware | Transform template lookup by URI | | `list_prompts(prompts)` | Pure function | Transform the sequence of prompts | | `get_prompt(name, call_next)` | Middleware | Transform lookup by name | List methods receive sequences directly and return transformed sequences. Get methods use `call_next` for routing flexibility—when a client requests "new_name", your transform maps it back to "original_name" before calling `call_next()`. ```python class PrefixTransform(Transform): def __init__(self, prefix: str): self.prefix = prefix async def list_tools(self, tools: Sequence[Tool]) -> Sequence[Tool]: return [t.model_copy(update={"name": f"{self.prefix}_{t.name}"}) for t in tools] async def get_tool(self, name: str, call_next: GetToolNext) -> Tool | None: # Reverse the prefix to find the original if not name.startswith(f"{self.prefix}_"): return None original = name[len(self.prefix) + 1:] tool = await call_next(original) if tool: return tool.model_copy(update={"name": name}) return None ```