Skip to content

MCP tool handlers do not accept or propagate CancellationToken from the client #1418

Description

@Widthdom

Summary

None of the MCP tool handlers accept or propagate a CancellationToken. JSON-RPC $/cancelRequest notifications from the client are effectively ignored — long-running impact_analysis, index, or large search calls run to completion even after the client cancels (or disconnects).

Evidence

  • src/CodeIndex/Mcp/McpServer.cs dispatches each tool call synchronously and does not maintain a per-request CancellationTokenSource.
  • src/CodeIndex/Mcp/McpToolHandlers.cs — every Execute* method is synchronous (JsonNode Execute*(...)) with no CancellationToken parameter.
  • Verified codebase-wide: a search for catch (OperationCanceledException) returns zero hits, confirming there is no cooperative cancellation anywhere downstream of MCP handlers.

Impact

  • A user pressing Ctrl-C in their IDE-side MCP client cannot interrupt a multi-minute indexing or analysis call.
  • Disconnected clients leave the server doing wasted work.
  • This is a prerequisite for the cancellation issues in IndexCommandRunner.RunFullScan and DbWriter backfills (related issues filed separately).

Proposed direction

  1. Maintain a ConcurrentDictionary<requestId, CancellationTokenSource> in McpServer.
  2. On $/cancelRequest, look up the request id and cancel the token.
  3. Plumb CancellationToken through all Execute* methods and into DB / file walks.
  4. Wrap each handler invocation in a try { ... } catch (OperationCanceledException) { return CreateCancelledResponse(id); }.

Repro env

  • Branch: main @ 2ee912d (release v1.21.0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions