Skip to content
Agentic Levels

Everything starts here.

GuestLocal progress only
PreferencesSign in
01Start with one taskBest first move for beginners.02Check your LevelMeasure where you are.03Score an AI resultFind the habit to practice first.04Return to Your WorkScores, links, and checkpoints.
Start here

Begin

HomeThe main entry point.New to AIStart with one useful task.
Know where you are

Measure

Check your LevelUse this after you have tried AI.Fluency ScoreScore an AI result you can review.
Build the habit

Learn

LevelsLessonsTracks
Find the reference

Library

PromptsReferenceResourcesCompare Tools
Turn it into work

Apply

Your Next MoveChoose what AI should change next.Tool SetupGet the tools ready.
Come back later

Return

Your WorkScores, links, and checkpoints.My PathContinue from your level.Updates
Site

Site

PricingAboutFAQ & FeedbackPreferences

© 2026 Fuentes Studio

Privacy·Terms
yourCouncil
Ready to help
✦

What do you want to understand?

Ask anything about what you're learning.

← Back
L9Free

Deep dive · Jump here anytime when you want more on this idea

Running an AI agent on a schedule

LaunchAgents keep your pipeline running while you are not watching

After this, you'll be able to set up a background AI agent on macOS using a LaunchAgent plist that runs on a schedule, completes a task, and writes its output to a file you can check.

Before you start

Complete Harness Engineering first; this lesson builds on hooks and scheduled execution patterns for AI agents.

The idea

A background agent is an AI-powered script that runs on a schedule, does its task, and exits. You don't watch it run. You check the output afterward. On macOS, LaunchAgents are the built-in system for scheduling background processes: a plist file in your ~/Library/LaunchAgents/ folder tells macOS when to run your script, how to restart it if it crashes, and where to send its output. The agent itself is a shell or Python script that calls the Claude CLI with the --print flag (claude -p), which runs non-interactively and exits after printing the output, rather than opening an interactive chat session. The script writes results to a log file.

Here is the before and after: without a background agent, you run your morning briefing script manually when you remember, which is about half of mornings. With a LaunchAgent plist, the script runs at 7:05 AM every day, calls Claude with a prompt that summarizes your pending tasks, and writes the output to ~/briefings/today.md; ready when you sit down.

Now try it: write a LaunchAgent plist that runs a one-line shell script on a schedule, where the script calls the Claude CLI and writes the output to a file. Load it with launchctl load and confirm it runs at the scheduled time. The three files you need are the plist, the script, and the output file.

Try it (15 min)

Watch out for

  • Assuming your API keys are available inside a LaunchAgent; they are not. The LaunchAgent environment has no shell, so authentication fails silently unless you set every credential in the plist EnvironmentVariables block.
  • Not setting StandardErrorPath in the plist; without it, errors disappear silently and you have no way to debug a failing agent
  • Setting a run interval so short that a new run starts before the previous one finishes; use a minimum of 5 minutes for any agent that calls an LLM
  • Testing with launchctl start before testing the script directly in a terminal; always confirm the script works standalone first

Paste this into Claude

I want to set up a background AI agent on macOS that [describe the task: what the agent should do, what data it reads, what output it produces]. It should run [describe the schedule: daily at a specific time, every N minutes, or on login]. The agent output should be written to [describe the output location: a specific log file or folder]. Please give me: 1) the complete shell or Python script that calls the Claude CLI and writes output to the file, 2) the complete LaunchAgent plist file with the correct StartCalendarInterval or StartInterval entry, 3) the exact launchctl commands to load the plist and verify it is registered, and 4) how to view the stderr log if the agent fails to run. Include StandardErrorPath and StandardOutPath in the plist so errors are always captured.

Created by potrace 1.16, written by Peter Selinger 2001-2019 What good looks like

  • The plist file is valid XML and loads without error using launchctl load
  • Running launchctl list | grep your-label shows an entry; after the first scheduled run, the exit status column shows 0
  • After the scheduled time passes, the output file exists and contains the expected content from the Claude call
  • The stderr log path was set in the plist and captures any error output from the last run

When this breaks

  • Breaks when the plist does not include the full path to the interpreter (e.g., /usr/bin/python3 rather than python3) because the LaunchAgent environment has a minimal PATH that does not include your shell's PATH
  • Breaks when API credentials are not set in the plist EnvironmentVariables block because the script inherits no shell environment and authentication fails silently

Created by potrace 1.16, written by Peter Selinger 2001-2019 You can now

✓

Check launchctl list for your agent's label, open the output file, and confirm it contains content from a run that happened after the scheduled time with no errors in the stderr log.

Key takeaways

A LaunchAgent is a three-file system: the plist that schedules it, the script that does the work, and the output file you check. Get all three right and the agent runs without you.

  1. 1Background agents run on a schedule and exit; you check the output file, you do not watch the run
  2. 2LaunchAgent plists go in ~/Library/LaunchAgents/ and are loaded with launchctl load
  3. 3Set the full interpreter path and any API keys in the plist EnvironmentVariables; the LaunchAgent environment has no shell
  4. 4StandardErrorPath is not optional; it is how you debug an agent that silently stopped working

Was this helpful?

← Back to lessons