Skip to content

MCP tools/call cancellation does not terminate Neo4j transaction #829

Open

Description

@SamwiseS

Summary

When an MCP client cancels a tools/call in flight, the underlying Neo4j transaction keeps running until it completes or is manually terminated at the Neo4j layer. There is no cancel/reset surface exposed on the CGC side, which means any hung query becomes operator-visible CPU load until someone opens cypher-shell and runs TERMINATE TRANSACTION.

Evidence

Observed behaviour

  • An MCP client (Claude Code) issued get_repository_stats, then cancelled the call after it had not returned in a reasonable time.
  • The Neo4j transaction dispatched by that call continued running for 21+ minutes after cancellation, pegging a CPU core at ~102% on the host machine.
  • The only way to stop it was docker exec neo4j-cgc cypher-shell ... "TERMINATE TRANSACTION '<id>'" after locating the id via SHOW TRANSACTIONS.

Likely root cause

src/codegraphcontext/server.py dispatches blocking Neo4j calls like this (paraphrased from line ~361):

result = await asyncio.to_thread(lambda: session.run(query, **params).data())

asyncio.to_thread makes the call awaitable, but once the blocking work is handed to the worker thread it is uncancellable from the asyncio side. Cancelling the surrounding task simply stops the coroutine from receiving the result; the Neo4j session.run continues to completion.

Impact

  • Any runaway query hangs the MCP connection indefinitely from the user's point of view.
  • The host CPU stays pegged on the Neo4j side until an operator manually terminates the transaction.
  • There is no CGC-side surface (tool, admin endpoint, config toggle) that can stop an in-flight query. The escape hatch is always "open cypher-shell, TERMINATE TRANSACTION".

Suggested direction

Transactions started in response to tools/call should be associated with a cancellation token derived from the MCP request. On cancellation, CGC should call the Neo4j dbms.killTransaction / TERMINATE TRANSACTION equivalent for that transaction id. At minimum, per-tool query timeouts (configurable, with a sane default) would prevent unbounded runaway calls.

Environment

  • CGC version: 0.2.3 (pip)
  • Neo4j: running in Docker container (neo4j-cgc)
  • Host: Windows 11, Python 3.14
  • MCP client: Claude Code

Activity

  1. github-actions commented on Apr 17, 2026

    @github-actions
    Contributor

    Hi! 👋 Join our CodeGraphContext Discord channel to collaborate: https://discord.gg/dR4QY32uYQ

  2. Shashankss1205 commented on Aug 2, 2026

    @Shashankss1205
    Collaborator

    Linking #1228, and noting that it will not close this one — worth being explicit so the two aren't conflated.

    • This issue is that an MCP tools/call cancellation doesn't terminate the running database query. Confirmed at server.py:734: result = await asyncio.to_thread(handler, **args). Work handed to to_thread is not cancellable, so the query runs to completion regardless. Fixing it needs a server-side query timeout or an explicit TERMINATE TRANSACTION.
    • feat: Add cancel_job() method to JobManager #1228 adds cancel_job() to JobManager — background indexing-job bookkeeping. core/jobs.py:21 defines JobStatus.CANCELLED and nothing ever sets it.

    Different subsystems; implementing #1228 leaves the 21 minutes of pegged CPU you measured completely unaddressed.

    A third angle on the same general gap: #1536 — switch_context tears down the DB driver while an indexing job is still running, because nothing tracks or waits on in-flight work.

  3. added
    gssoc:approvedGSSoC validation: counts toward scoring
    level:advancedGSSoC difficulty: 55 pts contributor / 30 mentor
    mentor:Shashankss1205GSSoC mentor attribution: credits reviewing mentor
    type:bugGSSoC type bonus: bug
    on Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    gssoc:approvedGSSoC validation: counts toward scoringlevel:advancedGSSoC difficulty: 55 pts contributor / 30 mentormentor:Shashankss1205GSSoC mentor attribution: credits reviewing mentortype:bugGSSoC type bonus: bug

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions