from collections.abc import AsyncIterator from contextlib import asynccontextmanager from dataclasses import dataclass from mcp.server.fastmcp import FastMCP from mistralai.client import Mistral from app.core.config import settings from app.core.logger import logger @dataclass class AppContext: """Shared resources available to all tools via ctx.request_context.lifespan_context.""" mistral: Mistral @asynccontextmanager async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]: """Initialize and cleanly tear down shared clients.""" logger.info("Initializing Mistral client...") client = Mistral(api_key=settings.MISTRAL_API_KEY) try: yield AppContext(mistral=client) finally: logger.info("Shutting down lifespan resources.")