PrefectHQ/fastmcp · error
Cannot mount a server onto itself
Error message
Cannot mount a server onto itself
What it means
FastMCP.mount() rejects mounting a server onto itself (server is self), which would create infinite recursion when resolving tools/resources/prompts. Guard clause raising ValueError.
Source
Thrown at fastmcp_slim/fastmcp/server/server.py:2352
When a server is mounted without a namespace (namespace=None), its tools, resources, templates,
and prompts are accessible with their original names. Multiple servers can be mounted
without namespaces, and they will be tried in order until a match is found.
The mounted server's lifespan is executed when the parent server starts, and its
middleware chain is invoked for all operations (tool calls, resource reads, prompts).
Args:
server: The FastMCP server to mount.
namespace: Optional namespace to use for the mounted server's objects. If None,
the server's objects are accessible with their original names.
tool_names: Optional mapping of original tool names to custom names. Use this
to override namespaced names. Keys are the original tool names from the
mounted server.
"""
from fastmcp.server.providers.fastmcp_provider import FastMCPProvider
if server is self:
raise ValueError("Cannot mount a server onto itself")
# Warn if parent masks errors but child doesn't (or vice versa)
if self._mask_error_details and not server._mask_error_details:
logger.warning(
f"Parent server {self.name!r} has mask_error_details=True but "
f"mounted server {server.name!r} does not. Error details from "
f"{server.name!r} may leak through to clients. Set "
f"mask_error_details=True on the child server to prevent this."
)
# Create provider and add it with namespace
provider: Provider = FastMCPProvider(server)
# Apply tool renames first (scoped to this provider), then namespace
# So foo → bar with namespace="baz" becomes baz_bar
if tool_names:
transforms = {
old_name: ToolTransformConfig(name=new_name)View on GitHub (pinned to 1f02114297)
Solutions
- Pass a distinct FastMCP instance to mount()
- Check that the variable passed to mount is actually the subserver, not the parent
- Build the child server in its own factory/constructor
Example fix
// before
mcp.mount(mcp) # self-mount
// after
sub = FastMCP("subserver")
mcp.mount(sub) Defensive patterns
Strategy: validation
Validate before calling
if sub_server is mcp:
raise ValueError("refusing to mount server onto itself") Try / catch
try:
mcp.mount(child)
except ValueError as e:
logger.error("mount failed: %s", e) Prevention
- Construct child servers in dedicated factories
- Assert child is not parent before mount
- Avoid reusing variable names that may alias the parent
When it happens
Trigger: Calling mcp.mount(mcp) — passing the same FastMCP instance as both parent and child, often via a variable that accidentally aliases self.
Common situations: Factory functions returning the parent by mistake; refactoring where a variable meant to hold a subserver still references the parent.
Related errors
- Error rendering prompt {name!r}
- Error rendering prompt {name!r}: {e}
- module {__name__!r} has no attribute {name!r}
- Cannot resolve tool reference: {fn!r}
- Cannot specify both a name as first argument and as keyword
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/b9a9f98d52940650.
Report an issue: GitHub.