Documentation: Server composition pattern incompatible with fastmcp dev
Enhancement
The server composition documentation shows a pattern that only works when running servers directly, but fails silently when using fastmcp dev.
Current Documentation Pattern
The docs show:
from fastmcp import FastMCP
import asyncio
# Define subservers
weather_mcp = FastMCP(name="WeatherService")
@weather_mcp.tool
def get_forecast(city: str) -> dict:
"""Get weather forecast."""
return {"city": city, "forecast": "Sunny"}
# Define main server
main_mcp = FastMCP(name="MainApp")
# Import subserver
async def setup():
await main_mcp.import_server(weather_mcp, prefix="weather")
if __name__ == "__main__":
asyncio.run(setup())
main_mcp.run()
The Problem
This pattern does not work with fastmcp dev:
fastmcp dev server.py
# Result: No tools listed - setup() never runs
Why: fastmcp dev imports the module but doesn't execute the if __name__ == "__main__" block, so setup() is never called and subservers are never imported.
What Works
The pattern works fine when running directly:
python server.py
# or
npx @modelcontextprotocol/inspector uv run python server.py
Suggested Documentation Fix
The composition docs should include a warning and show the correct pattern for fastmcp dev compatibility:
Option 1: Event Loop Compatible Setup (Recommended)
async def setup():
await main_mcp.import_server(weather_mcp, prefix="weather")
# Run setup at module level - compatible with both fastmcp dev and direct execution
try:
loop = asyncio.get_running_loop()
loop.create_task(setup())
except RuntimeError:
asyncio.run(setup())
if __name__ == "__main__":
main_mcp.run()
Option 2: Use MCP Inspector Instead
Add a note that for development/testing composed servers, the MCP Inspector is recommended:
npx @modelcontextprotocol/inspector uv run python server.py
edit: listen to jeremiah not to me
importing requires a live server, mounting does not, can you use a mounted server?
the live server requirement precludes doing this with fastmcp dev
You may be able to import the server via a lifespan as starting in 2.13 lifespan is server lifetime-bound
Actually I'd say neither of those is the best pattern. fastmcp run and fastmcp dev have the same semantics, including the use of a factory_function entrypoint for exactly this use case.
However I see that fastmcp run has a warning about __main__ but fastmcp dev only documents its entrypoints without that warning, so we should add it
Running fastmcp dev on the code shown in server composition documentation doesn't fail, but no tools are listed. This is quite confusing... at least at first.