-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
enhancementImprovement to existing functionality. For issues and smaller PR improvements.Improvement to existing functionality. For issues and smaller PR improvements.proposalA proposal for a feature or enhancement either requiring or seeking comments on its design.A proposal for a feature or enhancement either requiring or seeking comments on its design.serverRelated to FastMCP server implementation or server-side functionality.Related to FastMCP server implementation or server-side functionality.
Description
Summary
The FastMCP class in server.py is ~2950 lines and handles too many responsibilities: lifecycle management, transport configuration, component registration, middleware orchestration, and factory methods. This "God Object" pattern makes the code harder to test, extend, and maintain.
Problem
Current FastMCP responsibilities:
- Lifecycle:
run(),run_async(), lifespan management, startup/shutdown - Transports: HTTP, stdio, SSE configuration and launching
- Components: Tool/resource/prompt registration, providers, mounting
- Middleware: Registration, ordering, execution chain
- Factories:
from_openapi(),from_client(), config loading
This violates Single Responsibility Principle and makes isolated testing difficult.
Proposed Solution
Split FastMCP into 4 focused mixins that compose into the final class:
# src/fastmcp/server/mixins/lifecycle.py
class LifecycleMixin:
"""Server startup, shutdown, and lifespan management."""
async def run_async(self, ...): ...
def run(self, ...): ...
@asynccontextmanager
async def lifespan(self): ...
# src/fastmcp/server/mixins/transport.py
class TransportMixin:
"""Transport configuration and launching."""
def run_stdio(self, ...): ...
async def run_http_async(self, ...): ...
def http_app(self, ...): ...
# src/fastmcp/server/mixins/component.py
class ComponentMixin:
"""Tool, resource, prompt registration and providers."""
def tool(self, ...): ...
def resource(self, ...): ...
def prompt(self, ...): ...
def mount(self, ...): ...
def add_provider(self, ...): ...
# src/fastmcp/server/mixins/middleware.py
class MiddlewareMixin:
"""Middleware registration and chain management."""
def add_middleware(self, ...): ...
def enable(self, ...): ...
def disable(self, ...): ...
# src/fastmcp/server/server.py
class FastMCP(LifecycleMixin, TransportMixin, ComponentMixin, MiddlewareMixin):
"""FastMCP server - composes all mixins."""
def __init__(self, name: str, ...): ...Directory Structure
src/fastmcp/server/
βββ server.py # FastMCP class (slim, ~200 lines)
βββ mixins/
β βββ __init__.py
β βββ lifecycle.py # ~400 lines
β βββ transport.py # ~600 lines
β βββ component.py # ~800 lines
β βββ middleware.py # ~400 lines
βββ ...
Benefits
- Testability: Each mixin can be tested in isolation
- Readability: Developers can focus on one responsibility at a time
- Extensibility: Users can subclass individual mixins for customization
- Maintainability: Changes to transport don't risk breaking component registration
Implementation Notes
- Start with extracting
LifecycleMixin(smallest, clearest boundaries) - Move transport-related code to
TransportMixin - Extract component registration to
ComponentMixin - Finally, isolate middleware to
MiddlewareMixin - Use
Selftype hints for method chaining - Ensure all existing tests pass after each extraction
Risks
- MRO complexity: 4 mixins is manageable; avoid going deeper
- Circular imports: May need careful import organization
- Breaking changes: Public API should remain identical
Related
- Refactor managers to eliminate code duplicationΒ #1552 proposed
BaseManagerextraction (different approach, now stale) - Follows patterns from Django's class-based views and Starlette's routing mixins
This issue was identified during an architecture review of the FastMCP codebase.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementImprovement to existing functionality. For issues and smaller PR improvements.Improvement to existing functionality. For issues and smaller PR improvements.proposalA proposal for a feature or enhancement either requiring or seeking comments on its design.A proposal for a feature or enhancement either requiring or seeking comments on its design.serverRelated to FastMCP server implementation or server-side functionality.Related to FastMCP server implementation or server-side functionality.