Guide · updated November 5, 2026
How to run Claude Code agents in the background on a Mac
Run claude -p (print mode) from a script or a LaunchAgent, give each run a session id so the next run can --resume it, limit what it may do with --permission-mode and --allowedTools, and stop the Mac from sleeping while it works.
1. Run Claude Code headless
Print mode runs one prompt to completion and exits, with no interactive terminal:
claude -p "Fix the failing test in src/totals.test.ts, then run npm test" \ --output-format stream-json --verbose
--output-format stream-json prints one JSON event per line (messages, tool calls, the final result) as they happen, so another program can show progress or save a transcript. It only works together with -p.
2. Keep context between runs
Each -p run is a separate conversation unless you tell it otherwise. Start the first run with a session id you choose, and resume it on later runs:
ID=$(uuidgen | tr A-Z a-z) claude -p "Start on the backlog in TODO.md" --session-id "$ID" --output-format stream-json --verbose # later, after it finishes: claude -p "Continue with the next item" --resume "$ID" --output-format stream-json --verbose
We start a new session each morning and resume it for every run that day. One long session per day keeps the agent's context without carrying a week of history.
3. Give it standing instructions
Put the agent's role and your rules in a file and append it to the system prompt on every run:
claude -p "…" --append-system-prompt-file ./agent-rules.md
Concrete rules work best: "never push to main", "drafts only, never send email", "run npm test before saying done".
4. Decide what it may do without asking
An unattended run can't answer permission prompts, so anything that needs approval is refused. Two ways to set this up:
- Allow-list (what we recommend):
--permission-mode acceptEdits --allowedTools "Bash(npm test:*),Bash(git status:*),Bash(git diff:*)". The agent can edit files and run exactly those commands. - Skip all checks:
--dangerously-skip-permissionslets it run anything your user account can. Only use it in a sandbox or with rules you trust completely.
5. Start it on a schedule with launchd
On macOS a LaunchAgent can start your runner script at login (RunAtLoad), at a time (StartCalendarInterval), and restart it if it crashes (KeepAlive). Save it in ~/Library/LaunchAgents/, then:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.agents.plist
Give it a full PATH in EnvironmentVariables: launchd doesn't read your shell profile, so a claude or node installed in your home folder won't be found otherwise.
6. Keep the Mac awake
A sleeping Mac pauses every agent. While a batch runs, caffeinate -i prevents idle sleep:
caffeinate -i ./run-agents.sh
For a Mac that works all day, set it not to sleep on power in System Settings › Battery (or Energy), or with sudo pmset -c sleep 0. The display can still turn off.
Where Elco Console fits
Elco Console is this setup, packaged: it runs each agent with exactly these flags, gives every agent a daily session, applies your rules and an allow-list by default, schedules runs inside your workday with a daily cap, and its npm run init -- --launchagent writes the LaunchAgent for you.