Claude/Desktop/Scheduled Task/Q/Is there a declarative, programmatic way to manage Claude Desktop scheduled tasks that's scoped to a specific repo?
Is there a declarative, programmatic way to manage Claude/Desktop/Scheduled Tasks that's scoped to a specific repo?
- Short answer: Yes — an MCP tool surface (
list_scheduled_tasks, create_scheduled_task, update_scheduled_task, delete_scheduled_task) lets a session manage tasks programmatically, and the working folder is bound implicitly to whatever repo the calling session is anchored in. That's what makes it usable per-repo, and it supersedes hand-editing files or filling out the Desktop UI form. The supported mechanism
create_scheduled_task(taskId, prompt, description, cronExpression | fireAt) creates a task; update_scheduled_task(taskId, ...) does partial updates (prompt, description, schedule, enabled, notification); list_scheduled_tasks() returns every task's id, schedule, enabled state, and SKILL.md path; delete_scheduled_task(taskId) removes one.- None of these take an explicit folder/cwd argument — the task's working folder comes from the session that calls them. Running
create_scheduled_task from a session opened in a given repo is what scopes the task there, matching Desktop's own "trusted working folder" model. - That turns "define scheduled tasks declaratively for a repo" into: commit a manifest in the repo (task id, schedule, description, prompt — the same shape as the
SKILL.md frontmatter + body Desktop already writes) plus a short instruction telling Claude to reconcile it — call list_scheduled_tasks, diff by taskId, create_scheduled_task for anything missing, update_scheduled_task for anything changed. Opening the repo and asking Claude to run that reconciliation once leaves every machine with the same tasks, without ever hand-filling the New Routine form. - Net effect versus Claude/Desktop/Scheduled Task/Q/Is there a way to define a Claude Desktop scheduled task inside a repository's .claude directory so it's scoped to that repo and runs by default on any computer opening it?: still not automatic registration on clone — a session still has to run the reconciliation once per machine — but that step becomes one idempotent tool-driven action instead of manual multi-field UI entry, and it goes through a supported API rather than a file hack or symlink.
What's actually stored on disk (unofficial, background only)
- Confirmed by inspecting local application data on macOS and decompiled strings from
/Applications/Claude.app/Contents/Resources/app.asar: the registration these tools read and write lives in one JSON file per Claude account: ~/Library/Application Support/Claude/claude-code-sessions/<accountUuid>/<sessionUuid>/scheduled-tasks.json (account UUID is lastKnownAccountUuid in that same folder's config.json). - Shape:
{"scheduledTasks": [{"id", "cronExpression", "enabled", "filePath", "createdAt", "model", "cwd", "useWorktree", "lastRunAt", "approvedPermissions": [...]}], "recordedSkips": {}} — one array for every task on the machine across all repos, disambiguated only by each entry's own cwd. list_scheduled_tasks doesn't surface cwd at all, consistent with the tool being scoped by the calling session rather than by filtering that field. id must match ^[a-z0-9_-]+$ and equals the folder name under ~/.claude/scheduled-tasks/<id>/. Desktop polls the JSON file (fs.watchFile) and reloads on external change, so a raw file edit would likely still be picked up — but this is undocumented internal state with no compatibility guarantee, so the MCP tools above are the right interface, not this file.