{"id":51331622,"url":"https://github.com/ryanlewis/claude-cron","last_synced_at":"2026-07-01T23:04:58.581Z","repository":{"id":338665901,"uuid":"1158652576","full_name":"ryanlewis/claude-cron","owner":"ryanlewis","description":"Run Claude Code on a schedule. Natural language task files, deployed to exe.dev VMs.","archived":false,"fork":false,"pushed_at":"2026-03-04T16:56:56.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-04T23:42:45.186Z","etag":null,"topics":["anthropic","automation","claude","claude-code","cron","exe-dev","scheduled-tasks"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryanlewis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-15T18:02:54.000Z","updated_at":"2026-03-04T17:01:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ryanlewis/claude-cron","commit_stats":null,"previous_names":["ryanlewis/claude-cron"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/ryanlewis/claude-cron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanlewis%2Fclaude-cron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanlewis%2Fclaude-cron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanlewis%2Fclaude-cron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanlewis%2Fclaude-cron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryanlewis","download_url":"https://codeload.github.com/ryanlewis/claude-cron/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanlewis%2Fclaude-cron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35025993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anthropic","automation","claude","claude-code","cron","exe-dev","scheduled-tasks"],"created_at":"2026-07-01T23:04:55.969Z","updated_at":"2026-07-01T23:04:58.575Z","avatar_url":"https://github.com/ryanlewis.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# claude-cron\n\nRun Claude Code on a schedule. Write tasks as markdown files. Push to deploy.\n\nDesigned for quick setup on [exe.dev](https://exe.dev) VMs ($20/mo). Works on any Linux machine — see [Running on Your Own Machine](#running-on-your-own-machine).\n\n## Why\n\nI gave [OpenClaw](https://github.com/openclaw/openclaw) a go — it's a seriously\nimpressive project — but it does a lot more than I needed or wanted. I mostly\njust wanted to summarise things every morning and get it in my inbox (I actually\nget a bunch of summaries sent to a series of Discord channels). I already use\nClaude Code for everything else, so a cron job and a prompt file in a repo felt\na little more appropriate.\n\n## Setup\n\n### 1. Create your repo\n\nClick **\"Use this template\"** on GitHub to create your own copy.\n\n### 2. Create a VM (exe.dev)\n\n```bash\nssh exe.dev new --name=my-cron\n```\n\n### 3. Set up the VM\n\n```bash\n# SSH into your VM\nssh my-cron.exe.xyz\n\n# Install and log into Claude (interactive prompt — do this once)\nclaude\n\n# Clone your repo and run setup\ngit clone https://github.com/YOUR-USERNAME/claude-cron ~/claude-cron\n~/claude-cron/scripts/setup.sh\n```\n\nDone. Your crontab is now managed by Claude.\n\n## Adding a Task\n\nCreate a `.md` file in `tasks/`. Write what you want and when:\n\n```markdown\nRun every weekday at 9am UTC. Max 50 turns, $1 budget. Use haiku.\n\nCheck https://github.com/you/project for open PRs older than 7 days.\nPost a reminder comment on each one. Email me a summary.\n```\n\nThen redeploy on the VM:\n\n```bash\n~/claude-cron/scripts/update.sh\n```\n\nOne file per task. Delete the file to remove the task. You can also set up [CI](#ci-deploy-optional) to deploy automatically on `git push`.\n\n### Frontmatter (optional)\n\nIf you prefer explicit config over prose:\n\n```markdown\n---\nschedule: \"*/30 9-17 * * 1-5\"\nmax-turns: 50\ntimeout: 600\nmodel: claude-haiku-4-5-20251001\n---\n\nCheck CI status for the main branch. If any checks are failing,\nopen an issue with the failure details.\n```\n\n## CI Deploy (Optional)\n\nAuto-deploy on every push to main. Commit a task, push, done.\n\n### 1. Generate a deploy key\n\n```bash\nssh-keygen -t ed25519 -C \"claude-cron-ci\" -f ~/.ssh/claude-cron-ci -N \"\"\n```\n\n### 2. Add it to exe.dev\n\n```bash\ncat ~/.ssh/claude-cron-ci.pub | ssh exe.dev ssh-key add\n```\n\n### 3. Enable the workflow\n\n```bash\ncp .github/workflows/deploy.yml.example .github/workflows/deploy.yml\ngit add .github/workflows/deploy.yml\ngit commit -m \"Enable CI deploy\"\n```\n\n### 4. Set GitHub secrets\n\n```bash\ngh variable set EXE_DEV_HOST --body \"VMNAME.exe.xyz\"\ngh variable set EXE_DEV_USER --body \"exedev\"\ngh secret set EXE_DEV_SSH_KEY \u003c ~/.ssh/claude-cron-ci\n```\n\nReplace `VMNAME` with your VM name from step 2.\n\n### 5. Push\n\n```bash\ngit push\n```\n\nCheck it worked: `gh run list`\n\n## How It Works\n\n- Tasks live in `tasks/*.md` — one file per task\n- On deploy, Claude reads every task file, extracts the schedule and limits, and generates the crontab\n- At runtime, `run-task.sh` pipes the task file to Claude with the right CLI flags\n- Logs go to `data/logs/\u003ctask\u003e/`, rotated to the last 50 runs\n- Failed tasks send an email via exe.dev's built-in gateway\n\n## Running on Your Own Machine\n\nThe core system is just cron + the Claude CLI — it works anywhere Linux runs. A few pieces are wired to exe.dev's infrastructure and need adapting if you're running elsewhere:\n\n- **Failure alert email** (`scripts/run-task.sh`) — On failure, the task runner sends an alert via exe.dev's metadata gateway (`curl 169.254.169.254/gateway/email/send`). Replace the curl block with `sendmail`, an SMTP call, or remove it if you don't need failure alerts.\n- **`/send-email` skill** (`.claude/skills/send-email/`) — Tasks that send email use this skill, which wraps the same gateway. Rewrite it for your mail setup or delete it if your tasks don't send email.\n- **Email config in `CLAUDE.md`** — The `Email` section documents the gateway endpoint and inbound mail (`~/Maildir`). Update or remove it to match your environment.\n- **CI workflow** (`.github/workflows/deploy.yml.example`) — Uses `EXE_DEV_*` secrets to SSH into the VM and redeploy. Rename the variables and update the SSH target to point at your machine.\n\nEverything else — task files, the `/deploy` skill, `run-task.sh`, log rotation, `setup.sh` — is portable as-is.\n\n## Usage \u0026 Terms\n\nThis project uses the official Claude Code CLI in headless mode (`-p`), a documented and supported feature. It's just cron + the real CLI.\n\nA few things to be aware of:\n\n- **Pro/Max subscriptions:** Scheduled tasks count against the same rolling usage window as interactive Claude Code and claude.ai. Use the safeguards available — `timeout`, model choice, scheduling frequency — to limit execution.\n- **API keys:** Usage is billed per-token at standard API rates. No rolling windows — the better option for high-volume or mission-critical automation.\n- **Reliability:** Tasks depend on external sites and LLM output. They may fail or produce incorrect results — don't rely on this for anything critical.\n- **Terms:** Anthropic's [Consumer Terms of Service](https://www.anthropic.com/legal/consumer-terms) govern subscription usage. This project is a scheduling wrapper — you're responsible for ensuring your usage complies with their terms.\n\n## Extending\n\nYou can give your tasks extra capabilities with skills, MCP servers, and plugins. These let Claude interact with external services, follow custom workflows, or use specialised tools.\n\n### Skills\n\nSkills are prompt files that teach Claude reusable workflows. claude-cron ships with three built-in skills:\n\n| Skill | What it does |\n|-------|-------------|\n| `/deploy` | Reads task files, generates and installs the crontab |\n| `/send-email` | Sends an email via exe.dev's gateway |\n| `/list-tasks` | Shows all tasks with schedules and recent run status |\n\nAdd your own by creating a `SKILL.md` in `.claude/skills/your-skill/`:\n\n```markdown\n---\nname: your-skill\ndescription: \"What this skill does\"\n---\n\nInstructions for Claude to follow when this skill is invoked.\n```\n\n### MCP Servers\n\nMCP servers give your tasks access to external services like GitHub, Slack, etc.\n\nRun these commands **on the VM, from `~/claude-cron`**. Secrets are stored in `~/.claude.json` on the VM — never in the repo.\n\n**GitHub (remote):**\n\n```bash\ncd ~/claude-cron\nclaude mcp add --transport http github https://api.githubcopilot.com/mcp/ \\\n  --header \"Authorization: Bearer YOUR_GITHUB_PAT\"\n```\n\nCreate a [Personal Access Token](https://github.com/settings/tokens) with the scopes your tasks need.\n\n**Any HTTP MCP server:**\n\n```bash\ncd ~/claude-cron\nclaude mcp add --transport http NAME URL \\\n  --header \"Authorization: Bearer YOUR_TOKEN\"\n```\n\n**Verify:** `claude mcp list`\n\nThen just mention the service in your task prompt — Claude will use the MCP server automatically.\n\n### Plugins\n\nAny Claude Code plugins you've installed are available to your tasks automatically.\n\nFor example, the official [code-review](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-review) plugin gives your tasks access to `/code-review`. A task could use it like:\n\n```markdown\nRun every hour during working hours. Max 50 turns.\n\nCheck https://github.com/you/project for open PRs that haven't been reviewed.\nRun /code-review on each one.\n```\n\n## Repo Structure\n\n```\nclaude-cron/\n  .claude/skills/\n    deploy/SKILL.md\n    send-email/SKILL.md\n    list-tasks/SKILL.md\n  .github/workflows/\n    deploy.yml.example\n  scripts/\n    run-task.sh\n    setup.sh\n    update.sh\n  tasks/\n    your-tasks-here.md\n  CLAUDE.md\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanlewis%2Fclaude-cron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryanlewis%2Fclaude-cron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanlewis%2Fclaude-cron/lists"}