diff --git a/graph/solutions/claude-scheduled-tasks-headless-claude-code-on-systemd-timer-cb5e88.md b/graph/solutions/claude-scheduled-tasks-headless-claude-code-on-systemd-timer-cb5e88.md new file mode 100644 index 00000000000..7888cb4e0af --- /dev/null +++ b/graph/solutions/claude-scheduled-tasks-headless-claude-code-on-systemd-timer-cb5e88.md @@ -0,0 +1,49 @@ +--- +id: cb5e8814-f689-4de0-8854-823358706dec +type: solution +title: "Claude Scheduled Tasks: headless Claude Code on systemd timers" +tags: [claude-scheduled, systemd, automation, headless, claude-code, homelab, solution] +importance: 0.9 +confidence: 0.8 +created: "2026-03-01T06:20:55.075783+00:00" +updated: "2026-03-01T06:20:55.075783+00:00" +--- + +# Claude Scheduled Tasks System + +## Summary +Built a "Claude Cowork"-style scheduled task system using systemd timers and `claude -p` headless mode. Allows fully autonomous Claude Code sessions to run on a schedule without human interaction. + +## Architecture + +- **Universal runner:** `~/.config/claude-scheduled/runner.sh` +- **Per-task config directory:** `~/.config/claude-scheduled/tasks//` + - `prompt.md` — task instructions + - `settings.json` — model, budget, allowed tools + - `mcp.json` — MCP server config for that task +- **Systemd template unit:** `claude-scheduled@.service` +- **Per-task timer files:** `claude-scheduled@.timer` + +## Key invocation flags +``` +claude -p \ + --model sonnet \ + --max-budget-usd 0.75 \ + --output-format json \ + --no-session-persistence \ + --allowedTools \ + --mcp-config \ + --strict-mcp-config \ + --append-system-prompt +``` + +## Critical notes +- Must `unset CLAUDECODE` before invoking `claude -p` inside any shell that may be a Claude session (nested session error otherwise) +- `--permission-mode bypassPermissions` cannot be used as root — run as non-root user +- `--max-budget-usd` is not an instant cutoff — can overshoot (set $0.25, spent $0.37) +- Results stored to cognitive-memory as workflow+episode +- Log rotation: keeps 30 logs per task in `~/.config/claude-scheduled/tasks//logs/` +- Global kill switch: create `~/.config/claude-scheduled/disabled` file to halt all tasks + +## Gitea issue +claude-home#2