
Remind Me
- 893 installs
- 635 repo stars
- Updated March 7, 2026
- sundial-org/awesome-openclaw-skills
remind-me is a bash agent skill that reads a markdown reminders file, outputs due time-based items, and marks them complete for developers who store scheduled tasks in simple checkbox syntax.
About
remind-me is a bash skill from sundial-org/awesome-openclaw-skills that checks a markdown reminders file and outputs items whose scheduled time has passed so an agent can surface them. Reminders use unchecked checkbox lines with a datetime and message, for example '- [ ] 2026-01-06 14:30 | Pay for Gumroad', and the script supports shortcuts like replacing 'today' with the current date. The default reminders file path is /home/julian/clawd/reminders.md, which teams typically override for their environment. Developers reach for remind-me when agents should proactively poll a plain-markdown reminder list instead of integrating a calendar or task API.
- Scans reminders.md for due items using epoch comparison
- Supports 'today' and 'tomorrow' shorthand dates
- Automatically marks completed reminders with [x]
- Outputs only currently due reminder messages for the agent
- Zero-config integration with any agent workflow
Remind Me by the numbers
- 893 all-time installs (skills.sh)
- +4 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #530 of 3,301 Productivity & Planning skills by installs in the Skillselion catalog
- Security screen: HIGH risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/sundial-org/awesome-openclaw-skills --skill remind-meAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 893 |
|---|---|
| repo stars | ★ 635 |
| Security audit | 2 / 3 scanners passed |
| Last updated | March 7, 2026 |
| Repository | sundial-org/awesome-openclaw-skills ↗ |
How do agents check markdown file reminders?
Automatically surface and mark off time-based reminders stored in a simple markdown file.
Who is it for?
Developers running OpenClaw-style agents who keep time-based tasks in a simple markdown checkbox file.
Skip if: Teams needing calendar sync, recurring RRULE reminders, or multi-user task management with notifications infrastructure.
When should I use this skill?
An agent session should poll a markdown reminders file and surface or complete time-based checkbox reminders that are now due.
What you get
List of due reminder messages and updated checked-off entries in the markdown reminders file.
- Due reminder messages
- Checked-off reminder entries
By the numbers
- Default reminders file path: /home/julian/clawd/reminders.md
Files
Remind Me
Natural language reminders that fire automatically. Uses cron for scheduling, markdown for logging.
Usage
One-Time Reminders
Just ask naturally:
- "Remind me to pay for Gumroad later today"
- "Remind me to call mom tomorrow at 3pm"
- "Remind me in 2 hours to check the oven"
- "Remind me next Monday at 9am about the meeting"
Recurring Reminders
For repeating reminders:
- "Remind me every hour to stretch"
- "Remind me every day at 9am to check email"
- "Remind me every Monday at 2pm about the meeting"
- "Remind me weekly to submit timesheet"
How It Works
1. Parse the time from your message 2. Create a one-time cron job with --at 3. Log to /home/julian/clawd/reminders.md for history 4. At the scheduled time, you get a message
Time Parsing
One-Time Reminders
Relative:
- "in 5 minutes" / "in 2 hours" / "in 3 days"
- "later today" → 17:00 today
- "this afternoon" → 15:00 today
- "tonight" → 20:00 today
Absolute:
- "tomorrow" → tomorrow 9am
- "tomorrow at 3pm" → tomorrow 15:00
- "next Monday" → next Monday 9am
- "next Monday at 2pm" → next Monday 14:00
Dates:
- "January 15" → Jan 15 at 9am
- "Jan 15 at 3pm" → Jan 15 at 15:00
- "2026-01-15" → Jan 15 at 9am
- "2026-01-15 14:30" → Jan 15 at 14:30
Recurring Reminders
Intervals:
- "every 30 minutes"
- "every 2 hours"
Daily:
- "daily at 9am"
- "every day at 3pm"
Weekly:
- "weekly" → every Monday at 9am
- "every Monday at 2pm"
- "every Friday at 5pm"
Reminder Log
All reminders are logged to /home/julian/clawd/reminders.md:
- [scheduled] 2026-01-06 17:00 | Pay for Gumroad (id: abc123)
- [recurring] every 2h | Stand up and stretch (id: def456)
- [recurring] cron: 0 9 * * 1 | Weekly meeting (id: ghi789)Status:
[scheduled]— one-time reminder waiting to fire[recurring]— repeating reminder (active)[sent]— one-time reminder already delivered
Manual Commands
# List pending reminders
cron list
# View reminder log
cat /home/julian/clawd/reminders.md
# Remove a scheduled reminder
cron rm <job-id>Agent Implementation
One-Time Reminders
When the user says "remind me to X at Y":
bash /home/julian/clawd/skills/remind-me/create-reminder.sh "X" "Y"Examples:
bash /home/julian/clawd/skills/remind-me/create-reminder.sh "Pay for Gumroad" "later today"
bash /home/julian/clawd/skills/remind-me/create-reminder.sh "Call dentist" "tomorrow at 3pm"
bash /home/julian/clawd/skills/remind-me/create-reminder.sh "Check email" "in 2 hours"Recurring Reminders
When the user says "remind me every X to Y":
bash /home/julian/clawd/skills/remind-me/create-recurring.sh "Y" "every X"Examples:
bash /home/julian/clawd/skills/remind-me/create-recurring.sh "Stand up and stretch" "every 2 hours"
bash /home/julian/clawd/skills/remind-me/create-recurring.sh "Check email" "daily at 9am"
bash /home/julian/clawd/skills/remind-me/create-recurring.sh "Weekly team meeting" "every Monday at 2pm"Both scripts automatically: 1. Parse the time/schedule 2. Create a cron job (one-time with --at or recurring with --every/--cron) 3. Log to /home/julian/clawd/reminders.md 4. Return confirmation with job ID
#!/bin/bash
# Check reminders and output due ones (to be sent by the agent)
REMINDERS_FILE="/home/julian/clawd/reminders.md"
NOW_EPOCH=$(date +%s)
# Exit if no reminders file
[[ ! -f "$REMINDERS_FILE" ]] && exit 0
DUE_REMINDERS=()
# Process each unchecked reminder
while IFS= read -r line; do
# Extract: "- [ ] 2026-01-06 14:30 | Pay for Gumroad"
datetime=$(echo "$line" | sed -n 's/^- \[ \] \(.*\) | .*/\1/p')
message=$(echo "$line" | sed -n 's/^- \[ \] .* | \(.*\)/\1/p')
# Skip if parsing failed
[[ -z "$datetime" ]] || [[ -z "$message" ]] && continue
# Handle shortcuts
datetime=$(echo "$datetime" | sed "s/^today/$(date '+%Y-%m-%d')/")
datetime=$(echo "$datetime" | sed "s/^tomorrow/$(date -d 'tomorrow' '+%Y-%m-%d')/")
# Add default time if missing
if ! echo "$datetime" | grep -q ":"; then
datetime="$datetime 09:00"
fi
# Parse to epoch
reminder_epoch=$(date -d "$datetime" +%s 2>/dev/null)
# Skip if date parsing failed
[[ -z "$reminder_epoch" ]] && continue
# Check if due
if [[ $NOW_EPOCH -ge $reminder_epoch ]]; then
DUE_REMINDERS+=("$message")
# Mark as done by replacing [ ] with [x]
escaped_datetime=$(echo "$datetime" | sed 's/[]\/$*.^[]/\\&/g')
escaped_message=$(echo "$message" | sed 's/[]\/$*.^[]/\\&/g')
sed -i "s/^- \[ \] $escaped_datetime | $escaped_message$/- [x] $escaped_datetime | $escaped_message/" "$REMINDERS_FILE"
fi
done < <(grep "^- \[ \]" "$REMINDERS_FILE")
# Output due reminders
if [[ ${#DUE_REMINDERS[@]} -gt 0 ]]; then
for reminder in "${DUE_REMINDERS[@]}"; do
echo "⏰ $reminder"
done
fi
# Clean up reminders older than 24 hours
while IFS= read -r line; do
datetime=$(echo "$line" | sed -n 's/^- \[x\] \(.*\) | .*/\1/p')
reminder_epoch=$(date -d "$datetime" +%s 2>/dev/null)
[[ -z "$reminder_epoch" ]] && continue
age_hours=$(( (NOW_EPOCH - reminder_epoch) / 3600 ))
if [[ $age_hours -gt 24 ]]; then
# Delete old completed reminders
escaped_line=$(echo "$line" | sed 's/[\/&]/\\&/g')
sed -i "/^${escaped_line}$/d" "$REMINDERS_FILE"
fi
done < <(grep "^- \[x\]" "$REMINDERS_FILE")
#!/bin/bash
# Create a recurring reminder
# Usage: create-recurring.sh "message" "schedule"
MESSAGE="$1"
SCHEDULE="$2"
REMINDERS_FILE="/home/julian/clawd/reminders.md"
TIMEZONE="Europe/Warsaw"
[[ -z "$MESSAGE" ]] && echo "Error: No message provided" && exit 1
[[ -z "$SCHEDULE" ]] && echo "Error: No schedule provided" && exit 1
# Parse schedule to cron expression or duration
parse_schedule() {
local input="$1"
# Every X minutes/hours
if [[ "$input" =~ every[[:space:]]+([0-9]+)[[:space:]]+(minute|hour)s? ]]; then
local amount="${BASH_REMATCH[1]}"
local unit="${BASH_REMATCH[2]}"
case "$unit" in
minute) echo "duration:$((amount))m" ;;
hour) echo "duration:$((amount))h" ;;
esac
return
fi
# Daily at specific time
if [[ "$input" =~ (daily|every[[:space:]]+day)[[:space:]]+at[[:space:]]+([0-9]{1,2})(:[0-9]{2})?(am|pm)? ]]; then
local hour="${BASH_REMATCH[2]}"
local minute="${BASH_REMATCH[3]:-:00}"
local ampm="${BASH_REMATCH[4]}"
minute="${minute#:}"
# Convert to 24h if needed
if [[ "$ampm" == "pm" ]] && [[ $hour -lt 12 ]]; then
hour=$((hour + 12))
elif [[ "$ampm" == "am" ]] && [[ $hour -eq 12 ]]; then
hour=0
fi
# Cron: minute hour * * *
echo "cron:$minute $hour * * *"
return
fi
# Weekday at time (e.g., "every Monday at 2pm")
if [[ "$input" =~ every[[:space:]]+(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)[[:space:]]+at[[:space:]]+([0-9]{1,2})(:[0-9]{2})?(am|pm)? ]]; then
local day="${BASH_REMATCH[1]}"
local hour="${BASH_REMATCH[2]}"
local minute="${BASH_REMATCH[3]:-:00}"
local ampm="${BASH_REMATCH[4]}"
minute="${minute#:}"
# Convert to 24h if needed
if [[ "$ampm" == "pm" ]] && [[ $hour -lt 12 ]]; then
hour=$((hour + 12))
elif [[ "$ampm" == "am" ]] && [[ $hour -eq 12 ]]; then
hour=0
fi
# Convert day to cron day-of-week (0=Sunday)
local dow
case "$day" in
Sunday) dow=0 ;;
Monday) dow=1 ;;
Tuesday) dow=2 ;;
Wednesday) dow=3 ;;
Thursday) dow=4 ;;
Friday) dow=5 ;;
Saturday) dow=6 ;;
esac
# Cron: minute hour * * day-of-week
echo "cron:$minute $hour * * $dow"
return
fi
# Weekly (defaults to Monday 9am)
if [[ "$input" =~ ^weekly$ ]]; then
echo "cron:0 9 * * 1"
return
fi
echo "error"
}
# Parse the schedule
PARSED=$(parse_schedule "$SCHEDULE")
if [[ "$PARSED" == "error" ]]; then
echo "Error: Could not parse schedule: $SCHEDULE"
exit 1
fi
# Build cron command based on type
if [[ "$PARSED" =~ ^duration:(.+)$ ]]; then
DURATION="${BASH_REMATCH[1]}"
cd /home/julian/clawdbot
JOB_OUTPUT=$(npx tsx src/index.ts cron add \
--name "Recurring: $MESSAGE" \
--every "$DURATION" \
--session isolated \
--wake now \
--message "⏰ $MESSAGE" \
--deliver \
--channel telegram \
--to 6636746252 \
--json 2>&1)
SCHEDULE_DISPLAY="every $DURATION"
elif [[ "$PARSED" =~ ^cron:(.+)$ ]]; then
CRON_EXPR="${BASH_REMATCH[1]}"
cd /home/julian/clawdbot
JOB_OUTPUT=$(npx tsx src/index.ts cron add \
--name "Recurring: $MESSAGE" \
--cron "$CRON_EXPR" \
--tz "$TIMEZONE" \
--session isolated \
--wake now \
--message "⏰ $MESSAGE" \
--deliver \
--channel telegram \
--to 6636746252 \
--json 2>&1)
SCHEDULE_DISPLAY="cron: $CRON_EXPR"
fi
if [[ $? -ne 0 ]]; then
echo "Error creating cron job: $JOB_OUTPUT"
exit 1
fi
# Extract JSON from output
JSON_OUTPUT=$(echo "$JOB_OUTPUT" | grep -A100 "^{" | grep -B100 "^}")
JOB_ID=$(echo "$JSON_OUTPUT" | jq -r '.id' 2>/dev/null)
# Log to markdown
mkdir -p "$(dirname "$REMINDERS_FILE")"
echo "- [recurring] $SCHEDULE_DISPLAY | $MESSAGE (id: $JOB_ID)" >> "$REMINDERS_FILE"
echo "✅ Recurring reminder set: $SCHEDULE_DISPLAY"
echo "📝 Logged to $REMINDERS_FILE"
echo "🆔 Job ID: $JOB_ID"
#!/bin/bash
# Create a one-time reminder
# Usage: create-reminder.sh "message" "when"
MESSAGE="$1"
WHEN="$2"
REMINDERS_FILE="/home/julian/clawd/reminders.md"
TIMEZONE="Europe/Warsaw"
[[ -z "$MESSAGE" ]] && echo "Error: No message provided" && exit 1
[[ -z "$WHEN" ]] && echo "Error: No time provided" && exit 1
# Parse natural language to timestamp
parse_time() {
local input="$1"
local now=$(date +%s)
# Relative times with "in X minutes/hours/days"
if [[ "$input" =~ in[[:space:]]+([0-9]+)[[:space:]]+(minute|hour|day)s? ]]; then
local amount="${BASH_REMATCH[1]}"
local unit="${BASH_REMATCH[2]}"
case "$unit" in
minute) date -d "+${amount} minutes" --iso-8601=seconds ;;
hour) date -d "+${amount} hours" --iso-8601=seconds ;;
day) date -d "+${amount} days" --iso-8601=seconds ;;
esac
return
fi
# Time of day shortcuts
case "$input" in
"later today"|"later"|"this afternoon")
date -d "today 17:00" --iso-8601=seconds
return
;;
"tonight")
date -d "today 20:00" --iso-8601=seconds
return
;;
"tomorrow")
date -d "tomorrow 09:00" --iso-8601=seconds
return
;;
esac
# Try GNU date parsing
date -d "$input" --iso-8601=seconds 2>/dev/null
}
# Parse the time
TIMESTAMP=$(parse_time "$WHEN")
if [[ -z "$TIMESTAMP" ]]; then
echo "Error: Could not parse time: $WHEN"
exit 1
fi
# Format for display
DISPLAY_TIME=$(date -d "$TIMESTAMP" '+%Y-%m-%d %H:%M')
# Create cron job
cd /home/julian/clawdbot
JOB_OUTPUT=$(npx tsx src/index.ts cron add \
--name "Reminder: $MESSAGE" \
--at "$TIMESTAMP" \
--session isolated \
--wake now \
--message "⏰ Reminder: $MESSAGE" \
--deliver \
--channel telegram \
--to 6636746252 \
--json 2>&1)
if [[ $? -ne 0 ]]; then
echo "Error creating cron job: $JOB_OUTPUT"
exit 1
fi
# Extract JSON from output (skip npm warnings)
JSON_OUTPUT=$(echo "$JOB_OUTPUT" | grep -A100 "^{" | grep -B100 "^}")
JOB_ID=$(echo "$JSON_OUTPUT" | jq -r '.id' 2>/dev/null)
# Log to markdown
mkdir -p "$(dirname "$REMINDERS_FILE")"
echo "- [scheduled] $DISPLAY_TIME | $MESSAGE (id: $JOB_ID)" >> "$REMINDERS_FILE"
echo "✅ Reminder set for $DISPLAY_TIME"
echo "📝 Logged to $REMINDERS_FILE"
echo "🆔 Job ID: $JOB_ID"
Related skills
How it compares
Use remind-me for plain-markdown agent reminders; use full PM integrations when tasks need assignees, dependencies, or external notifications.
FAQ
What reminder format does remind-me expect?
remind-me expects unchecked markdown lines like '- [ ] 2026-01-06 14:30 | Message', parses the datetime and text, and outputs entries whose scheduled time has passed.
Where does remind-me read reminders from?
remind-me reads from a REMINDERS_FILE markdown path, defaulting to /home/julian/clawd/reminders.md, and exits quietly if the file is missing.
Is Remind Me safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.