Claude Code Scheduled Tasks: Setting Them Up and Keeping Oversight

Claude Code can run on a schedule inside a session, on your desktop, in the cloud, or from cron and CI. Nobody is there to approve anything when it does, so the permissions are decided in advance and the results have to land where a person will read them.

7 min read

Claude Code has three documented ways to schedule work: /loop and its cron tools inside an open session, scheduled tasks in the Desktop app that run on your machine, and routines that run in the cloud and are created with /schedule. Outside those, claude -p runs non-interactively, so cron, Windows Task Scheduler or a CI schedule can start it. Whichever you choose, the run is unattended: nobody is there to answer a permission prompt, so you decide beforehand exactly which tools it may use. And nobody is watching the output, so the result has to land somewhere a person reads, such as a comment on the card the job is about, written with a token that can read and comment and do nothing else.

The options, side by side

  • /loop — runs a prompt on an interval while the session stays open, on your machine. Minimum interval one minute. Good for polling a deploy or a pull request this afternoon.
  • Desktop scheduled tasks — start a new session on your machine at a time you choose, with access to your local files. The app must be open and the computer awake. Permission mode is set per task.
  • Routines — run in Anthropic’s cloud on a fresh clone of your repository, with your machine off. Minimum interval one hour. They run without permission prompts. A research preview, on Pro, Max, Team and Enterprise plans.
  • claude -p from a scheduler — your own cron job, Task Scheduler entry or CI workflow, on whatever machine you choose. You own the schedule and every permission.

/loop: scheduling inside a session

In a Claude Code session
/loop 30m check whether CI passed on this branch and tell me what failed
remind me at 3pm to push the release branch
what scheduled tasks do I have?

Behind these, Claude uses three tools: CronCreate, CronList and CronDelete. The details worth knowing are all limits. Tasks fire only while Claude Code is running and idle, between your turns. Times are local. A recurring task fires up to 30 minutes late by design (the docs (opens in a new tab) call it jitter), and expires after seven days. A session holds at most 50. Starting a new conversation clears them. CLAUDE_CODE_DISABLE_CRON=1 turns the scheduler off entirely.

A loop inherits the session’s permissions, so it is only as unattended as the session is. It is the right tool for watching something today, not for a nightly job.

Desktop scheduled tasks and cloud routines

In the Desktop app’s Code tab, Routines, New routine, choose Local for a task on your machine or Cloud for a routine. A local task has its own permission mode. If it runs in Manual mode and reaches a tool it has no approval for, the run stalls until you approve it. The docs (opens in a new tab) suggest clicking Run now once after creating it, answering each prompt with “always allow”, and reviewing those approvals later in its Always allowed panel. There is also a worktree toggle, so each run gets its own checkout instead of your working directory with its uncommitted changes.

Routines run as full cloud sessions with no permission-mode picker: they run shell commands and call your connectors without stopping for approval. Three details from the documentation (opens in a new tab) matter for oversight. Connectors are the ones on your claude.ai account, and all of them are included by default, so remove the ones a routine does not need. Anything a routine does through a connector appears as you. And a green status in the run list means the session started and exited without an infrastructure error, not that the job succeeded; you have to open the run to find out.

claude -p from cron or CI

The most controllable option is the plainest: a non-interactive run on a machine you choose, started by a scheduler you already use. A -p run loads the same configuration an interactive session would, including your MCP servers, unless you pass --bare. Here is a weekday job that reviews the In Progress lane and comments on anything stale:

crontab
10 7 * * 1-5  cd /srv/app && claude -p "$(cat .claude/morning-review.md)" \
  --permission-mode dontAsk \
  --allowedTools "Read,Grep,Glob,mcp__fenbs__fenbs_get_context,mcp__fenbs__fenbs_list_items,mcp__fenbs__fenbs_get_item,mcp__fenbs__fenbs_comment" \
  --max-turns 40 >> "$HOME/logs/morning-review.log" 2>&1

Each flag is doing a job. --allowedTools lists what may run without asking, using the same rule syntax as settings, including MCP tools by their full mcp__<server>__<tool> name. --permission-mode dontAsk denies anything that would otherwise prompt, which the docs (opens in a new tab) describe as useful for locked-down CI runs. --max-turns stops a run that is going in circles. On recent versions, --permission-prompts none also tells Claude that nobody can approve a request, so it does not keep retrying one.

The same pattern works in CI. The Claude Code GitHub Action (opens in a new tab) runs on any event, including a cron schedule, and with a plain prompt Claude has no shell or API access until you grant tools with --allowedTools in claude_args.

Permissions for a run nobody watches

An interactive session has you as its last line of defence. A scheduled one does not, so the limits have to be in place before it starts. Three questions settle most jobs:

  • What does it need to read? Usually the code and the board. Grant Read, Grep, Glob and the board’s read tools, and nothing more.
  • What does it need to change? For a review, a triage pass or a report: nothing but comments. For a job that fixes things, grant edits and specific commands, such as Bash(npm test *), rather than all of Bash.
  • Where does it write its result? One place, named in the prompt.

Claude Code’s permissions limit what the run may do on the machine. The board has its own gate, and it is worth using both. In fenbs, issue a token by hand under Settings, “Connect an AI assistant”, tick read and comment only, name it after the job, and set an expiry. Revoke it the day the job is retired. That token can list and read tasks and comment on them. It cannot move, add or edit a task, whatever the prompt says and whatever the allowed-tools list says, because the board checks the token’s scopes itself, on its own side of the connection. Name it after the job, so it can be revoked on its own without touching your other assistants.

Once, on the machine that runs the job
claude mcp add --transport http fenbs https://fenbs.ai/api/mcp --header "Authorization: Bearer YOUR_TOKEN"

If the job should file what it finds as new tasks, tick write as well and have it pass key to fenbs_create_item. The same key never files twice, so a nightly run that sees the same failing test every night comments on one task instead of opening seven.

Oversight: results on the card

A log file on a server is where a scheduled job’s output goes to be ignored. The run list for a routine is better, but it lives with one person’s account. What works is putting each result where the work is already discussed: on the card it concerns, as a comment, signed with the job’s name.

.claude/morning-review.md
You are the morning review job. Start every comment with "Morning review:".
1. Call fenbs_get_context, then list lane "doing".
2. For each card with no comment in the last two working days, comment:
   what the last comment said, and one question for its owner.
3. Change nothing else. If you cannot finish, comment on no card and
   end with a one-line reason.

The review is then the board itself. Every comment appears in the history as “Claude via <your name>”, and the prefix says which job wrote it. A person reading a card sees the job’s question next to the work it concerns, and can answer it there. If the job misbehaves, the history shows exactly what it did, and revoking its token stops it at once without touching anything else.

For the wider question of which decisions should wait for a person at all, see human in the loop for AI agents. For a regular look at what every connected assistant can do and has done, see how to audit AI agents.

Related

What each scope allows: assistant tokens and scopes. Connecting Claude Code, by sign-in or with a token: Claude Code integration and the MCP docs. Which MCP risks matter most for a job that runs alone: MCP security best practices.

Questions people ask.

Can Claude Code run tasks on a schedule?

Yes. /loop and the cron tools schedule prompts inside an open session, the Desktop app runs scheduled tasks on your machine, and routines run in the cloud and are created with /schedule. You can also start claude -p from cron, Task Scheduler or a CI schedule.

How do I stop a scheduled Claude Code run from asking for permission?

Decide the permissions in advance. List the tools it may use with --allowedTools and pass --permission-mode dontAsk, which denies anything that would otherwise prompt instead of waiting for an answer. For a Desktop task, run it once and choose always allow for each tool it needs.

How long does a /loop schedule last?

Recurring tasks expire seven days after they are created, and all session-scoped tasks stop when the session exits or you start a new conversation. For durable schedules, use Desktop scheduled tasks, routines or your own scheduler with claude -p.

What access should a scheduled job have on the board?

For reviews, triage and reports, read and comment only. In fenbs, issue a token with just those scopes, name it after the job, set an expiry, and revoke it when the job is retired. It can then report on cards but cannot move, add or edit a task, and revoking it affects nothing else.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.