Redesign lifespan: separate server-scoped and session-scoped lifetimes #2113
Copy link
Copy link
Closed
Labels
P1Significant bug affecting many users, highly requested featureSignificant bug affecting many users, highly requested featurebreaking changeWill break existing deployments when updated without changesWill break existing deployments when updated without changesenhancementRequest for a new feature that's not currently supportedRequest for a new feature that's not currently supportedv2Affects the v2 line (2.x on main)Affects the v2 line (2.x on main)
Description
Summary
The current lifespan implementation is tied to sessions/transports rather than having distinct scopes. This causes two P0 bugs (#1300, #1304) and makes the model fundamentally wrong for production use.
Problem
- With
streamable-http, the lifespan does not execute on server startup — it only runs when a client connects and a session is created (Lifespan does not execute on startup streamable-http #1300) - With
stateless_http=True, the lifespan enters and exits for every request because each request spins up a new transport (Lifespan enters and exits for each request when stateless_http=True #1304) - There is no way to distinguish between resources that should live for the entire server process (database connections, caches) and resources that should be scoped to an individual session (per-user state, auth context)
Goal
Provide two distinct lifetime scopes:
- Server lifespan — entered once when the server starts, exited when it shuts down. Survives across all sessions and requests. This is where you put database pools, ML models, shared caches.
- Session lifespan — entered when a client session is established, exited when the session ends. This is where you put per-user state, auth context, session-specific resources.
Both should be accessible from handler context. The current single lifespan parameter should be replaced or extended to support both scopes.
Subsumes
- Lifespan does not execute on startup streamable-http #1300 — Lifespan does not execute on startup with streamable-http
- Lifespan enters and exits for each request when stateless_http=True #1304 — Lifespan enters and exits for each request when stateless_http=True
Reacted by Kirill Vorozhtsov
Metadata
Metadata
Assignees
Labels
P1Significant bug affecting many users, highly requested featureSignificant bug affecting many users, highly requested featurebreaking changeWill break existing deployments when updated without changesWill break existing deployments when updated without changesenhancementRequest for a new feature that's not currently supportedRequest for a new feature that's not currently supportedv2Affects the v2 line (2.x on main)Affects the v2 line (2.x on main)
Activity
kumar-pankaj0 commentedon Feb 22, 2026
Hi @maxisbey - I wanted to share my understanding of the lifespan redesign issue and confirm the proposed solution.
Problem Summary
The current single
lifespanis tied toServer.run(), which is called per-session (streamable-http) or per-request (stateless_http). This causes:Both problems stem from the same root cause: no way to create resources that live for the entire server process.
Proposed Solution: Two Separate Lifespans
Server Lifespan (runs ONCE)
Session Lifespan (runs PER CLIENT)
API Design Question
I see two possible approaches:
Option A: Extend (backwards compatible)
Option B: Replace (breaking change, clearer)
Given this is a "redesign" and the maintainers marked the related bugs as "subsumed by #2113", I lean toward Option B for a cleaner API, with a migration guide.
Context Access in Handlers
Would love to hear your thoughts on the API design choice and whether this aligns with your vision for the fix!
fix: update MCPServer lifespan example for API consistency
style: apply ruff formatting
fix: update task tests to use session_lifespan parameter
maxisbey commentedon Aug 10, 2026
This landed as part of v2, which is now released (via #2928) — closing. Feel free to reopen if there's something still outstanding.