Skip to content

How to Build a 24/7 AI Agent Automation Workflow

I wanted my AI agents to work while I sleep. But every time I closed my laptop, my Claude Code sessions died. My automation dreams were just dreams.

Then I saw someone on Reddit running OpenClaw on a VPS 24/7. Another person bought a Mac mini just for agents. That’s when it clicked - I needed dedicated infrastructure.

The Problem

My AI agents kept stopping:

  • Laptop goes to sleep → agents stop
  • Network drops → agents fail
  • Manual triggers only → no automation
  • No error recovery → silent failures

I needed agents that run continuously, check for work automatically, and recover from errors. Let me show you how I built it.

Infrastructure: Where to Run 24/7 Agents

You have three options:

┌─────────────────────────────────────────────────────────┐
│ Choose Your Platform │
├──────────────────┬──────────────────┬──────────────────┤
│ VPS │ Mac Mini │ Local Server │
│ (Cloud, Cheap) │ (macOS Tools) │ (Full Control) │
├──────────────────┼──────────────────┼──────────────────┤
│ $5-20/month │ $600+ upfront │ Free + power │
│ Any OS │ macOS only │ Your hardware │
│ SSH access │ GUI apps work │ Network config │
└──────────────────┴──────────────────┴──────────────────┘

I started with a VPS. It’s cheap and easy. But some tools need macOS, so I eventually added a Mac mini.

VPS Setup (Ubuntu example):

setup-vps.sh
# Update system
sudo apt update && sudo apt upgrade -y
# Install Node.js (for Claude Code)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# Install Claude CLI
npm install -g @anthropic-ai/claude-code
# Create agent user (security!)
sudo useradd -m -s /bin/bash agent
sudo -u agent -i

Mac Mini Setup:

setup-mac.sh
# Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Claude CLI
brew install node
npm install -g @anthropic-ai/claude-code
# Prevent sleep (important!)
sudo pmset -a disablesleep 1

Scheduling: Making Agents Run Themselves

Now the key part: automation. I use cron jobs (Linux) or launchd (macOS).

Cron Jobs (Linux/VPS)

Cron is the classic scheduler. It runs commands at specific times.

edit-crontab.sh
# Edit crontab
crontab -e
crontab-entries.txt
# Morning brief at 7 AM every day
0 7 * * * /home/agent/scripts/morning-brief.sh >> /var/log/agents/brief.log 2>&1
# Check for new work every 30 minutes
*/30 * * * * /home/agent/scripts/poll-work.sh >> /var/log/agents/poll.log 2>&1
# Weekly review on Sunday at 6 PM
0 18 * * 0 /home/agent/scripts/weekly-review.sh >> /var/log/agents/review.log 2>&1

At first, I made a mistake - I didn’t redirect output to logs. Agents failed silently and I had no idea why. Always log everything.

launchd (macOS)

macOS uses launchd instead of cron:

com.agent.morningbrief.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.agent.morningbrief</string>
<key>ProgramArguments</key>
<array>
<string>/Users/agent/scripts/morning-brief.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>7</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/tmp/agent-brief.log</string>
<key>StandardErrorPath</key>
<string>/tmp/agent-brief-error.log</string>
</dict>
</plist>
load-launchd.sh
# Load the agent
launchctl load ~/Library/LaunchAgents/com.agent.morningbrief.plist

Agent Architecture: Three Patterns

I discovered three patterns for building agents:

┌─────────────────────────────────────────────────────────┐
│ Agent Patterns │
├──────────────────┬──────────────────┬──────────────────┤
│ Polling │ Event-Driven │ Scheduled │
├──────────────────┼──────────────────┼──────────────────┤
│ Check every X │ React to trigger │ Run at time Y │
│ │ │ │
│ ┌─────┐ │ ┌─────┐ │ ┌─────┐ │
│ │Timer│ │ │Event│ │ │Clock│ │
│ └──┬──┘ │ └──┬──┘ │ └──┬──┘ │
│ │ │ │ │ │ │
│ v │ v │ v │
│ ┌─────┐ │ ┌─────┐ │ ┌─────┐ │
│ │Check│ │ │React│ │ │ Run │ │
│ └─────┘ │ └─────┘ │ └─────┘ │
│ │ │ │
│ Every 30 mins │ Webhook/API │ Daily 7 AM │
│ Check for tasks │ File system │ Weekly report │
└──────────────────┴──────────────────┴──────────────────┘

Pattern 1: Polling Agent

Checks for new work at regular intervals. Simple and reliable.

poll-work.sh
#!/bin/bash
# Set working directory
cd /home/agent/workspace
# Check if there's new work
WORK_FILE="/home/agent/data/work-queue.json"
if [ -f "$WORK_FILE" ]; then
# Run Claude with the work
claude --file "$WORK_FILE" --output "/home/agent/output/result-$(date +%Y%m%d%H%M%S).md"
# Archive processed work
mv "$WORK_FILE" "/home/agent/archive/work-$(date +%Y%m%d%H%M%S).json"
echo "$(date): Processed work queue"
else
echo "$(date): No work found"
fi

Pattern 2: Event-Driven Agent

Reacts to triggers like file changes or webhooks.

file-watcher.sh
#!/bin/bash
# Uses inotifywait to watch for file changes
inotifywait -m -r -e create,moved_to /home/agent/inbox |
while read dir action file; do
echo "$(date): New file detected - $file"
claude --file "$dir$file" --output "/home/agent/output/"
done

Pattern 3: Scheduled Agent

Runs at specific times for regular tasks.

morning-brief.sh
#!/bin/bash
# Morning brief at 7 AM
# Pulls calendar, emails, tasks and generates summary
claude --prompt "Generate morning brief:
1. Check calendar for today's meetings
2. Summarize overnight emails
3. List top 3 priorities
Output as markdown." \
--output "/home/agent/briefs/$(date +%Y-%m-%d).md"
echo "$(date): Morning brief generated"

Common Mistakes I Made

Mistake 1: No Error Handling

My first agents failed silently. I had no idea until I checked logs days later.

agent-with-handling.sh
#!/bin/bash
set -e # Exit on error
LOG_FILE="/var/log/agents/agent.log"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
# Trap errors
trap 'log "ERROR: Agent failed at line $LINENO"' ERR
log "Starting agent run"
if ! claude --file "/home/agent/work.json" --output "/home/agent/out.md"; then
log "ERROR: Claude execution failed"
exit 1
fi
log "Agent completed successfully"

Mistake 2: Over-Scheduling

I ran 10 agents every 5 minutes. Hit API rate limits immediately.

┌──────────────────────────────────────────────────────┐
│ Scheduling Mistakes to Avoid │
├────────────────────────────────────────────────────┤
│ ❌ 10 agents x every 5 mins = 120 calls/hour │
│ → API rate limit hit! │
│ │
│ ✅ 3 agents x every 30 mins = 6 calls/hour │
│ → Comfortable margin │
└────────────────────────────────────────────────────┘

Start with longer intervals. You can always increase frequency later.

Mistake 3: No Persistent State

Agents forgot what they did last run. They processed the same work twice.

agent-state.json
{
"last_run": "2026-03-28T07:00:00Z",
"last_processed_id": "task-12345",
"processed_count": 42,
"errors": []
}
stateful-agent.sh
#!/bin/bash
STATE_FILE="/home/agent/data/state.json"
WORK_FILE="/home/agent/data/work.json"
# Load state
if [ -f "$STATE_FILE" ]; then
LAST_ID=$(jq -r '.last_processed_id' "$STATE_FILE")
else
LAST_ID="none"
fi
# Process only new work
jq --arg last "$LAST_ID" '.[] | select(.id > $last)' "$WORK_FILE" | \
while read -r task; do
claude --input "$task"
done
# Save state
echo "{\"last_processed_id\": \"$(date +%s)\"}" > "$STATE_FILE"

Mistake 4: Running as Root

I ran agents as root. Big security mistake. One bug could delete the entire system.

secure-setup.sh
# Create dedicated user
sudo useradd -m -s /bin/bash agent
# Limit permissions
sudo mkdir -p /home/agent/{workspace,logs,data}
sudo chown -R agent:agent /home/agent
# Run as non-root
sudo -u agent crontab -e

Real Examples from the Community

People are running impressive automations:

  1. Morning Brief Agent - Runs at 7 AM daily, checks calendar, summarizes emails, lists priorities
  2. Calendar Watcher - Monitors for meetings, pings 15 minutes before each one
  3. Weekly Review - Collects completed tasks every Sunday, generates progress report
  4. Code Review Bot - Watches GitHub repos, reviews PRs automatically
  5. Agent Army - Multiple specialized agents, each handling a domain (finance, health, learning)
┌─────────────────────────────────────────────────────────┐
│ My Agent Setup │
├─────────────────────────────────────────────────────────┤
│ │
│ VPS (Ubuntu) │
│ ├── Morning Brief (7:00 AM daily) │
│ ├── Task Poller (every 30 min) │
│ └── Weekly Review (Sunday 6 PM) │
│ │
│ Mac Mini │
│ ├── Calendar Watcher (every 15 min) │
│ ├── Email Summarizer (every 2 hours) │
│ └── Dev Helper (on file change) │
│ │
└─────────────────────────────────────────────────────────┘

Starting Simple: Your First 24/7 Agent

Don’t build everything at once. Start with one triggered workflow:

first-agent.sh
#!/bin/bash
# Your first 24/7 agent - a simple file processor
INPUT_DIR="/home/agent/input"
OUTPUT_DIR="/home/agent/output"
LOG_FILE="/home/agent/logs/agent.log"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
for file in "$INPUT_DIR"/*.md; do
if [ -f "$file" ]; then
log "Processing: $file"
if claude --file "$file" --output "$OUTPUT_DIR/"; then
mv "$file" "/home/agent/processed/"
log "Success: $file"
else
log "Failed: $file"
fi
fi
done

Add to cron:

add-to-cron.sh
# Run every 30 minutes
*/30 * * * * /home/agent/scripts/first-agent.sh

Test it manually first:

test-agent.sh
# Run once to test
/home/agent/scripts/first-agent.sh
# Check logs
tail -f /home/agent/logs/agent.log

Once that works reliably, add more agents. Build incrementally.

Key Takeaways

  1. Choose infrastructure wisely - VPS for cheap cloud, Mac mini for macOS tools, local server for control
  2. Use reliable schedulers - cron (Linux) or launchd (macOS) are battle-tested
  3. Pick the right pattern - Polling for regular checks, event-driven for triggers, scheduled for fixed times
  4. Handle errors - Log everything, track state, recover from failures
  5. Start small - One agent, test thoroughly, then expand
  6. Mind security - Never run as root, use dedicated users, limit permissions

The shift from “I have to manually run my agents” to “my agents work while I sleep” changed everything. Now I wake up to completed work, morning briefs, and clean code reviews - all done automatically.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments