Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
Mae avatar

Cron

  • 1 repo stars
  • Updated July 25, 2026
  • cadrianmae/claude-marketplace

Schedule notifications and reminders with crontab(5) syntax, anacron-style catch-up, per-tick dedup, and global or per-project schedules inside Claude Code.

About

Cron provides hook-based scheduled notifications using familiar crontab(5) syntax with anacron-style catch-up and per-tick deduplication so missed ticks still fire once. It supports both global and per-project schedules with add or replace modes through a single unified interactive command. It depends on python3 and jq being available.

  • crontab(5) scheduling syntax
  • Anacron-style catch-up with per-tick dedup
  • Global and per-project schedules
  • Unified interactive /cron command
  • Requires python3 and jq

Cron by the numbers

  • Data as of Jul 26, 2026 (Skillselion catalog sync)
/plugin marketplace add cadrianmae/claude-marketplace
/plugin install cron@cadrianmae-claude-marketplace

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
repo stars1
Last updatedJuly 25, 2026
Repositorycadrianmae/claude-marketplace

What it does

Schedule notifications and reminders with crontab(5) syntax, anacron-style catch-up, per-tick dedup, and global or per-project schedules inside Claude Code.

README.md

Cron Plugin

Hook-based scheduled notification system for recurring reminders in Claude Code.

Overview

Provides passive, time-based notifications that appear in your Claude Code conversation when scheduled times arrive.

Key Features:

  • Full crontab(5) syntax for schedules (5 fields, ranges, lists, steps, named months/days)
  • Dynamic notification text via shell commands (date, git, curl, etc.)
  • Anacron-style catch-up by default — missed ticks fire on the next prompt; toggleable per schedule
  • Per-tick deduplication — each matching tick fires exactly once
  • Global and per-project schedules with add/replace modes
  • Legacy time+days form still supported

Cron Syntax

Standard 5-field crontab(5):

MIN  HOUR  DOM  MONTH  DOW
0-59 0-23  1-31 1-12   0-7  (0 or 7 = Sunday)

Operators: *, a-b, a,b, */n, a-b/n. Named months (jan-dec) and days (sun-sat).

OR rule: if both day-of-month and day-of-week are restricted (neither is *), the match is OR — same as crond. E.g. 0 9 1,15 * 5 fires on the 1st, the 15th, and every Friday at 9:00.

Quick examples

# Hourly chime with live timestamp
/cron --command "date '+Chime: %H:%M %A'" --cron "0 * * * *" global

# Every 15 minutes during work hours, weekdays
/cron "Stretch break" --cron "*/15 9-17 * * 1-5" global

# Standup at 9:00 weekdays, no catchup (only fires if active in that minute)
/cron "Standup time!" --cron "0 9 * * 1-5" --catchup false global

catchup

Value Behavior
true (default) Anacron-style. If a tick was missed (no prompt during that minute), the next prompt still fires it once.
false Strict cron. Only fires if the matching tick is in the current wall-clock minute. Missed ticks are lost.

message vs command

  • message — static text (positional argument).
  • --command — shell command run via bash -c; stdout becomes the notification text. Lets the message change every time it fires.

Mutually exclusive. Commands run with your shell privileges; treat ~/.claude/schedules.json as trusted (same as ~/.bashrc).

sound

Optional per-schedule audio cue. Non-blocking — the player is detached from the hook so Claude never waits on playback.

Value Behavior
absent / false Silent (default).
true Plays the bundled default (sounds/ding.wav). Override with top-level "defaultSound" in schedules.json.
"ding" / "chime" / "beep" / "pop" Short name — resolves to one of the bundled stereo WAVs shipped with the plugin.
"/path/to/file" Plays a custom audio file. Any format your player supports.

Bundled sounds (in sounds/, stereo 32 kHz WAV):

Name Description
ding Warm bell with inharmonic partials and reverb tail
chime Sustained B major chord (B4/D#5/F#5/B5) with FM shimmer
beep Soft dual-tone UI blip (880 Hz + octave)
pop Short high-pitched sweep with reverb

Portable player detection (first match wins): paplayaplayafplayffplayplay. If none are installed, the schedule still fires notifications silently.

Example:

{
  "defaultSound": "ding",
  "schedules": [
    { "id": "standup", "cron": "0 9 * * 1-5", "message": "Standup!", "sound": true },
    { "id": "deploy",  "cron": "0 16 * * 5",  "message": "Deploy window", "sound": "/home/me/sounds/airhorn.wav" }
  ]
}

Installation

This plugin is available in the cadrianmae-claude-marketplace. Enable it through your Claude Code plugin settings.

Dependencies:

  • jq - JSON processor (sudo dnf install jq on Fedora)
  • python3 - cron expression evaluator (preinstalled on Fedora)

Verify installation:

/cron

Configuration

Global Schedules

Global schedules apply to all projects and directories. Managed user-wide.

Create global schedule:

/cron "Morning standup" --time 09:00 --days weekdays global

File location: ~/.claude/schedules.json

Format:

[
  {
    "id": "morning-standup",
    "time": "09:00",
    "message": "Morning standup time!",
    "days": ["Mon", "Tue", "Wed", "Thu", "Fri"],
    "enabled": true
  }
]

Per-Project Schedules

Project schedules apply only within specific projects. Useful for project-specific reminders like deployment windows or sprint reviews.

Create project schedule:

/cron "Deploy window" --time 16:00 --days Mon,Wed,Fri

File location: .claude/schedules.json (in project root)

Format:

{
  "mode": "add",
  "schedules": [
    {
      "id": "deploy-window",
      "time": "16:00",
      "message": "Daily deployment window",
      "days": ["Mon", "Wed", "Fri"],
      "enabled": true
    }
  ]
}

Project Modes

Mode: "add" (default)

  • Merges project schedules with global schedules
  • Both global and project notifications appear

Mode: "replace"

  • Uses only project schedules
  • Ignores global schedules
  • Useful for focused work sessions (e.g., pomodoro mode)

Usage

Add Schedule

Interactive mode:

/cron

Claude prompts for message, time, days, and scope.

All-in-one mode:

# Weekday standup
/cron "Standup time!" --time 09:00 --days weekdays

# Global afternoon break
/cron "Take a break" --time 15:00 --days weekdays global

# Weekend reminder
/cron "Weekend planning" --time 10:00 --days weekends

# Specific days
/cron "Deploy day" --time 16:00 --days Mon,Wed,Fri

# Daily reminder
/cron "End of day review" --time 17:00 --days daily

Special day values:

  • weekdays → Mon,Tue,Wed,Thu,Fri
  • weekends → Sat,Sun
  • daily → Every day (*)

List Schedules

/cron              # Show all (global + project)
/cron global       # Global only
/cron project      # Project only

Disable / Enable / Remove

Run /cron and pick the action. The skill lists existing schedules so you can pick one by id. disable keeps the entry (so it can be re-enabled later); remove deletes it.

How It Works

The plugin uses a UserPromptSubmit hook that runs every time you send a message to Claude:

  1. For each schedule, computes the most recent matching minute (the "tick") using the cron expression
  2. Compares it against the last tick that was already fired (stored in the state file)
  3. Fires the notification if this tick is newer — including ticks missed while you were away (anacron-style catch-up), unless catchup is set to false
  4. Records the fired tick so the same tick is never shown twice

Passive notifications: Reminders appear on your next prompt after the scheduled tick, not immediately.

Deduplication: Per-tick, not time-windowed. A given matching minute fires exactly once; subsequent prompts in the same minute (or any time before the next matching tick) produce nothing.

State Management

State files track last-shown timestamps:

  • Global: ~/.claude/.schedule-state.json
  • Project: .claude/.schedule-state.json

Auto-created and managed by hook. Can be manually reset by deleting them.

Examples

Daily Standup

/cron "Daily standup in 5 minutes" --time 08:55 --days weekdays global

Lunch Break

/cron "Time for lunch break!" --time 12:30 --days daily global

Code Review Friday

/cron "Friday code review session" --time 14:00 --days Fri

Pomodoro (Project-Specific)

{
  "mode": "replace",
  "schedules": [
    {
      "id": "work-block",
      "time": "09:00",
      "message": "Start 25-minute work block",
      "days": ["*"],
      "enabled": true
    },
    {
      "id": "break-time",
      "time": "09:25",
      "message": "5-minute break",
      "days": ["*"],
      "enabled": true
    }
  ]
}

Troubleshooting

No notifications appear

  1. Check time format is HH:MM (24-hour)
  2. Verify day abbreviations: Mon, Tue, Wed, Thu, Fri, Sat, Sun
  3. Check enabled: true in configuration
  4. Validate JSON: jq . ~/.claude/schedules.json
  5. Wait 60+ seconds after last notification

Notifications spam every prompt

  • Check state files exist and are writable:
    • ~/.claude/.schedule-state.json
    • .claude/.schedule-state.json
  • Delete state files to reset

Hook errors

Missing jq:

sudo dnf install jq

Permission denied:

chmod +x ~/.claude/plugins/.../hooks/scripts/check-schedule.sh

Invalid JSON:

jq . ~/.claude/schedules.json  # Check syntax errors

Testing

To test without waiting for real time, temporarily modify the hook script:

File: Hook script in plugin installation

Add after set -euo pipefail:

# Test overrides
CURRENT_TIME="09:00"
CURRENT_DAY="Mon"

Replace time/day lines:

local current_time="$CURRENT_TIME"
local current_day="$CURRENT_DAY"

Submit a prompt - notifications should appear immediately.

Remember to restore the original time/day code after testing!

Command

A single unified interactive command:

  • /cron — Interactive entry point for add / list / enable / disable / remove. Uses AskUserQuestion to walk through each workflow. Accepts arguments to skip prompts (e.g. /cron list, /cron add "Standup" --cron "0 9 * * 1-5" global).

License

MIT

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.