61. FastAPI as Web Framework
Date: 2025-11-29Status
AcceptedCategory
Core ArchitectureContext
The MCP Server requires a web framework to expose HTTP APIs, handle WebSocket connections for real-time communication, and integrate with the Model Context Protocol. Key requirements include:- Async-first architecture: LLM calls, database operations, and external API calls are I/O-bound
- High performance: Low latency for real-time agent interactions
- Type safety: Runtime validation of request/response payloads
- OpenAPI generation: Automatic API documentation for clients
- WebSocket support: Real-time streaming for agent responses
- Dependency injection: Clean separation of concerns for testing
Frameworks Considered
- Flask: Synchronous by default, WSGI-based, mature ecosystem
- Django: Full-featured, ORM-included, admin interface
- FastAPI: Async-native, Pydantic integration, automatic OpenAPI
- Starlette: Lightweight async framework (FastAPI is built on it)
- Quart: Flask-compatible async framework
Decision
Use FastAPI as the web framework for all HTTP and WebSocket endpoints.Key Reasons
- Native Async Support: Built on Starlette with first-class async/await support
- Pydantic Integration: Request/response validation using the same models as the rest of the codebase (ADR-0014)
- Automatic OpenAPI: Self-documenting APIs with Swagger UI and ReDoc
- Dependency Injection: Clean DI system for authentication, database connections, etc.
- WebSocket Support: Native WebSocket handling for streaming responses
- Performance: One of the fastest Python frameworks (comparable to Node.js/Go)
- Type Hints: Full IDE support with autocomplete and type checking
Implementation Pattern
Consequences
Positive
- Developer Productivity: Type hints + autocomplete reduce errors
- Performance: Async I/O handles concurrent requests efficiently
- Documentation: OpenAPI spec generated automatically
- Testing: Dependency injection makes mocking straightforward
- Ecosystem: Large community, extensive middleware available
Negative
- Learning Curve: Async patterns require understanding of asyncio
- Debugging: Async stack traces can be harder to follow
- Dependency: Tied to Starlette’s release cycle
Alternatives Considered
Flask
- Rejected: Synchronous by default; async support via extensions is bolted-on
- Would require Flask-SocketIO for WebSocket, Flask-Pydantic for validation
Django
- Rejected: Heavy for an API-only service; ORM not needed (using raw asyncpg)
- Django REST Framework adds complexity without benefit for our use case
Starlette
- Considered: FastAPI is built on Starlette, provides same performance
- Rejected: FastAPI adds valuable abstractions (Pydantic, OpenAPI, DI)
References
- Implementation:
src/mcp_server_langgraph/api/(all API endpoints) - Configuration:
src/mcp_server_langgraph/core/server.py - Related ADRs: ADR-0014, ADR-0019
- External: FastAPI Documentation