claudeclaw + cron — Claude as an assistant with its own schedule
Claude Code can work even when I'm not driving. claudeclaw is the mechanism that schedules tasks for it — daily briefings, PR reviews, dependency audits. Showing how it works on my setup.

The default Claude Code model is "I sit down, I ask, the agent answers." claudeclaw inverts that: the agent has its own calendar and pings me when it has something to say. I run four active cron jobs and a few one-shots, here's what it looks like and what I learned.
What is claudeclaw
A Claude Code plugin that adds:
- a daemon holding state across sessions
- a way to define jobs (cron expression + prompt + delivery)
- Telegram integration for two-way comms
- a heartbeat that confirms the daemon is alive
My config repository:
~/.openclaw/cron/
├── jobs.json # job definitions
└── runs/
├── morning.jsonl # run log
└── ...Each job is a JSON object:
{
"id": "morning-briefing",
"name": "Morning briefing",
"agentId": "main",
"enabled": true,
"schedule": { "kind": "cron", "expr": "0 8 * * *", "tz": "Europe/Warsaw" },
"payload": {
"kind": "agentTurn",
"message": "Check weather, today's calendar, backup status, latest emails (top 5). Short summary.",
"lightContext": true
},
"delivery": { "mode": "announce", "channel": "telegram", "to": "5094102576" }
}Job 1: morning briefing
Daily, 8 AM. The agent checks:
- weather via Home Assistant (outdoor sensor)
- Google Calendar (today's events)
- backup status (Proxmox)
- top 5 unread emails
Output goes to Telegram as a single ~150-word message. No filters, no parsing, the model decides what's relevant.
🌅 Good morning. 8°C, foggy until 11.
📅 Today: 14:00 meeting #1, 17:00 workout.
💾 VM backup proxmox: ✅ at 03:00.
📧 3 emails worth attention: invoice X (deadline tomorrow), ...This replaces the "open four apps in the morning" ritual. Running for 4 months, reliably.
Job 2: post-merge code review
A GitHub webhook fires the job with a PR number. The agent:
- fetches the diff
- reads the project's CLAUDE.md (style context)
- runs the
code-reviewersubagent - sends the result to Telegram
{
"id": "post-merge-review",
"schedule": { "kind": "trigger", "via": "webhook" },
"payload": {
"kind": "agentTurn",
"message": "Code review on PR ${PR_NUMBER} in ${REPO}. Focus on: consistency with existing style, security, no silent failures."
}
}It doesn't replace "real" review (the bot has no intent context), but it catches 1-2 nits per PR. On average.
Job 3: dependency audit
Weekly, Sunday 22:00. The agent does:
# Pseudocode for what it runs
for project in ~/projects/*; do
cd "$project"
npm audit --json
pip-audit
doneOutput: an aggregate of HIGH/CRITICAL CVEs, sorted by project. If zero, short "all clear" message. If something, list with links.
Often it's a false positive (a CVE'd package only in devDeps). But sometimes it catches a real issue before I notice. Worth it.
Job 4: backup status
Daily, 6 AM. Checks:
- whether the Proxmox VM snapshot ran
- whether obsidian-livesync (CouchDB) is current
- whether the GitHub mirror works
Output is sent only when something is wrong. Key detail: silence means "all ok". I do not want 365 "backup OK" pings per year.
What I learned
1. Light context as the default. Each job starts a fresh session with no history. Simplifies debugging (each run is deterministic) and lowers cost. Full context only for things that genuinely need it (e.g. continuation).
2. Telegram > email for alerts. Email gets 200 a day, Telegram from a bot gets only from a bot. If something shows up there, I read it.
3. Cron expression isn't everything. I also have trigger-based jobs (GitHub webhook, callback from systemd). claudeclaw handles both. I use trigger more than cron.
4. Failover to Telegram. Every job notifies on failure. Not silent death, but "job X failed, log at Y." Earlier I had jobs that hadn't run for a month and I didn't know.
Anti-patterns
Three things I tried early and dropped:
1. "Smart" intervals. "Run the job when CPU < 30%." The agent handles models, not scheduling. Leave that to systemd timers.
2. One job, many responsibilities. I had "monitoring-everything" running 8 minutes. Split into 5 smaller ones, each < 90 seconds. Easier to debug, each has a clear owner.
3. Memory between runs. I tried passing state via a file. Ended with the agent reading it inconsistently. Now every run is stateless; if I need continuity, I use a db (sqlite) explicitly.
Minimum setup
If you want to try, the smallest sensible setup:
# 1. Install the plugin
claude plugin install claudeclaw
# 2. Create your first job (morning ping)
claude jobs create \
--name "morning-ping" \
--cron "0 8 * * *" \
--message "Say good morning. Check if I have anything in the calendar today."
# 3. Status
claude jobs listThe first job works after one night. Once it becomes a habit, add more.
claudeclaw isn't sci-fi or an autonomous agent. It's plain cron with a wrapper that talks to me in plain language. That's enough for the agent to be useful while I sleep.