@@ -296,6 +296,24 @@ await _transport.SendMessageAsync(new JsonRpcResponse
296296 } , cancellationToken ) . ConfigureAwait ( false ) ;
297297 }
298298
299+ private CancellationTokenRegistration RegisterCancellation ( CancellationToken cancellationToken , RequestId requestId )
300+ {
301+ if ( ! cancellationToken . CanBeCanceled )
302+ {
303+ return default ;
304+ }
305+
306+ return cancellationToken . Register ( static objState =>
307+ {
308+ var state = ( Tuple < McpSession , RequestId > ) objState ! ;
309+ _ = state . Item1 . SendMessageAsync ( new JsonRpcNotification
310+ {
311+ Method = NotificationMethods . CancelledNotification ,
312+ Params = JsonSerializer . SerializeToNode ( new CancelledNotification { RequestId = state . Item2 } , McpJsonUtilities . JsonContext . Default . CancelledNotification )
313+ } ) ;
314+ } , Tuple . Create ( this , requestId ) ) ;
315+ }
316+
299317 public IAsyncDisposable RegisterNotificationHandler ( string method , Func < JsonRpcNotification , CancellationToken , Task > handler )
300318 {
301319 Throw . IfNullOrWhiteSpace ( method ) ;
@@ -357,9 +375,16 @@ public async Task<JsonRpcResponse> SendRequestAsync(JsonRpcRequest request, Canc
357375 _logger . SendingRequest ( EndpointName , request . Method ) ;
358376
359377 await _transport . SendMessageAsync ( request , cancellationToken ) . ConfigureAwait ( false ) ;
360-
361378 _logger . RequestSentAwaitingResponse ( EndpointName , request . Method , request . Id . ToString ( ) ) ;
362- var response = await tcs . Task . WaitAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
379+
380+ // Now that the request has been sent, register for cancellation. If we registered before,
381+ // a cancellation request could arrive before the server knew about that request ID, in which
382+ // case the server could ignore it.
383+ IJsonRpcMessage ? response ;
384+ using ( var registration = RegisterCancellation ( cancellationToken , request . Id ) )
385+ {
386+ response = await tcs . Task . WaitAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
387+ }
363388
364389 if ( response is JsonRpcError error )
365390 {
0 commit comments