Skip to main content

reminders-cli

Read, add, edit, complete and delete macOS Reminders from the command line. Use when the user asks about their reminders, to-dos, or tasks on a Mac.

Source facts

Repository
udondan/reminders-cli
Last source activity
September 16, 2026 at 08:56
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
reminders-cli
description
Read, add, edit, complete and delete macOS Reminders from the command line. Use when the user asks about their reminders, to-dos, or tasks on a Mac.
allowed-tools
Bash(reminders:*)
# reminders-cli `reminders` is a macOS command-line tool that talks to Reminders.app through EventKit. ## Invocation - The binary is `reminders` and must be on `PATH`. Install with `brew install udondan/software/reminders-cli`. - The terminal application running the command needs Reminders access (System Settings > Privacy & Security > Reminders). Without it every command fails with exit status 11. When that happens, or a command unexpectedly returns nothing, run `reminders doctor --format json` and relay the `suggestion` of each entry in `problems` to the user. - Output goes to stdout. Errors go to stderr only, with a stable code and exit status (see Errors). ## Rules for agents 1. **Always pass `--format json`.** Every subcommand supports it. Parse the output instead of the plain-text format. 2. **Always act on reminders by ID.** Every reminder has a stable `externalId`. Look it up with `show` or `show-all`, then pass it to `edit`, `complete`, `uncomplete`, `postpone` and `delete`. Never match reminders by title. 3. Wherever a `<list>` argument is accepted, either the list name or its `calendarIdentifier` (from `show-lists --format json`) works. Prefer the ID when the name is ambiguous or contains shell-unfriendly characters. 4. `show`, `show-all`, `today`, `overdue`, `upcoming` and `show-lists` print a JSON array. `add`, `edit`, `complete`, `uncomplete`, `postpone` and `delete` print the affected reminder as a single JSON object (for `delete`, the reminder as it was before removal) when given one ID, and an array of the affected reminders for a batch (several IDs, a comma-separated list, or `-`). `new-list` prints the created list. `delete-list --confirm` prints the deleted list. `doctor` prints a single diagnostics object. Keys are sorted alphabetically. 5. Reminder text is passed as trailing positional arguments and may contain spaces; quote it. Notes go in `--notes`/`-n` and may start with `-` or span lines (e.g. a `- [ ] item` checklist). Reminder text that starts with `-` must come after `--`, placed after all options: `reminders add <list> --notes "- [ ] a" -- "- text"`. 6. `delete` finds a reminder by ID regardless of completion state, so completed reminders need no special handling. 7. **Act on several reminders in one call.** `complete`, `uncomplete` and `delete` take several IDs as separate arguments or comma-separated. `edit` and `postpone` take a comma-separated list in their `<id>` argument. Everywhere, `-` reads newline-separated IDs from stdin (e.g. `... --format json | jq -r '.[].externalId' | reminders postpone <list> - today`). Every ID is resolved first; if any is missing, ambiguous or can't be changed, the command fails and changes nothing. 8. **Never pass `--confirm` to `delete-list` on your own.** Run it without `--confirm` first. It exits 13 (`confirmation_required`) and its message says how many reminders the list holds. Show that to the user, and add `--confirm` only after they explicitly agree to delete the list and all its reminders. Pass the list's `calendarIdentifier`; partial names are rejected. ## Commands | Command | Arguments and options | | --- | --- | | `reminders show-lists` | Lists with their open and overdue reminder counts. `--default-only`/`-d` (only the list Reminders.app adds to by default), `--include-completed` (also count completed reminders, slower), `--sort`/`-s <none\|name\|open\|overdue>` | | `reminders show <list>` | Reminders on one list. Filters: `--only-completed`, `--include-completed`, `--include-overdue` (with `--due-date`, also include items due before that date), `--due-date`/`-d <date>`, `--overdue`, `--due-before <date>`, `--due-after <date>`, `--no-due-date`, `--priority <none\|low\|medium\|high>` (repeatable), `--search <text>` (case-insensitive, matches title or notes), `--flagged`, `--completed-since <date>`. Sorting: `--sort`/`-s <none\|creation-date\|due-date\|priority>`, `--sort-order`/`-o <ascending\|descending>` | | `reminders show-all` | Reminders across all lists. Same filters and sorting as `show`, plus `--list <list>` (repeatable) to restrict to some lists | | `reminders today` | Incomplete reminders due today plus overdue ones, across all lists. `--no-overdue` (only due today), `--list <list>` (repeatable), `--sort`/`--sort-order` (default due date ascending) | | `reminders overdue` | Incomplete reminders whose due date has passed. `--list <list>` (repeatable), `--sort`/`--sort-order` (default due date ascending) | | `reminders upcoming` | Incomplete reminders due from now through the end of the day N days ahead. `--days <n>` (default 7), `--include-overdue` (also past-due ones), `--list <list>` (repeatable), `--sort`/`--sort-order` (default due date ascending) | | `reminders add <list> <text...>` | `--due-date`/`-d <date>`, `--priority`/`-p <none\|low\|medium\|high>`, `--notes`/`-n <text>`, `--repeat <daily\|weekly\|monthly\|yearly>`, `--repeat-interval <n>`, `--repeat-until <date>`, `--repeat-on <days>` (weekly on these days, e.g. `mon,wed,fri`, `weekdays`, `weekends`; implies `--repeat weekly`) | | `reminders edit <list> <id[,id...]> [new text...]` | `--due-date`/`-d <date>`, `--clear-due-date`, `--priority`/`-p <value>`, `--clear-priority`, `--notes`/`-n <text>` (overwrites), `--clear-notes`, `--list <list>` (move to another list), `--repeat <frequency>`, `--repeat-interval <n>`, `--repeat-until <date>`, `--clear-repeat-end` (repeat forever), `--repeat-on <days>` (replace the days of a weekly repeat), `--clear-repeat-on` (remove the days), `--clear-repeat` | | `reminders complete <list> <id...>` | Mark done | | `reminders uncomplete <list> <id...>` | Mark not done | | `reminders postpone <list> <id[,id...]> [date]` | Move the due date without touching the repeat rule. Pass either a `date` or `--next-weekday` (next Mon-Fri, keeps the time of day, requires an existing due date) | | `reminders delete <list> <id...>` | Delete the reminders | | `reminders new-list <name>` | `--source`/`-s <name>` (account to create the list in, e.g. iCloud; required only when several accounts hold lists) | | `reminders delete-list <list>` | Delete a list and every reminder on it. `--confirm` (required to actually delete; without it the command exits 13 and only reports what would be deleted). `<list>` must be the ID or the whole name, not a part of it. The default list and read-only lists are refused (exit 12) | | `reminders doctor` | Diagnose Reminders access and the environment without requesting access. Exits 0 when no check failed, 1 otherwise (the report is still on stdout, nothing on stderr) | All commands also accept `--format`/`-f <plain|json>`. `show`, `show-all`, `today`, `overdue` and `upcoming` additionally accept `pretty` (a coloured, column-aligned layout with shortened IDs, for people only; never parse it) and `--verbose`/`-v` (only with `pretty`). The `REMINDERS_FORMAT` environment variable can make `pretty` their default, so always pass `--format json` explicitly; an explicit `--format` always wins. Constraints enforced by the CLI (violations are usage errors, exit status 64): - `show`/`show-all`: `--only-completed` and `--include-completed` are exclusive. `--no-due-date` cannot be combined with `--due-date`, `--due-before`, `--due-after`, `--overdue` or `--include-overdue`. `--completed-since` requires `--only-completed` or `--include-completed`. `--list` exists only on `show-all`. `--flagged` combines with every other filter. - Flagged state is read-only. `add` and `edit` have no flag options, so tell the user to flag or unflag in Reminders.app. - `add`: `--repeat` and `--repeat-on` require `--due-date`. `--repeat-interval` and `--repeat-until` require `--repeat` or `--repeat-on`. `--repeat-interval` must be at least 1. `--repeat-until` must not be earlier than `--due-date`. `hourly` is rejected because EventKit reminders have no hourly frequency. - `--repeat-on` takes a comma-separated list of `sun`..`sat` or full day names (case-insensitive), or the aliases `weekdays` (Mon-Fri) and `weekends` (Sat, Sun). Duplicates are ignored, unknown names are a usage error. It only works with a weekly repeat: combining it with `--repeat daily|monthly|yearly` is a usage error. - `edit`: at least one change is required. New text can't be combined with several IDs (a comma-separated list or `-`). `--due-date`/`--clear-due-date`, `--priority`/`--clear-priority`, `--notes`/`--clear-notes` and `--repeat-on`/`--clear-repeat-on` are pairwise exclusive. `--clear-repeat` cannot be combined with other repeat options. Changing only the interval, end or days keeps the existing frequency. `--repeat-on`/`--clear-repeat-on` on a reminder whose repeat is not weekly fails with `invalid_argument`. Changing the frequency resets the interval to 1 unless `--repeat-interval` is given. - `postpone`: exactly one of `date` or `--next-weekday`. - `upcoming`: `--days` must be at least 1. - `--sort priority` orders high, medium, low, then none, with due date ascending as the tiebreaker. `--sort due-date` always puts reminders without a due date last. - `show-lists --sort name` is ascending and case-insensitive; `--sort open` and `--sort overdue` are descending (busiest list first) with the name as the tiebreaker. `show-lists` has no `--sort-order`. ## JSON fields of a reminder All dates are ISO 8601 strings in UTC (for example `2026-09-14T07:00:00Z`). `completionDate`, `dueDate` and `nextDueDate` also have a `...Local` variant: the same instant in the machine's time zone with its offset (for example `2026-09-15T00:00:00+02:00`, or `Z` when the offset is zero). To group or compare by calendar day, use the date part of a `...Local` field rather than converting the UTC value yourself, and check `isAllDay` before reading a time of day. Fields marked optional are omitted from the object when they do not apply. <!-- json-fields:start --> | Field | Type | Present | Meaning | | --- | --- | --- | --- | | `externalId` | string | always | Stable identifier. Use it for `edit`, `complete`, `uncomplete`, `postpone` and `delete`. | | `lastModified` | string | optional | Last modification time. | | `creationDate` | string | optional | Creation time. | | `title` | string | always | Reminder text. | | `notes` | string | optional | Notes. Omitted when empty. | | `url` | string | never | Reserved. EventKit never returns a URL for reminders, so the key is absent in practice. | | `location` | string | optional | `"latitude, longitude"` of a location-based alarm. | | `locationTitle` | string | optional | Title of a location-based alarm. | | `completionDate` | string or null | always | Completion time, `null` while incomplete. | | `completionDateLocal` | string or null | always | `completionDate` in the machine's time zone with offset, `null` while incomplete. | | `isCompleted` | boolean | always | Whether the reminder is done. | | `priority` | integer | always | EventKit priority: `0` none, `1` high, `5` medium, `9` low. | | `startDate` | string | optional | Start date, if set. | | `dueDate` | string | optional | Due date. For repeating reminders this is the date last set, not the next occurrence (see below). | | `dueDateLocal` | string | optional | `dueDate` in the machine's time zone with offset. Present whenever `dueDate` is. | | `isAllDay` | boolean | optional | Whether the due date has no time of day (a date-only reminder, due at local midnight). Present whenever `dueDate` is. | | `list` | string | always | Name of the list containing the reminder. | | `listId` | string | always | `calendarIdentifier` of that list. | | `recurrence` | string | optional | `daily`, `weekly`, `monthly` or `yearly`. Only present when `hasRecurrence` is true. | | `recurrenceInterval` | integer | optional | Repeat every N units of `recurrence`. Only present when `hasRecurrence` is true. | | `recurrenceDays` | array of strings | optional | Days a weekly repeat fires on, lowercase three-letter names in Sunday-first order, e.g. `["mon","wed","fri"]`. Only present when the rule has plain weekday selectors. | | `recurrenceEnd` | string | optional | Date the repeat rule ends. Only for date-ended rules. | | `recurrenceCount` | integer | optional | Number of occurrences. Only for count-ended rules (created by Reminders.app, not by this CLI). | | `hasRecurrence` | boolean | always | Whether a repeat rule is set. | | `isFlagged` | boolean | always | Whether the reminder is flagged. Read-only: no command can set or clear it. Reads `false` on macOS versions that don't expose the flag. | | `nextDueDate` | string | optional | Next actionable occurrence of a repeating reminder, computed by the CLI: the first occurrence at or after now, counted from `dueDate` (equals `dueDate` while that is still ahead). Only present when `hasRecurrence` is true, `isCompleted` is false and the rule is a plain daily/weekly/monthly/yearly (+ interval) rule or a weekly rule on `recurrenceDays`. | | `nextDueDateLocal` | string | optional | `nextDueDate` in the machine's time zone with offset. Present whenever `nextDueDate` is. | <!-- json-fields:end -->
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub