Skip to content

Commit e73677a

Browse files
committed
remove resumtion from call_tool API
1 parent 2bd0a27 commit e73677a

File tree

3 files changed

+44
-44
lines changed

3 files changed

+44
-44
lines changed

src/mcp/client/session.py

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
import mcp.types as types
99
from mcp.shared.context import RequestContext
1010
from mcp.shared.message import (
11-
ClientMessageMetadata,
12-
ResumptionToken,
13-
ResumptionTokenUpdateCallback,
1411
SessionMessage,
1512
)
1613
from mcp.shared.session import BaseSession, RequestResponder
@@ -264,38 +261,8 @@ async def call_tool(
264261
name: str,
265262
arguments: dict[str, Any] | None = None,
266263
read_timeout_seconds: timedelta | None = None,
267-
on_resumption_token_update: ResumptionTokenUpdateCallback | None = None,
268-
resumption_token: ResumptionToken | None = None,
269264
) -> types.CallToolResult:
270-
"""Send a tools/call request to invoke or resume a tool operation.
271-
272-
This method supports two modes of operation:
273-
274-
Initial Invocation:
275-
- Tool is executed from the beginning
276-
- If on_resumption_token_update is provided, it will receive resumption tokens
277-
if transport supports resumable operations
278-
279-
Resumption:
280-
- Requires a resumption_token from a previous execution
281-
- Continues execution from the specified resumption token
282-
283-
Args:
284-
name: Tool name to call
285-
arguments: Optional arguments dictionary for the tool
286-
read_timeout_seconds: request read timeout
287-
on_resumption_token_update: Optional callback that receives
288-
resumption tokens during execution, which can be
289-
used later to resume an interrupted operation
290-
resumption_token: Optional token to resume from a specific token
291-
(supported by some transports)
292-
"""
293-
metadata = None
294-
if on_resumption_token_update or resumption_token:
295-
metadata = ClientMessageMetadata(
296-
on_resumption_token_update=on_resumption_token_update,
297-
resumption_token=resumption_token,
298-
)
265+
"""Send a tools/call request."""
299266

300267
return await self.send_request(
301268
types.ClientRequest(
@@ -306,7 +273,6 @@ async def call_tool(
306273
),
307274
types.CallToolResult,
308275
request_read_timeout_seconds=read_timeout_seconds,
309-
metadata=metadata,
310276
)
311277

312278
async def list_prompts(self) -> types.ListPromptsResult:

src/mcp/shared/session.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ async def send_request(
242242
# TODO: Support progress callbacks
243243

244244
await self._write_stream.send(
245-
SessionMessage(message=JSONRPCMessage(jsonrpc_request))
245+
SessionMessage(
246+
message=JSONRPCMessage(jsonrpc_request), metadata=metadata
247+
)
246248
)
247249

248250
# request read timeout takes precedence over session read timeout

tests/shared/test_streamable_http.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838
StreamId,
3939
)
4040
from mcp.shared.exceptions import McpError
41+
from mcp.shared.message import (
42+
ClientMessageMetadata,
43+
ResumptionToken,
44+
ResumptionTokenUpdateCallback,
45+
SessionMessage,
46+
)
4147
from mcp.shared.session import RequestResponder
4248
from 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

Comments
 (0)