Deep dive · Jump here anytime when you want more on this idea
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
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.
What good looks like
When this breaks
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.