Commit 5f26e0d
committed
Support session expiry controls for
## Motivation and Context
The MCP specification recommends expiring session IDs to reduce session hijacking risks:
https://modelcontextprotocol.io/specification/latest/basic/security_best_practices#session-hijacking
Several other SDKs (Go, C#, PHP, Python) already implement session expiry controls, but
the Ruby SDK did not. Sessions persisted indefinitely unless explicitly deleted or
a stream error occurred, leaving abandoned sessions to accumulate in memory.
This adds a `session_idle_timeout:` option to `StreamableHTTPTransport#initialize`. When
set, sessions that receive no HTTP requests for the specified duration (in seconds) are
automatically expired. Expired sessions return 404 on subsequent requests (GET and POST),
matching the MCP specification's behavior for terminated sessions. Each request resets
the idle timer, so actively used sessions are not interrupted.
A background reaper thread periodically cleans up expired sessions to handle orphaned
sessions that receive no further requests. The reaper only starts when
`session_idle_timeout` is configured.
The default is `nil` (no expiry) for backward compatibility, consistent with the Python
SDK's approach. The Python SDK recommends 1800 seconds (30 minutes) for most deployments:
modelcontextprotocol/python-sdk#2022
Resolves #265.
## How Has This Been Tested?
Added tests for session expiry, idle timeout reset, reaper thread lifecycle, input
validation, and default behavior in `streamable_http_transport_test.rb`. All existing
tests continue to pass.
## Breaking Change
None. The default value of `session_idle_timeout` is `nil`, which preserves the existing
behavior of sessions never expiring. The new `last_active_at` field in the internal
session hash is not part of the public API. Existing code that instantiates
`StreamableHTTPTransport.new(server)` or
`StreamableHTTPTransport.new(server, stateless: true)` continues to work without changes.StreamableHTTPTransport
1 parent e189d78 commit 5f26e0d
File tree
3 files changed
+422
-16
lines changed- lib/mcp/server/transports
- test/mcp/server/transports
3 files changed
+422
-16
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
293 | 293 | | |
294 | 294 | | |
295 | 295 | | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
296 | 304 | | |
297 | 305 | | |
298 | 306 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
18 | 29 | | |
19 | 30 | | |
20 | 31 | | |
21 | 32 | | |
22 | 33 | | |
| 34 | + | |
23 | 35 | | |
24 | 36 | | |
25 | 37 | | |
| |||
35 | 47 | | |
36 | 48 | | |
37 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
38 | 53 | | |
39 | 54 | | |
40 | 55 | | |
| |||
56 | 71 | | |
57 | 72 | | |
58 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
59 | 79 | | |
60 | 80 | | |
61 | 81 | | |
| |||
75 | 95 | | |
76 | 96 | | |
77 | 97 | | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
78 | 103 | | |
79 | 104 | | |
80 | 105 | | |
| |||
97 | 122 | | |
98 | 123 | | |
99 | 124 | | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
100 | 155 | | |
101 | 156 | | |
102 | 157 | | |
| |||
141 | 196 | | |
142 | 197 | | |
143 | 198 | | |
144 | | - | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
145 | 202 | | |
146 | 203 | | |
147 | 204 | | |
| |||
235 | 292 | | |
236 | 293 | | |
237 | 294 | | |
| 295 | + | |
238 | 296 | | |
239 | 297 | | |
240 | 298 | | |
| |||
256 | 314 | | |
257 | 315 | | |
258 | 316 | | |
259 | | - | |
260 | | - | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
261 | 320 | | |
262 | 321 | | |
263 | 322 | | |
| |||
273 | 332 | | |
274 | 333 | | |
275 | 334 | | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
276 | 351 | | |
277 | 352 | | |
278 | 353 | | |
| |||
378 | 453 | | |
379 | 454 | | |
380 | 455 | | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
381 | 462 | | |
382 | 463 | | |
383 | 464 | | |
| |||
0 commit comments