This example demonstrates how to use EnrichMCP with a real SQLite database, showcasing:
- Lifespan management: Database connection lifecycle
- Context injection: Accessing database from resolvers and resources
- Progress reporting: Visual feedback during operations
- Logging: Structured logging throughout the API
- SQLite database with automatic schema creation
- Sample data initialization
- Context injection in all resolvers and resources
- Proper error handling and logging
- Progress reporting for long operations
python app.pyThis will:
- Create a SQLite database (
shop.db) in the current directory - Initialize the schema with tables for users, products, orders
- Insert sample data if the database is empty
- Start the MCP server
The lifespan async context manager handles database setup and teardown:
@asynccontextmanager
async def lifespan(app: EnrichMCP) -> AsyncIterator[dict[str, Any]]:
# Setup: Connect to database
db = Database("shop.db")
await db.connect()
# Yield context available in handlers
yield {"db": db}
# Cleanup: Close connection
await db.close()Access the database through context injection in your resources or resolvers:
from fastmcp import Context
@app.retrieve
async def get_user(user_id: int, ctx: Context) -> User:
# Access database from lifespan context
db = ctx.request_context.lifespan_context["db"]
# Use logging
await ctx.info(f"Fetching user {user_id}")
# Query database
user_row = await db.get_user(user_id)
return User(**user_row)- Real Database: All data comes from SQLite, not hardcoded lists
- Async Operations: Database operations are async-ready
- Context Usage: Shows logging, progress, and database access
- Error Handling: Proper handling of missing data
- users: Customer accounts with risk scores
- products: Items for sale with fraud risk levels
- orders: Purchase transactions with status tracking
- order_products: Many-to-many relationship between orders and products