claude-code·9 min read·
Claude Code on Windows Task Scheduler for UK indie hackers in 2026
Your UK desk PC is on anyway. It is cheaper, faster, and more private than a cloud worker for most overnight jobs. Here is how to wire Claude Code into Windows Task Scheduler properly: PATH, working directory, NonInteractive, logging, and a 7am morning brief that just works.

Most UK indie hackers run their side projects on the same Windows 11 PC they use for everything else. It is on from 7am to midnight, it is paid for, it sits in the corner of the living room or the spare bedroom, and it is doing approximately nothing for nineteen of those hours. That spare capacity is, frankly, free agent compute. Once you have written a Claude Code workflow that does something useful - a morning brief, a nightly QA pass, a weekly competitor scrape - the next move is not to deploy it. The next move is to schedule it. On the machine you already own.
This post is the practical UK builder's guide to Windows Task Scheduler with Claude Code. The schtasks route, the PowerShell wrapper, the logging discipline, the pitfalls that will eat your Saturday afternoon if you skip them. We finish with a concrete worked example: a 7am Companies House morning brief that pulls fresh filings for a watchlist of competitors and emails you a one-pager before your second coffee.
Why a UK desk PC beats a cloud worker for most jobs
Cloud workers are great when you genuinely need always-on, public-facing, multi-user infrastructure. For everything else - and "everything else" is most of what an indie hacker actually schedules - a home PC is the better answer.
The numbers, roughly. A Railway worker with persistent storage is around GBP 4 to 8 per month. A Hetzner box is around GBP 4. A Vercel cron on the Hobby plan is free but capped at 60 seconds, which is short for a real agent run. A UK home desktop sat at idle costs around 5 to 8p a day in electricity at current rates, runs the agent in 15 seconds with no cold start, keeps every byte of data inside your house, and does not need a GDPR conversation. If your agent only fires a handful of times a day and does not need a public endpoint, the home PC wins on every axis except resilience.
Resilience is the honest caveat. Power cuts happen. Windows reboots after updates. You will, occasionally, find a job did not run because the PC was asleep. The mitigation is a power plan that prevents sleep, an automatic reboot recovery setting in Task Scheduler, and a "if this job did not run in the last 24 hours, ping me" cloud canary. Half a day of plumbing buys you 90% of cloud-level reliability at zero ongoing cost.
For background on the headless side of Claude Code that you are going to be scheduling, the headless claude -p scripting guide covers the flags and prompt patterns you will lean on here.
The two routes: schtasks and the GUI
Task Scheduler has two front doors. The Task Scheduler app under Computer Management, which is fine for a one-off setup but tedious to repeat, and schtasks.exe, the command-line tool, which lets you commit your schedule to git alongside your agent code. UK indie hackers should default to schtasks because it makes your setup reproducible. If your dev PC dies, you reinstall Windows, clone the repo, run one script, and you are back.
The shape of a minimal schtasks command in PowerShell:
schtasks /Create `
/TN "MorningBrief" `
/TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\ClaudeProjects\morning-agent\run.ps1" `
/SC DAILY `
/ST 06:55 `
/RL HIGHEST `
/F
That creates a task called MorningBrief that fires every day at 06:55, runs a PowerShell script as the highest-privilege user, and overwrites any existing task with the same name. -NoProfile keeps PowerShell startup fast and predictable. -ExecutionPolicy Bypass lets your unsigned script run without prompting. /RL HIGHEST matters if your script touches anything protected; if it does not, drop it.
The Program/script field should always point at powershell.exe, not at claude.exe directly. You want a script in the middle that handles environment, logging, and exit codes. We will write that script next.
The PowerShell wrapper that solves 90% of pitfalls
Here is the wrapper that turns a scheduled task from "it sort of works" into "it ships". Save this as C:\ClaudeProjects\morning-agent\run.ps1.
$ErrorActionPreference = "Stop"
$root = "C:\ClaudeProjects\morning-agent"
Set-Location $root
$env:PATH = "$env:USERPROFILE\AppData\Roaming\npm;" + $env:PATH
$env:ANTHROPIC_API_KEY = (Get-Content "$root\.env" |
Where-Object { $_ -match "^ANTHROPIC_API_KEY=" }) -replace "^ANTHROPIC_API_KEY=", ""
$logDir = "$root\logs"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory $logDir | Out-Null }
$logFile = "$logDir\$(Get-Date -Format yyyy-MM-dd).log"
"=== Run started $(Get-Date -Format o) ===" | Out-File $logFile -Append
try {
claude -p (Get-Content "$root\prompts\morning.md" -Raw) `
--output-format json `
--max-turns 8 *>> $logFile
"=== Run OK $(Get-Date -Format o) ===" | Out-File $logFile -Append
}
catch {
"=== Run FAILED $(Get-Date -Format o): $($_.Exception.Message) ===" |
Out-File $logFile -Append
exit 1
}
Five things this wrapper fixes:
- PATH. Task Scheduler gives you a stripped environment. The
claudecommand lives under%USERPROFILE%\AppData\Roaming\npmif you installed via npm. Prepend it explicitly so the script never has to guess. - Working directory.
Set-Location $rootpins you to the project folder before anything else runs. Claude Code reads its CLAUDE.md from the working directory; without this line you are inSystem32and your context is gone. - API key. Read from a
.envfile you keep out of git, not from a user environment variable that Task Scheduler may or may not inherit. Belt and braces. - Logging. Every run goes to a dated file under
logs/.*>>redirects all output streams (stdout, stderr, info, warnings) to the file. You will thank yourself the first time a 7am run misbehaves. - Exit code. A non-zero exit from the script bubbles up to Task Scheduler's "last result" field, which Task Scheduler can use to trigger a follow-up task (email-on-failure, for example).
This is the wrapper that should sit in every scheduled Claude Code agent you build. Copy it. Vary the body. Keep the scaffolding.
The five pitfalls that will eat your Saturday
These are the bugs every UK indie hacker hits the first time. Plan for them.
PATH. The claude binary, node, python, git, gh - none of them are guaranteed to be on PATH when Task Scheduler runs your script. Either use absolute paths or set PATH explicitly at the top of your wrapper. If your script works in a terminal and fails in Task Scheduler, PATH is the first place to look.
Working directory. The default is C:\Windows\System32. Claude Code reads CLAUDE.md, .mcp.json, settings.json from the working directory. Without a Set-Location at the top of your script, you lose all of that. The Start in (optional) field in the Task Scheduler GUI does the same job, but a Set-Location inside the script is more reliable and survives a refactor of the task definition.
NonInteractive flag. PowerShell launched from Task Scheduler does not know it is non-interactive unless you tell it. If your script accidentally hits a Read-Host, Get-Credential, or any cmdlet that wants a prompt, the task will hang forever. Add -NonInteractive to the powershell.exe call in your schtasks /TR argument and your script will fail fast rather than block. Most modern scripts do not need this, but if you are calling third-party tooling it is cheap insurance.
OneDrive and Dropbox. Do not run agents inside a OneDrive or Dropbox sync folder. The sync client will lock files mid-write, Claude Code will see a stale version of CLAUDE.md, and you will spend an hour wondering why your context is wrong. Keep scheduled projects under C:\ClaudeProjects\ or similar. If you need cloud backup, push to a private GitHub repo on a schedule - that is what version control is for. Network drive paths (UNC like \\server\share) are worse: they can disappear when Wi-Fi drops, and Task Scheduler will give you a misleading error.
Encoding. Windows PowerShell 5.1 writes files in UTF-16 LE by default. If your agent reads its prompt from a file your wrapper wrote, and the file is UTF-16 but your prompt expects UTF-8, you will get phantom characters. Always pass -Encoding utf8 when writing files that another tool will read. PowerShell 7 fixed this; if you can install it (winget install --id Microsoft.Powershell), do.
Smoke-testing a scheduled task
Once you have created the task with schtasks, the worst thing you can do is wait until 06:55 tomorrow to find out it does not work. Smoke-test it now:
# Trigger immediately, ignoring the schedule
schtasks /Run /TN "MorningBrief"
# Watch the log
Get-Content "C:\ClaudeProjects\morning-agent\logs\$(Get-Date -Format yyyy-MM-dd).log" -Wait
# Check last result code (0 = success, non-zero = failure)
schtasks /Query /TN "MorningBrief" /V /FO LIST | Select-String "Last Result"
A Last Result of 0 means the task ran cleanly. 267009 means it is still running. 1 is a generic script error - read the log. 2147942402 means the script file was not found - your /TR path is wrong. 2147750687 is a permissions issue - try /RL HIGHEST or run the task as your own user account rather than SYSTEM.
If you have a hooks setup for your interactive Claude Code, note that hooks fire in headless runs too. Make sure none of them shell out to interactive tools or your scheduled task will stall.
The worked example: a 7am Companies House morning brief
Concrete shippable example, end to end. You are a UK sole trader. You have a watchlist of ten competitor companies and you want to know if any of them filed something interesting yesterday before you start your working day.
The pieces:
- A watchlist file
watchlist.jsonwith ten Companies House numbers. - A prompt
prompts/morning.mdthat tells the agent how to fetch and summarise. - A
.envwith yourANTHROPIC_API_KEYandCH_KEY(Companies House is free, ten minutes to register). - The
run.ps1wrapper above, scheduled at 06:55. - A Resend account on the free tier (GBP 0/mo for 3,000 emails) to deliver the brief to your inbox.
The prompt body is short:
Read ./watchlist.json. For each company number, call the
Companies House filings API. Summarise any filings dated
within the last 24 hours. If there are none, say so plainly.
Format as a markdown brief with one section per company.
Send the brief by email via the Resend MCP tool to
tim@example.co.uk with subject "Morning brief YYYY-MM-DD".
The whole project is around 60 lines of code plus the wrapper. Token budget at current Sonnet pricing: roughly 2p to 5p per morning, so GBP 0.40 to GBP 1.00 per month. Resend free tier covers the email. Electricity to keep the PC on overnight: already paid. Total marginal cost: under GBP 1.
The first time the brief lands in your inbox at 07:02 you will understand why scheduled agents are the single biggest leverage move available to a UK indie hacker in 2026. You did not deploy anything. You did not pay for a worker. You did not write a CI pipeline. You wrote a prompt, a wrapper, and one schtasks command, and you have a tiny employee who works the first hour of your day before you have brushed your teeth.
For the wider question of what to schedule first - which UK opportunity is worth automating, and which is worth ignoring - have a look at the Claude Code multi-agent orchestration guide for patterns on chaining several scheduled agents into a pipeline.
What to schedule next
Once the first scheduled task is running clean, the marginal cost of a second one is nothing. The PC is on either way. UK indie hackers should consider, in rough priority order:
- A nightly QA agent that runs
npm test(or your equivalent) across your active repos and writes a one-page report to your inbox. - A weekly competitor scrape that pulls homepage copy from your top three rivals and flags significant changes.
- A fortnightly licence audit that opens
package.jsonin each repo, checks for newly introduced packages, and verifies the licences are commercial-friendly. - A monthly invoice chase that reads your accounting export, finds invoices older than 30 days, and drafts (not sends) chase emails.
Each is small. Each saves an annoying hour. Stack five and you have bought back a day a fortnight, on a PC you were going to keep running anyway.
New here? IdeaStack publishes one deeply researched UK business opportunity every Thursday - real keyword data, competitor analysis, builder prompts. See the latest free report.
Frequently asked
Why use Windows Task Scheduler instead of a cloud cron job?
For a UK indie hacker with a desktop PC that stays on, Task Scheduler is the cheapest host you will ever find. No monthly bill, no cold starts, no egress charges, no GDPR worries about where the data sits. The trade-off is reliability: power cuts, Windows updates, and laptop sleep states will all bite you. Run mission-critical jobs in the cloud and personal ops jobs at home.
Do I need a Claude Code Pro plan to run scheduled headless tasks?
It depends on what you run. Interactive Claude Code sessions are covered by the Pro plan. Headless runs via claude -p and Agent SDK calls are billed on your Anthropic API key. From 15 June 2026 these move to a separate monthly credit pool, still capped at your subscription price. Either way, set a hard daily spend cap on your key in the Anthropic console before you schedule anything.
What is the right working directory for a scheduled Claude Code task?
Always set Start in to an explicit local project folder, never let it default. A scheduled task without a working directory will land you in C:\Windows\System32 and Claude Code will not find your CLAUDE.md, your .env, or any of your context files. Use a path like C:\ClaudeProjects\my-agent and double-check it is not inside OneDrive or Dropbox unless you want sync collisions.
Why do my scheduled tasks fail when they work fine in the terminal?
Nine times out of ten it is PATH or working directory. Task Scheduler runs under a stripped environment. The claude command, node, or python may not resolve. Fix it by using the full path to the executable in your Program/script field, or by wrapping the call in a PowerShell script that sources your profile first. The remaining one in ten is permission scope - run with highest privileges if the script touches protected folders.
Can I log scheduled Claude Code runs to a file I can read in the morning?
Yes, and you should. Redirect stdout and stderr to a dated log file from your wrapper script. A line like claude -p prompt.md >> logs\$(Get-Date -Format yyyy-MM-dd).log 2>&1 gives you per-day logs you can grep through. Pair it with a tiny notifier that pings you on non-zero exit and you have observability without spending a penny on monitoring tools.
Filed under




