44from contextlib import asynccontextmanager
55from typing import AsyncIterator
66
7+ import uvicorn
78from mcp .server .fastmcp import FastMCP
9+ from starlette .applications import Starlette
810
911from server .config import settings
1012from server .embeddings .bm25 import BM25SparseProvider , close_sparse_embedding_provider
@@ -51,15 +53,29 @@ async def lifespan(_: FastMCP) -> AsyncIterator[None]:
5153 logger .info ("semcode MCP server stopped." )
5254
5355
56+ # For streamable-http we drive the Starlette app's lifespan ourselves (see main),
57+ # so the per-MCP-session lifespan would re-init the store on every client connect.
5458mcp = FastMCP (
5559 "semcode" ,
5660 instructions = "Semantic code search across microservices codebases. Supports Go, Java, Python, and TypeScript/React." ,
57- lifespan = lifespan ,
61+ lifespan = lifespan if settings . mcp_transport != "streamable-http" else None ,
5862 host = settings .mcp_host ,
5963 port = settings .mcp_port ,
6064)
6165
6266
67+ def _wrap_http_lifespan (app : Starlette ) -> None :
68+ original = app .router .lifespan_context
69+
70+ @asynccontextmanager
71+ async def combined (scope_app : Starlette ) -> AsyncIterator [None ]:
72+ async with lifespan (mcp ):
73+ async with original (scope_app ):
74+ yield
75+
76+ app .router .lifespan_context = combined
77+
78+
6379def main () -> None :
6480 from server .tools .search import register_search_tools
6581 from server .tools .index import register_index_tools
@@ -77,7 +93,17 @@ def main() -> None:
7793 register_system_prompts (mcp )
7894 register_http_routes (mcp )
7995
80- mcp .run (transport = settings .mcp_transport )
96+ if settings .mcp_transport == "streamable-http" :
97+ app = mcp .streamable_http_app ()
98+ _wrap_http_lifespan (app )
99+ uvicorn .run (
100+ app ,
101+ host = settings .mcp_host ,
102+ port = settings .mcp_port ,
103+ log_level = mcp .settings .log_level .lower (),
104+ )
105+ else :
106+ mcp .run (transport = settings .mcp_transport )
81107
82108
83109if __name__ == "__main__" :
0 commit comments