Skip to content

MCP: Handle notifications/cancelled to abort running requests #34

@evansenter

Description

@evansenter

Summary

When Claude Code sends notifications/cancelled (user hit ctrl-c), clemini ignores it and the Gemini request keeps running in the background. This wastes API tokens and can cause confusion if the abandoned task modifies files.

Current Behavior

// mcp.rs line 262-264
if request.method.starts_with("notifications/") {
    continue;  // Just ignores cancellation!
}

And tools/call spawns a task that runs independently:

tokio::spawn(async move {
    // This keeps running even after cancellation
});

Expected Behavior

When notifications/cancelled arrives:

  1. Abort any running tools/call task
  2. Clean up gracefully
  3. The spawned task should stop (not continue burning tokens)

Implementation

In mcp.rs:

  1. Store the JoinHandle from the spawned task:
let mut current_task: Option<tokio::task::JoinHandle<()>> = None;

// When spawning:
current_task = Some(tokio::spawn(async move { ... }));
  1. Handle the cancellation notification:
if request.method == "notifications/cancelled" {
    if let Some(handle) = current_task.take() {
        handle.abort();
    }
    continue;
}
  1. The task should handle JoinError::is_cancelled() gracefully if needed.

Testing

  1. Start clemini MCP server
  2. Send a long-running request (e.g., complex code generation)
  3. Send notifications/cancelled
  4. Verify in /tmp/clemini.log that tool calls stop after cancellation

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:highCritical priority

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions