Files
modelcontextprotocol--pytho…/examples/stories/lifespan/server.py
T
wehub-resource-sync 49b9bb6724
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 12:10:27 +08:00

40 lines
1.2 KiB
Python

"""Process-scoped dependency injection via `MCPServer(lifespan=...)`."""
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from dataclasses import dataclass
from typing import Any
from mcp.server.mcpserver import Context, MCPServer
from stories._hosting import run_server_from_args
@dataclass
class AppState:
db: dict[str, str]
@asynccontextmanager
async def app_lifespan(server: MCPServer[AppState]) -> AsyncIterator[AppState]:
"""Acquire process-scoped resources at startup; release them at shutdown."""
db = {"alpha": "one", "beta": "two"} # e.g. `await pool.connect()`
try:
yield AppState(db=db)
finally:
db.clear() # e.g. `await pool.disconnect()`
def build_server() -> MCPServer[AppState]:
mcp = MCPServer[AppState]("lifespan-example", lifespan=app_lifespan)
@mcp.tool(description="Look up a key in the process-scoped store.")
def lookup(key: str, ctx: Context[AppState, Any]) -> str:
# Interim 3-hop path; shortens to `ctx.state.db` in a later release.
return ctx.request_context.lifespan_context.db[key]
return mcp
if __name__ == "__main__":
run_server_from_args(build_server)