Prevent cancellation of initialize request per MCP spec (#1350)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
This commit is contained in:
parent
374f7195e5
commit
4f7095453c
1 changed files with 99 additions and 3 deletions
|
|
@ -190,11 +190,16 @@ internal sealed partial class McpSessionHandler : IAsyncDisposable
|
|||
{
|
||||
// Register before we yield, so that the tracking is guaranteed to be there
|
||||
// when subsequent messages arrive, even if the asynchronous processing happens
|
||||
// out of order.
|
||||
// out of order. Per spec, "The initialize request MUST NOT be cancelled by clients",
|
||||
// so we don't track it in _handlingRequests to prevent cancellation notifications from
|
||||
// canceling it.
|
||||
if (messageWithId is not null)
|
||||
{
|
||||
combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||
_handlingRequests[messageWithId.Id] = combinedCts;
|
||||
if (message is not JsonRpcRequest { Method: RequestMethods.Initialize })
|
||||
{
|
||||
_handlingRequests[messageWithId.Id] = combinedCts;
|
||||
}
|
||||
}
|
||||
|
||||
// If we await the handler without yielding first, the transport may not be able to read more messages,
|
||||
|
|
@ -528,9 +533,10 @@ internal sealed partial class McpSessionHandler : IAsyncDisposable
|
|||
// Now that the request has been sent, register for cancellation. If we registered before,
|
||||
// a cancellation request could arrive before the server knew about that request ID, in which
|
||||
// case the server could ignore it.
|
||||
// Per spec, "The initialize request MUST NOT be cancelled by clients", so skip registration for initialize.
|
||||
LogRequestSentAwaitingResponse(EndpointName, request.Method, request.Id);
|
||||
JsonRpcMessage? response;
|
||||
using (var registration = RegisterCancellation(cancellationToken, request))
|
||||
using (var registration = method != RequestMethods.Initialize ? RegisterCancellation(cancellationToken, request) : default)
|
||||
{
|
||||
response = await tcs.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue