Skip to content

How to mount streamable HTTP app to an existing starlette app #673

@Liujony

Description

@Liujony

Describe the bug
Can not mount streamable HTTP app to an existing starlette app with streamable_http_app() nor a brand new StreamableHTTPSessionManager

Or am I doing the wrong way

To Reproduce

  1. with streamable_http_app()
application = Starlette(
    debug=True,
    routes=[
        Route("/health", health),
    ],
    middleware=[Middleware(LoggingMiddleware)],
)
mcpServer = FastMCP("TestMCP", stateless_http=True, streamable_http_path="/test")
application.mount("/mcp/test", mcpServer.streamable_http_app())
uvicorn.run(application, host="0.0.0.0", port=8000)

Error Shows
INFO: 127.0.0.1:51977 - "POST /mcp/test/ HTTP/1.1" 404 Not Found

I think this is an issue related to the Starlette, that a sub app can not run lifespan lifespan events in sub-applications #649

  1. with StreamableHTTPSessionManager
    Then I try to create a brand new StreamableHTTPSessionManager and mount the handle_request on the app
application = Starlette(
    debug=True,
    routes=[
        Route("/health", health),
    ],
    middleware=[Middleware(LoggingMiddleware)],
)
mcp_server = FastMCP("TestMCP", stateless_http=True, streamable_http_path="/test")
ssesion_manager = StreamableHTTPSessionManager(
    app=mcp_server._mcp_server,
    stateless=True,
    # event_store=event_store,
    # json_response=is_json_response_enabled,
)
exit_stack = AsyncExitStack()
asyncio.run(exit_stack.enter_async_context(session_manager.run()))
application.mount("/mcp", session_manager.handle_request)
uvicorn.run(application, host="0.0.0.0", port=8000)

Error shows

INFO 2025-05-09 18:20:23,993 streamable_http_manager 17158 140704588348864 StreamableHTTP session manager started
INFO 2025-05-09 18:20:23,994 streamable_http_manager 17158 140704588348864 StreamableHTTP session manager shutting down
ERROR 2025-05-09 18:20:23,994 base_events 17158 140704588348864 an error occurred during closing of asynchronous generator <async_generator object StreamableHTTPSessionManager.run at 0x102abd3f0>
asyncgen: <async_generator object StreamableHTTPSessionManager.run at 0x102abd3f0>
  + Exception Group Traceback (most recent call last):
  |   File "/usr/local/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 772, in __aexit__
  |     raise BaseExceptionGroup(
  |         "unhandled errors in a TaskGroup", self._exceptions
  |     ) from None
  | BaseExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "/usr/local/lib/python3.13/site-packages/mcp/server/streamable_http_manager.py", line 112, in run
    |     yield  # Let the application run
    |     ^^^^^
    | GeneratorExit
    +------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.13/site-packages/mcp/server/streamable_http_manager.py", line 107, in run
    async with anyio.create_task_group() as tg:
               ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/usr/local/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 778, in __aexit__
    if self.cancel_scope.__exit__(type(exc), exc, exc.__traceback__):
       ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/anyio/_backends/_asyncio.py", line 457, in __exit__
    raise RuntimeError(
    ...<2 lines>...
    )
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in

which means StreamableHTTP session was not run successfully
And when I try connect mcp server with client is shows it was not run
RuntimeError: Task group is not initialized. Make sure to use run().

Expected behavior
Run Successfully

Package Version

  • mcp: 1.8.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions