Claude Code Desktop Scheduled Tasks: Local Automation

No. They only fire while the Desktop app is open and the computer is awake, and a run scheduled during sleep is skipped. Enable Keep computer awake in Desktop settings to prevent idle sleep, though closing the lid still sleeps the machine. For tasks that must run when the computer is off, create a cloud routine instead.
When the app starts or the computer wakes, Desktop checks whether each task missed runs in the last seven days and starts exactly one catch-up run for the most recently missed time, discarding anything older. A daily task that missed six days runs once. Write prompts with guardrails, since a 9am task might actually execute at 11pm.
By default yes — tasks run against whatever state your working directory is in, including uncommitted work. Enable the worktree toggle when creating the task so each run gets its own isolated git worktree, which is usually what you want for anything that commits or opens a pull request.
Click Run now right after creating the task, watch for permission prompts, and choose always allow for each. Future runs auto-approve those tools. Two categories never offer always-allow and stall every time: connector tools your organisation set to ask, and MCP tools marked as requiring user interaction.
The prompt lives in a SKILL.md file under ~/.claude/scheduled-tasks/ named after the task, with YAML frontmatter for name and description and the prompt as the body. Edits take effect on the next run. The schedule, folder, model and enabled state are not in that file — change those through the Edit form or by asking Claude.

Key Takeaway
Claude Code Desktop scheduled tasks start a fresh session automatically at a time you choose, running on your machine with direct access to your files and tools. They fire only while the app is open and the computer is awake, and a missed schedule produces exactly one catch-up run for the most recently missed time.
I set up a daily code review for nine in the morning, closed my laptop for the weekend, and came back on Monday to a review that had run at seven that evening and diligently summarised three days of commits as though they were today's. The task worked exactly as designed. My prompt had assumed a fact about the clock that the scheduler never promised.
Local scheduled tasks are the middle option between a session loop and a cloud routine, and their constraints are specific enough to design around. This post covers what separates them from the other two, the schedule options and the deterministic offset, the catch-up rule and how to write a prompt that survives it, the permission dance that avoids stalled runs, and where the task actually lives on disk.
The Desktop app's routines page creates both kinds, which is convenient and briefly confusing. A local task runs on your machine with direct access to your files and tools, and only fires while the app is open and the computer is awake. A remote routine runs in the cloud even when your computer is off, and can additionally fire on API calls or GitHub events — but works from a fresh clone rather than your working directory.
That difference is the whole basis for choosing. If the task needs to see uncommitted work, a local checkout, or a tool that only exists on your machine, it has to be local. If it needs to happen reliably regardless of whether you are at your desk, it has to be remote. Very little sits in between.
By default a scheduled task runs against whatever state your working directory is in, including uncommitted changes. That is occasionally what you want and usually not — a task that commits or opens a pull request will happily sweep up your half-finished work. Enable the worktree toggle when creating the task and each run gets its own isolated git worktree instead.
The picker covers the common cases and plain language covers the rest, which is a good division. What is worth knowing is that your task will not fire exactly on the minute you chose, by design.
# Presets in the Schedule control:
# Manual no schedule; only runs when you click Run now
# Hourly
# Daily time picker, defaults to 9:00 AM local
# Weekdays as Daily, skipping Saturday and Sunday
# Weekly time picker plus a day picker
# For anything the picker does not offer — every 15 minutes,
# the first of each month, a single run at a future time — just
# ask Claude in any Desktop session, in plain language:
#
# "schedule a task to run all the tests every 6 hours"
# "set up a daily code review that runs every morning at 9am"
# "remind me at 3pm tomorrow to check the deploy"
#
# The last one creates a ONE-TIME task that disables itself
# after it fires.
# Each task gets a delay of a few minutes after its scheduled
# time to stagger API traffic. The delay is DETERMINISTIC — the
# same task always starts at the same offset.This is the section I wish I had read before setting up my first task. The catch-up behaviour is sensible — one run rather than six, for the most recent missed time rather than the oldest — and it means the gap between the scheduled time and the actual execution can be enormous.
# Write the prompt for the time it might ACTUALLY run.
#
# Desktop checks, on app start or machine wake, whether a task
# missed any runs in the last seven days. If so it starts
# exactly ONE catch-up run for the most recently missed time
# and discards everything older. A daily task that missed six
# days runs once on wake.
#
# So a task scheduled for 9am can genuinely execute at 11pm.
# A prompt that survives that:
Review commits pushed to main today.
If it is after 5pm, skip the review and post a one-line
summary of what was missed instead.
Do not review commits from previous days.
# Guardrails belong in the prompt, not in your assumptions
# about when the schedule fires.The general principle is that a scheduled prompt should establish its own context rather than inherit it from the schedule. Instead of review today's commits, write review commits pushed since the last run and say so if that is more than a day. The prompt is the only thing that travels with the task; the time you set is a hope.
When a task fires you get a desktop notification and a new session appears under a scheduled section in the sidebar, independent of any manual sessions you have open. Open it to see what Claude did, review the changes, or answer a permission prompt it is waiting on. Claude can edit files, run commands, create commits and open pull requests, exactly as in a session you started yourself.
One capability is missing: a scheduled task cannot send or receive messages between your desktop sessions through the app's session surface. If your mental model of automation involves tasks that talk to each other, that is the boundary — coordination has to happen through the repository, or through a mechanism outside the desktop app.
Each task has its own permission mode, set when you create or edit it, and allow rules from your user settings apply as well. A task in manual mode that needs a tool it lacks permission for stalls until you approve — the session stays open in the sidebar, so nothing is lost, but nothing happens either until you notice.
If your tasks matter enough to depend on, turn on keep computer awake in the Desktop settings so idle sleep does not skip them. Closing the laptop lid still sleeps the machine regardless, so this helps a desktop or an always-plugged-in laptop and does nothing for one you carry home. For anything that must run when the machine is off, the answer is a cloud routine rather than a setting.
Each task is a skill file, which makes editing the prompt in your editor straightforward and makes it clear what is and is not part of it. Deleting a task archives its sessions, with a checkbox in the confirmation dialog to also remove the files.
# The prompt lives on disk as a skill file:
~/.claude/scheduled-tasks/<task-name>/SKILL.md
# (or under CLAUDE_CONFIG_DIR if you set it)
#
# YAML frontmatter for name and description, prompt as the body.
# Edits take effect on the NEXT run.
# What is NOT in that file, and must be changed through the
# Edit form or by asking Claude:
# schedule
# folder
# model
# enabled state
# A running task can also reschedule ITSELF, using the
# update_scheduled_task MCP tool — so a code review can move
# itself earlier when it notices a release branch appeared.All three mechanisms are worth having, and the choice is decided by one question each.
One question per mechanism:
| Mechanism | The question it answers | Minimum interval |
|---|---|---|
| Cloud routine | Must this happen whether or not my machine is on? | One hour |
| Desktop scheduled task | Does this need my local files and tools? | One minute |
| A session loop | Am I sitting here watching it anyway? | One minute |
The habit that made these reliable for me was writing every scheduled prompt as though I had no idea when it would run, because in practice I do not. Bound the work by what it can observe rather than by the clock, turn on the worktree toggle so a run cannot sweep up whatever I left half-done, and pre-approve the tools once with a manual run. After that they are genuinely low-maintenance, which is the only kind of automation worth having.
Sources & further reading