Skip to content

[FEATURE] Add delete_scheduled_task to the scheduled-tasks MCP (Cowork) #59981

Description

Summary

The Cowork scheduled-tasks MCP exposes only create_scheduled_task, list_scheduled_tasks, and update_scheduled_task. There is no delete_scheduled_task. Disabled or obsolete tasks accumulate in the list permanently and cannot be removed from inside Claude Code.

Reproduction

  1. Create two tasks via create_scheduled_task (or via the Cowork UI).
  2. Disable one of them by calling update_scheduled_task(taskId: "...", enabled: false).
  3. Call list_scheduled_tasks — the disabled task still appears.
  4. There is no MCP method to remove it.

Editing the underlying state file does not help: the MCP keeps the canonical state in memory and rewrites the file every few minutes, restoring the entries.

Tested state file (Windows):
%APPDATA%\Claude\claude-code-sessions\<accountId>\<sessionId>\scheduled-tasks.json

Observed sequence on my machine (2026-05-17):

  • 11:03 — file shows 5 tasks (4 disabled, 1 active).
  • 11:04 — I edited the file on disk to remove the 4 disabled entries (file shrunk to ~80 KB, 1 entry).
  • 11:07 — MCP server rewrote the file (back to 232 KB, 5 entries).
  • 11:08 — Disk again shows 5 tasks; list_scheduled_tasks likewise.

Impact

  • Cannot maintain a clean task list. Old experiments and renamed tasks remain visible forever.
  • Workaround (closing Claude Code, editing the file, reopening) is fragile and loses the active session.
  • update_scheduled_task accepts no delete: true flag, so even a privileged side-channel deletion is unavailable.

Proposed fix

Add delete_scheduled_task(taskId) to the MCP:

  • Removes the entry from in-memory state and from the persisted state file in the same atomic write.
  • Refuses if enabled: true unless force: true is provided (safety check against accidental deletion of live schedules).
  • Returns a clear result: { deleted: true, taskId } or an error if the taskId does not exist.

Environment

  • Claude Code version: 2.1.138
  • OS: Windows 11
  • MCP server: built-in scheduled-tasks (Cowork)

Activity

  1. kcarriedo commented on May 17, 2026

    @kcarriedo

    This is a clean case of the MCP server owning state that the user can't reach through the protocol — the rewrite-every-few-minutes behaviour is the giveaway. The in-memory map is the source of truth and the JSON file is just a periodic snapshot, so any out-of-band edit is racing the next flush and losing.

    A couple of notes from running into the same shape on adjacent MCP servers:

    1. The asymmetric tool surface is the actual bug, not just a missing verb. create / list / update without delete implies the server thinks "disabled" is the terminal state for a task and that list-filtering on the client side is the intended UX. The reality is that long-lived sessions accumulate a backlog of disabled tasks that you'd want gone for the same reasons you'd close-and-archive a Jira ticket — they pollute auto-complete, scroll the active task off-screen, and make list_scheduled_tasks results unparseable to downstream agents that don't know to filter. A delete_scheduled_task is the right verb; an archive_scheduled_task (separate from enabled:false) would also work and is arguably more honest about cron-style semantics.

    2. The force:true flag belongs on the currently-running axis, not the enabled axis. Refusing to delete an enabled:true task without force is a fine guardrail, but the more dangerous case is deleting a task whose handler is mid-execution — that one should require force:true (and ideally return a running_invocation_id in the error so the caller can decide whether to wait or kill). enabled:false + currently-running can happen if the task just got disabled but the in-flight invocation hasn't returned yet.

    3. Atomic-write contract matters here more than usual. Because the file is rewritten on a timer, the failure mode if delete_scheduled_task writes-then-crashes mid-write is that the next periodic flush silently resurrects the deleted entry from the in-memory map. The delete needs to (a) remove from in-memory state, (b) cancel/flush any pending periodic-write timer, (c) write the new snapshot atomically (write-temp + rename), then (d) re-arm the periodic timer. If (a) and (c) aren't in the same critical section, you've shipped a bug.

    Adjacent symptom worth flagging on this issue for posterity: when the disabled-task list grows past ~5 entries, the list_scheduled_tasks response gets large enough that some MCP clients truncate it before the model sees the active task. The "can't delete" bug is also a "can't see the active task" bug at scale.

  2. Cupid673 commented on May 22, 2026

    @Cupid673

    +1 — also hitting this on Windows after migrating scheduled-tasks storage to a network share via NTFS junction. Built a filesystem-side cleanup handler (cron-driven, dry-run-first) as workaround, but the register-side ghosts described in your issue are by-design unreachable from the MCP — so the cleanup is half-coverage.

    Originally filed as #61445 (3-bug cluster: no-delete + path-traversal-UNC + filesystem-ghost-orphan). Closed as duplicate of this issue + #56244 (path traversal). Linking here for cross-ref.

  3. github-actions commented on Jun 22, 2026

    @github-actions

    Closing for now — inactive for too long. Please open a new issue if this is still relevant.

  4. github-actions commented on Aug 24, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  5. locked as resolved and limited conversation to collaborators on Aug 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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions