Skip to content

Commit 0a1aab2

Browse files
author
TheMailmans
committed
fix: add lifespan context manager to StreamableHTTP mounting examples
The ASGI mounting examples were missing the lifespan context manager needed to properly initialize the session manager. Without this, requests fail with "RuntimeError: Task group is not initialized". This adds the proper lifespan pattern to: - streamable_http_basic_mounting.py - streamable_http_host_mounting.py - streamable_http_multiple_servers.py Github-Issue:#1484
1 parent 02b7889 commit 0a1aab2

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

examples/snippets/servers/streamable_http_basic_mounting.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
uvicorn examples.snippets.servers.streamable_http_basic_mounting:app --reload
66
"""
77

8+
import contextlib
9+
810
from starlette.applications import Starlette
911
from starlette.routing import Mount
1012

@@ -20,9 +22,17 @@ def hello() -> str:
2022
return "Hello from MCP!"
2123

2224

25+
# Create a lifespan context manager to run the session manager
26+
@contextlib.asynccontextmanager
27+
async def lifespan(app: Starlette):
28+
async with mcp.session_manager.run():
29+
yield
30+
31+
2332
# Mount the StreamableHTTP server to the existing ASGI server
2433
app = Starlette(
2534
routes=[
2635
Mount("/", app=mcp.streamable_http_app()),
27-
]
36+
],
37+
lifespan=lifespan,
2838
)

examples/snippets/servers/streamable_http_host_mounting.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
uvicorn examples.snippets.servers.streamable_http_host_mounting:app --reload
66
"""
77

8+
import contextlib
9+
810
from starlette.applications import Starlette
911
from starlette.routing import Host
1012

@@ -20,9 +22,17 @@ def domain_info() -> str:
2022
return "This is served from mcp.acme.corp"
2123

2224

25+
# Create a lifespan context manager to run the session manager
26+
@contextlib.asynccontextmanager
27+
async def lifespan(app: Starlette):
28+
async with mcp.session_manager.run():
29+
yield
30+
31+
2332
# Mount using Host-based routing
2433
app = Starlette(
2534
routes=[
2635
Host("mcp.acme.corp", app=mcp.streamable_http_app()),
27-
]
36+
],
37+
lifespan=lifespan,
2838
)

examples/snippets/servers/streamable_http_multiple_servers.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
uvicorn examples.snippets.servers.streamable_http_multiple_servers:app --reload
66
"""
77

8+
import contextlib
9+
810
from starlette.applications import Starlette
911
from starlette.routing import Mount
1012

@@ -32,10 +34,21 @@ def send_message(message: str) -> str:
3234
api_mcp.settings.streamable_http_path = "/"
3335
chat_mcp.settings.streamable_http_path = "/"
3436

37+
38+
# Create a combined lifespan to manage both session managers
39+
@contextlib.asynccontextmanager
40+
async def lifespan(app: Starlette):
41+
async with contextlib.AsyncExitStack() as stack:
42+
await stack.enter_async_context(api_mcp.session_manager.run())
43+
await stack.enter_async_context(chat_mcp.session_manager.run())
44+
yield
45+
46+
3547
# Mount the servers
3648
app = Starlette(
3749
routes=[
3850
Mount("/api", app=api_mcp.streamable_http_app()),
3951
Mount("/chat", app=chat_mcp.streamable_http_app()),
40-
]
52+
],
53+
lifespan=lifespan,
4154
)

0 commit comments

Comments
 (0)