Skip to content

Commit 51372a3

Browse files
committed
Pass through the actual session ID
1 parent 797cca8 commit 51372a3

File tree

5 files changed

+13
-5
lines changed

5 files changed

+13
-5
lines changed

src/mcp/server/experimental/request_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ async def work(task: ServerTaskContext) -> CallToolResult:
187187
# Access task_group via TaskSupport - raises if not in run() context
188188
task_group = support.task_group
189189

190-
session_id = str(id(self._session))
190+
session_id = self._session.session_id
191191
task = await support.store.create_task(self.task_metadata, task_id, session_id=session_id)
192192

193193
task_ctx = ServerTaskContext(

src/mcp/server/lowlevel/experimental.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ def enable_tasks(
153153
async def _default_get_task(
154154
ctx: ServerRequestContext[LifespanResultT], params: GetTaskRequestParams
155155
) -> GetTaskResult:
156-
session_id = str(id(ctx.session))
156+
session_id = ctx.session.session_id
157157
task = await task_support.store.get_task(params.task_id, session_id=session_id)
158158
if task is None:
159159
raise MCPError(code=INVALID_PARAMS, message=f"Task not found: {params.task_id}")
@@ -175,7 +175,7 @@ async def _default_get_task_result(
175175
ctx: ServerRequestContext[LifespanResultT], params: GetTaskPayloadRequestParams
176176
) -> GetTaskPayloadResult:
177177
assert ctx.request_id is not None
178-
session_id = str(id(ctx.session))
178+
session_id = ctx.session.session_id
179179
req = GetTaskPayloadRequest(params=params)
180180
result = await task_support.handler.handle(req, ctx.session, ctx.request_id, session_id=session_id)
181181
return result
@@ -188,7 +188,7 @@ async def _default_list_tasks(
188188
ctx: ServerRequestContext[LifespanResultT], params: PaginatedRequestParams | None
189189
) -> ListTasksResult:
190190
cursor = params.cursor if params else None
191-
session_id = str(id(ctx.session))
191+
session_id = ctx.session.session_id
192192
tasks, next_cursor = await task_support.store.list_tasks(cursor, session_id=session_id)
193193
return ListTasksResult(tasks=tasks, next_cursor=next_cursor)
194194

@@ -199,7 +199,7 @@ async def _default_list_tasks(
199199
async def _default_cancel_task(
200200
ctx: ServerRequestContext[LifespanResultT], params: CancelTaskRequestParams
201201
) -> CancelTaskResult:
202-
session_id = str(id(ctx.session))
202+
session_id = ctx.session.session_id
203203
result = await cancel_task(task_support.store, params.task_id, session_id=session_id)
204204
return result
205205

src/mcp/server/lowlevel/server.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ async def run(
374374
# the initialization lifecycle, but can do so with any available node
375375
# rather than requiring initialization for each connection.
376376
stateless: bool = False,
377+
# Optional session identifier for task isolation. When provided (e.g.,
378+
# from the transport's mcp_session_id), tasks are bound to this ID.
379+
session_id: str | None = None,
377380
):
378381
async with AsyncExitStack() as stack:
379382
lifespan_context = await stack.enter_async_context(self.lifespan(self))
@@ -383,6 +386,7 @@ async def run(
383386
write_stream,
384387
initialization_options,
385388
stateless=stateless,
389+
session_id=session_id,
386390
)
387391
)
388392

src/mcp/server/session.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,11 @@ def __init__(
8383
write_stream: MemoryObjectSendStream[SessionMessage],
8484
init_options: InitializationOptions,
8585
stateless: bool = False,
86+
session_id: str | None = None,
8687
) -> None:
8788
super().__init__(read_stream, write_stream)
8889
self._stateless = stateless
90+
self.session_id = session_id
8991
self._initialization_state = (
9092
InitializationState.Initialized if stateless else InitializationState.NotInitialized
9193
)

src/mcp/server/streamable_http_manager.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ async def run_stateless_server(*, task_status: TaskStatus[None] = anyio.TASK_STA
172172
write_stream,
173173
self.app.create_initialization_options(),
174174
stateless=True,
175+
session_id=http_transport.mcp_session_id,
175176
)
176177
except Exception: # pragma: no cover
177178
logger.exception("Stateless session crashed")
@@ -240,6 +241,7 @@ async def run_server(*, task_status: TaskStatus[None] = anyio.TASK_STATUS_IGNORE
240241
write_stream,
241242
self.app.create_initialization_options(),
242243
stateless=False,
244+
session_id=http_transport.mcp_session_id,
243245
)
244246

245247
if idle_scope.cancelled_caught:

0 commit comments

Comments
 (0)