Claude Code becomes an automation tool when you stop typing prompts into it and start calling it from a script. This tutorial builds one small, useful automation from scratch: every weekday morning, Claude reads your last 24 hours of git commits and writes a plain-English digest to a file.
You will do it in three parts:
A skill holds the instructions, so you write them once.
A headless call (claude -p) runs that skill with no interactive session.
A schedule runs it for you.
The digest is deliberately simple. The same pattern works for changelog drafts, dependency checks, log summaries and PR triage. Swap the skill and keep the plumbing.
Rough timing: install and check, 5 minutes; try the task by hand, 5; write the skill, 10; wrap it in a script, 5; schedule it, 5 or more depending on the option. If Claude Code is already installed and logged in, you will finish sooner.
What you need
A terminal and a git repository with recent commits (any project works)
A Claude subscription (Pro, Max, Team or Enterprise), a Claude Console account, or access through a supported cloud provider
Claude Code installed and logged in (Step 1)
Command syntax and behavior below follow Anthropic's Claude Code documentation as of late September 2026. Claude Code ships updates often, so where a feature depends on a version, the article says so.
Step 1: Install Claude Code and confirm it works
The native installer is Anthropic's recommended route. It needs no Node.js and updates itself in the background.
macOS, Linux, WSL:
curl -fsSL https://claude.ai/install.sh | bash
Windows PowerShell:
irm https://claude.ai/install.ps1 | iex
Homebrew (brew install --cask claude-code) and WinGet (winget install Anthropic.ClaudeCode) also work. Those two do not auto-update, so upgrade them manually. Some older tutorials still tell you to install through npm; the current quickstart does not.
Open a new terminal window and check:
claude --version
If it prints a version number, you are set. If your shell says claude is not found, the install directory is not on your PATH yet. Anthropic's install troubleshooting page covers the fix.
Then log in once by starting an interactive session:
cd /path/to/your/repo claude
Follow the browser prompts. Your credentials are stored, so scripted runs can reuse them later.
Prefer not to use a terminal at all? Claude Code also has a Desktop app with a Code tab. This tutorial uses the CLI because scripting and scheduling are simplest there.
Step 2: Do the task by hand first
Before automating anything, run the task interactively and see whether the output is what you want. A weak prompt automated on a schedule just produces weak output every morning.
Two habits from community guides are worth borrowing here. First, ask for a plan before any work. Bloggers who teach Claude Code to beginners (AI Builder Club calls it an explore, plan, code, commit workflow) say skipping the plan step causes the most bad output. Second, put the work on a separate git branch for your first week so any mistake is one checkout away. Both are opinions from community writers, not official rules, but they cost almost nothing.
Inside your repo, start claude and try:
Look at the git commits from the last 24 hours and write a short, plain-English digest for a teammate who wasn't here. Group related changes. Flag anything that looks risky.
Iterate until you like the result. Tighten the wording, add constraints, decide on a length. That final prompt is what you will save as a skill.
Step 3: Turn the prompt into a skill
A skill is a folder with a SKILL.md file. Claude Code can load it automatically when relevant, and you can invoke it directly as /skill-name. For automation, the direct call matters most, because a skill gives your scheduled job a stable, named set of instructions instead of a long prompt buried in a shell script.
Create the folder. Personal skills live in ~/.claude/skills/ and are available in all your projects on that machine:
mkdir -p ~/.claude/skills/daily-digest
Save this as ~/.claude/skills/daily-digest/SKILL.md:
description: Turns the last 24 hours of git commits into a short plain-English digest. Use when asked for a daily digest or a summary of recent commits. allowed-tools: Bash(git log *) --- ## Commits from the last 24 hours !`git log --since="24 hours ago" --no-merges --pretty=format:"%h %an: %s"` ## Instructions Write a digest of the commits above for a teammate who was away. - Start with one sentence on the overall theme of the day. - Group related commits under short headings. - Add a "Worth a second look" section only if something looks risky (large refactors, config changes, removed tests). - If there are no commits, reply with exactly: "No commits in the last 24 hours." - Keep it under 250 words. Output Markdown only, no preamble.
What each part does:
The frontmatter description tells Claude when the skill applies. The directory name (daily-digest) becomes the command you type.
allowed-tools pre-approves the listed git command so it needs no permission prompt. Anthropic's docs note that the grant applies during the turn that invokes the skill.
The line starting with ! followed by a backtick is dynamic context injection. Claude Code runs the command before Claude sees the skill and swaps in the output. The model receives your actual commits, not a request to go fetch them. That makes the automation more predictable, because the data-gathering step is a fixed command.
The rest is the instruction set from Step 2.
Test it interactively from inside your repo:
/daily-digest
Claude Code watches skill folders for changes, so edits to SKILL.md are picked up within the same session without a restart.

Optional: add a short CLAUDE.md
CLAUDE.md is a file in your project that Claude reads at the start of a session, so it remembers stable facts and rules. Community guides from Build to Launch and AI Builder Club both recommend it as the highest-value five-minute setup. Keep it short: two sentences on what the project is, how to run and test it, and a few things Claude should never do. A file you can maintain beats a long one that drifts. Note that --bare runs (see Step 7) skip CLAUDE.md, so anything the job depends on should live in the skill itself.
Step 4: Run it headless with claude -p
The -p (or --print) flag runs Claude Code non-interactively. It takes your prompt, does the work, prints the result and exits. Anthropic's docs describe this as the CLI form of the Agent SDK.
User-invoked skills work in -p mode: put /skill-name in the prompt string and Claude Code expands it before running. From your repo directory:
claude -p "/daily-digest"
The digest prints to your terminal. Redirect it to a file and you have an automation:
claude -p "/daily-digest" > digest.md
A few properties of -p matter once you script it:
Exit codes: it exits 0 on success and non-zero on failure, so scripts can branch on the result.
Failures print to stdout: if something goes wrong inside the run (missing authentication, for example), Claude Code prints the failure as the result on stdout. Check the exit code, not just whether the output file exists.
Piping works: stdin is read, so git diff main | clause -p "..." is valid. Piped input is capped at 10 MB.
Structured output is available: --output-format json returns the result plus session metadata, including total_cost_usd. Anthropic notes that this figure is a client-side estimate and can differ from your actual bill.
Step 5: Wrap it in a script
A scheduler runs a command, not your interactive shell. Put the command in a script so you can test it exactly as the scheduler will run it.
Find your claude path first:
command -v claude
Create ~/bin/daily-digest.sh (change the paths to match yours):
#!/usr/bin/env bash set -euo pipefail CLAUDE_BIN="/absolute/path/from/command-v/claude" REPO="$HOME/projects/my-repo" OUT_DIR="$HOME/digests" OUT="$OUT_DIR/$(date +%F).md" mkdir -p "$OUT_DIR" cd "$REPO" "$CLAUDE_BIN" -p "/daily-digest" > "$OUT.tmp" && mv "$OUT.tmp" "$OUT" Make it executable and run it once by hand: chmod +x ~/bin/daily-digest.sh ~/bin/daily-digest.sh cat ~/digests/$(date +%F).md

Two small design choices are worth copying. The script writes to a temporary file and only renames it on success, so a failed run never leaves a half-written or error-filled digest that looks real. And it uses an absolute path to claude, because scheduled jobs often run with a much smaller PATH than your terminal.
Step 6: Schedule it
You have three realistic options. They differ in where the job runs, and that decides which one fits.
Feature | Local cron (or OS scheduler) | Desktop scheduled task | Cloud routine |
Runs on | Your machine | Your machine | Anthropic-managed cloud |
Machine must be on | Yes | Yes | No |
Sees local files | Yes | Yes | No, works on cloned GitHub repos |
Uses ~/.claude/skills/ | Yes | Yes | No. Commit the skill to the repo or enable it on your claude.ai account |
Minimum interval | Whatever the scheduler allows | See Desktop docs | 1 hour |
Best for | Simple, scriptable jobs you control | Local jobs with a UI and no cron | Jobs that should run while your laptop is closed |
Sources for the skill-loading and interval details: Anthropic's skills, routines and Desktop scheduled-tasks documentation.
Option A: cron (macOS, Linux, WSL)
This is the most transparent option. Open your crontab with crontab -e and add:
0 8 * * 1-5 /home/you/bin/daily-digest.sh >> /home/you/digests/cron.log 2>&1
That runs at 08:00 on weekdays and appends any output or errors to a log. Use your real home path, because cron does not expand ~ the way your shell does in every context. On Windows without WSL, use Task Scheduler to run an equivalent script.

Option B: Claude Code Desktop scheduled tasks
If you would rather not touch cron, the Claude Code Desktop app can run Claude on a recurring basis. Because these tasks run locally on your machine, they load your ~/.claude/skills/ folder. See Anthropic's "Schedule recurring tasks in Claude Code Desktop" page for the current setup flow, since the Desktop interface changes more often than the CLI.
Option C: a cloud routine
Routines run on Anthropic's cloud infrastructure, so they keep working when your laptop is closed. They are in research preview, available on Pro, Max, Team and Enterprise plans, and you create them at claude.ai/code/routines or with /schedule in the CLI.
There is one catch for this tutorial. Cloud sessions do not read ~/.claude/skills/ on your machine. If a routine invokes a skill that exists only locally, Claude Code reports it as not found. Two fixes:
Commit the skill to the repo's .claude/skills/daily-digest/ folder, or
Enable the skill on your claude.ai account.
Also note that a routine works on a cloned GitHub repository and pushes to claude/-prefixed branches. It does not write a file to your laptop. A digest routine would need to post somewhere (a connector such as Slack) or open a PR. Routines also have a daily run cap, and connectors you include can be used without per-action approval, so remove any the routine does not need.
Recommendation: for this tutorial, start with cron or a Desktop task. Move to a routine once you want the job to run without your machine on and you have decided where its output should go.
Step 7: Make unattended runs safer
An interactive session asks before risky actions. A scheduled one cannot. Anthropic's headless documentation gives you several controls; use the tightest one that works.
Pre-approve only what the job needs. Our skill needs a git log, and it declares exactly that. For ad-hoc -p calls, --allowedTools "Read,Bash(git log *)" does the same. The space before * matters: Bash(git diff *) is prefix matching, while Bash(git diff*) would also match git diff-index.
Know your starting permission mode. For -p, the built-in starting mode is Manual. Anything not covered by an allow rule or a mode you pass will be denied, since no one is there to answer.
Consider dontAsk for locked-down runs. With --permission-mode dontAsk, anything that would otherwise prompt is denied, while actions covered by your allow rules still run.
Use --permission-prompts none when nobody can answer and you have a permission host in play (such as an SDK app or --permission-prompt-tool). It requires Claude Code v2.1.259 or later; older versions reject the flag.
Use --bare in CI-style environments. It skips auto-discovery of hooks, skills, plugins, MCP servers, auto memory and CLAUDE.md, so the run behaves the same on every machine. Two catches for this tutorial: bare mode does not use your subscription login (it needs ANTHROPIC_API_KEY or an apiKeyHelper), and it will not load your daily-digest skill automatically. Anthropic says --bare is recommended for scripted calls and will become the -p default in a future release, so watch the changelog.
Be careful with untrusted repos. Without --bare, a -p session runs the hooks in a project's .claude/settings.json and connects servers in its .mcp.json, even in a folder you have never trusted, and shows no trust dialog. Only automate against repositories you control.
Avoid --dangerously-skip-permissions for anything you did not design tightly. Several community tutorials use it casually. For a read-only digest it is unnecessary.
Keep a gut safety net. Community guides consistently advise committing often and working on a branch, so a bad automated change is easy to reverse. That matters most once you let a job edit files, for example with --permission-mode acceptEdits.
Check the output, do not trust the exit code alone
Exit code 0 means the run finished without an infrastructure error. It does not prove the digest is good. Anthropic's routines documentation makes the same point about cloud runs: a green status means the session started and exited cleanly, not that the task succeeded.
Community writers add a second warning: Claude sometimes reports a task as complete too early. For jobs that write or change things, add a checking instruction to the skill, for example asking Claude to search for TODO markers, placeholder functions, mock data and skipped tests, then open the result yourself. For the digest, a quick read of the first few outputs is enough. Compare it against git log until you trust it.
Troubleshooting
Problem | Likely cause | Fix |
claude: command not found in cron, but it works in your terminal | Scheduler has a smaller PATH | Use the absolute path from command -v claude in the script |
Output file contains an error message instead of a digest | Failures print on stdout inside -p | Check the exit code; use the temp-file-then-mv pattern from Step 5 |
"Shell command failed for pattern ..." when the skill runs | A ! command failed, for example git log run outside a repo | cd into the repo in the script before calling claude. Any failing injected command aborts the whole skill invocation |
Permission-check error on an injected command | Command is not allowed, and you are not in auto mode | Add it to the skill's allowed-tools, as in Step 3. Deny and ask rules still override allowed-tools |
Skill not found in a scheduled run | Skill lives only in ~/.claude/skills/ and the job runs in the cloud, or the run is bare | For routines, commit the skill to the repo or enable it on claude.ai. Do not use --bare if you rely on auto-discovery |
Authentication failure in -p but interactive works | Credentials or environment differ between shells and schedulers | Confirm claude works from a plain shell, re-run /login if needed, and check whether ANTHROPIC_API_KEY is set. A community bug report shows this pattern on at least one version, so update Claude Code first |
Skill runs but Claude ignores the format | Instructions too loose | Tighten the skill body. Skill content stays in context once loaded, so write instructions as standing rules |
Job hangs after finishing | Claude started a background task or subagent | Anthropic's docs say background Bash shells are terminated about five seconds after the final result. Background subagents keep -p open until they finish, with a 10-minute idle ceiling by default |
When not to automate with Claude Code
The task is fully deterministic. If a plain script can do it (rename files, run a linter), skip the model. Cost and variability buy you nothing.
A wrong answer is expensive. Auto-merging, deploying or deleting on model output without review is a poor first automation. Have it draft or report, and let a human act.
The output must be identical every time. Model output varies. Use structured output (--output-format json with --json-schema) if downstream code depends on the shape, and still validate it.
The inputs are untrusted. Commit messages, issue text and log lines are content Claude reads. Treat instructions embedded in them as data, and keep the job's permissions narrow.
What it costs
Headless runs draw on the same usage as interactive ones. On a subscription that means your plan's limits. On an API-key setup it means metered token spend. Routines add their own daily run cap on top. Check Anthropic's pricing page for current plan prices, because they change.
For a sense of scale, the blogger behind Build to Launch reports rough pay-as-you-go costs from her own projects: a simple website around $2 to $10, data analysis $10 to $25, and larger projects $25 or more, with one niche project ending at $8.62. Those are one writer's experience with interactive building, not official figures, and a short git digest is a much smaller job. Cost scales with how much data your skill injects and how often the job runs. Run it a few times with --output-format json and read total_cost_usd to get your own number, remembering it is an estimate. Inside a session, /usage shows what is driving your limits.
Where to go next
Once the digest works, the same three-part pattern extends naturally:
Add structure: use --output-format json --json-schema '...' to get machine-readable output for a dashboard or Slack post.
Add arguments: skills accept $ARGUMENTS, so one skill can serve /report weekly and /report monthly.
React to events instead of time: hooks fire on Claude Code events, and routines can trigger from GitHub events or an HTTP call.
Go programmatic: the Python and TypeScript Agent SDK packages give you tool-approval callbacks and native message objects when shell scripts stop being enough.
Start small and let it compound. A product manager who documented building a personal assistant with Claude Code (Ron Forbes) describes automating one annoying task, then another, then another, rather than planning a system up front. Copy that pacing: one automation in week one, a second that builds on it in week two. Pick something you already do by hand and put off, not a tutorial exercise. If you use custom commands from older guides (files in .claude/commands/), they still work, but Anthropic has merged commands into skills, so new work belongs in .claude/skills/.
If you would rather avoid the terminal entirely, Claude Desktop also offers a Cowork mode for file-based tasks. It is a different product from the CLI approach in this article, so treat it as an alternative for non-coding work.
The first automation matters less for its own value than for the pattern it teaches: instructions in a skill, a headless call as the trigger, a scheduler as the clock, and permissions scoped to the job.
FAQ
Do I need an API key to run claude -p?
Not necessarily. Non-bare -p runs use your normal Claude Code login. --bare mode is different: it does not read OAuth credentials or the keychain, so it needs ANTHROPIC_API_KEY or an apiKeyHelper.
Can a scheduled Claude Code job edit files?
Yes, if you allow it. Pass --permission-mode acceptEdits for file edits, and add specific --allowedTools entries for shell commands. For a first automation, keep it read-only.
What is the difference between a skill and a hook?
A skill is instructions you or Claude invoke. A hook is a command that fires automatically on a Claude Code event, for example after an edit. For scheduled, prompt-driven work, start with a skill. For "always do X whenever Y happens in a session", look at hooks.