Skip to content

Commit 2d14019

Browse files
halter73Copilot
andcommitted
Fix idle session docs and clean up DI scope language
Any active HTTP request (POST or GET) prevents a session from being counted as idle, not just GET/SSE. Fix docs and API comment on MaxIdleSessionCount. Also remove redundant 'async' from 'async scope' in DI documentation since nearly all ASP.NET Core scopes are async. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ad14237 commit 2d14019

File tree

2 files changed

+7
-7
lines changed

2 files changed

+7
-7
lines changed

docs/concepts/sessions/sessions.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ The server tracks the last activity time for each session. Activity is recorded
159159

160160
Sessions that have no activity for the duration of <xref:ModelContextProtocol.AspNetCore.HttpServerTransportOptions.IdleTimeout> (default: **2 hours**) are automatically closed. The idle timeout is checked in the background every 5 seconds.
161161

162-
A client can keep its session alive by maintaining an open `GET` request (SSE stream). Sessions with an active `GET` request are never considered idle.
162+
A client can keep its session alive by maintaining any open HTTP request (e.g., a long-running POST with a streamed response or an open `GET` for unsolicited messages). Sessions with active requests are never considered idle.
163163

164164
When a session times out:
165165

@@ -177,7 +177,7 @@ You can disable idle timeout by setting it to `Timeout.InfiniteTimeSpan`, though
177177
- The oldest idle sessions are terminated (even if they haven't reached their idle timeout)
178178
- Termination continues until the idle count is back below the limit
179179

180-
Sessions with an active `GET` request (open SSE stream) don't count toward this limit.
180+
Sessions with any active HTTP request don't count toward this limit.
181181

182182
#### Termination
183183

@@ -305,7 +305,7 @@ How the server resolves scoped services depends on the transport and session mod
305305

306306
#### Stateful HTTP
307307

308-
In stateful mode, the server's <xref:ModelContextProtocol.McpServer.Services> is the application-level `IServiceProvider` — not a per-request scope. Because the server outlives individual HTTP requests, <xref:ModelContextProtocol.Server.McpServerOptions.ScopeRequests> defaults to `true`: each handler invocation (tool call, resource read, etc.) creates a new async scope via `IServiceScopeFactory.CreateAsyncScope()`. The scoped `IServiceProvider` is available on <xref:ModelContextProtocol.Server.RequestContext`1.Services>.
308+
In stateful mode, the server's <xref:ModelContextProtocol.McpServer.Services> is the application-level `IServiceProvider` — not a per-request scope. Because the server outlives individual HTTP requests, <xref:ModelContextProtocol.Server.McpServerOptions.ScopeRequests> defaults to `true`: each handler invocation (tool call, resource read, etc.) creates a new scope.
309309

310310
This means:
311311

@@ -342,9 +342,9 @@ builder.Services.AddMcpServer(options =>
342342

343343
| Mode | Service provider | ScopeRequests | Handler scope |
344344
|------|-----------------|---------------|---------------|
345-
| **Stateful HTTP** | Application services | `true` (default) | New async scope per handler invocation |
345+
| **Stateful HTTP** | Application services | `true` (default) | New scope per handler invocation |
346346
| **Stateless HTTP** | `HttpContext.RequestServices` | `false` (forced) | Shared HTTP request scope |
347-
| **stdio** | Application services | `true` (default, configurable) | New async scope per handler invocation |
347+
| **stdio** | Application services | `true` (default, configurable) | New scope per handler invocation |
348348

349349
## Security
350350

src/ModelContextProtocol.AspNetCore/HttpServerTransportOptions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ public class HttpServerTransportOptions
132132
/// </value>
133133
/// <remarks>
134134
/// Past this limit, the server logs a critical error and terminates the oldest idle sessions, even if they have not reached
135-
/// their <see cref="IdleTimeout"/>, until the idle session count is below this limit. Clients that keep their session open by
136-
/// keeping a GET request open don't count towards this limit.
135+
/// their <see cref="IdleTimeout"/>, until the idle session count is below this limit. Sessions with any active HTTP request
136+
/// are not considered idle and don't count towards this limit.
137137
/// </remarks>
138138
public int MaxIdleSessionCount { get; set; } = 10_000;
139139

0 commit comments

Comments
 (0)