3838 StreamId ,
3939)
4040from mcp .shared .exceptions import McpError
41+ from mcp .shared .message import (
42+ ClientMessageMetadata ,
43+ ResumptionToken ,
44+ ResumptionTokenUpdateCallback ,
45+ SessionMessage ,
46+ )
4147from mcp .shared .session import RequestResponder
4248from mcp .types import (
4349 InitializeResult ,
@@ -1031,12 +1037,21 @@ async def on_resumption_token_update(token: str) -> None:
10311037 async with anyio .create_task_group () as tg :
10321038
10331039 async def run_tool ():
1034- # Call the special tool that sends periodic notifications
1035- await session .call_tool (
1036- "long_running_with_checkpoints" ,
1037- {},
1040+ metadata = ClientMessageMetadata (
10381041 on_resumption_token_update = on_resumption_token_update ,
10391042 )
1043+ await session .send_request (
1044+ types .ClientRequest (
1045+ types .CallToolRequest (
1046+ method = "tools/call" ,
1047+ params = types .CallToolRequestParams (
1048+ name = "long_running_with_checkpoints" , arguments = {}
1049+ ),
1050+ )
1051+ ),
1052+ types .CallToolResult ,
1053+ metadata = metadata ,
1054+ )
10401055
10411056 tg .start_soon (run_tool )
10421057
@@ -1046,7 +1061,9 @@ async def run_tool():
10461061 await anyio .sleep (0.1 )
10471062 tg .cancel_scope .cancel ()
10481063
1049- # Clear captured notifications
1064+ # Store pre notifications and clear the captured notifications
1065+ # for the post-resumption check
1066+ captured_notifications_pre = captured_notifications .copy ()
10501067 captured_notifications = []
10511068
10521069 # Now resume the session with the same mcp-session-id
@@ -1067,11 +1084,22 @@ async def run_tool():
10671084
10681085 # Resume the tool with the resumption token
10691086 assert captured_resumption_token is not None
1070- result = await session .call_tool (
1071- "long_running_with_checkpoints" ,
1072- {},
1087+
1088+ metadata = ClientMessageMetadata (
10731089 resumption_token = captured_resumption_token ,
10741090 )
1091+ result = await session .send_request (
1092+ types .ClientRequest (
1093+ types .CallToolRequest (
1094+ method = "tools/call" ,
1095+ params = types .CallToolRequestParams (
1096+ name = "long_running_with_checkpoints" , arguments = {}
1097+ ),
1098+ )
1099+ ),
1100+ types .CallToolResult ,
1101+ metadata = metadata ,
1102+ )
10751103
10761104 # We should get a complete result
10771105 assert len (result .content ) == 1
@@ -1088,3 +1116,7 @@ async def run_tool():
10881116 and n .root .params .data == "Tool started"
10891117 for n in captured_notifications
10901118 )
1119+ # there is no intersection between pre and post notifications
1120+ assert not any (
1121+ n in captured_notifications_pre for n in captured_notifications
1122+ )
0 commit comments