remctl routes everything through one signed app, and Full Disk Access is part of the price
An Apple Reminders CLI for power users and AI agents. RemCTL supports all the latest Reminders features such as sections, subtasks, tags, rich links, groceries lists, templates, smart lists, and image attachments. (Not affiliated with Apple.)
At a glance
- What is it?
- remctl gives the terminal and AI apps control of Apple Reminders, including sections, tags, subtasks, smart lists and templates that Apple does not expose elsewhere. The permission model is centralized in a single signed host that runs in the background, which is what makes the feature set possible and also what couples your grants to the way you installed it.
- Who is it for?
- remctl suits a Mac user who wants reminders operable from scripts and agents and who accepts granting Reminders, Automation and Full Disk Access to a background app. Before installing, decide which route you will stay on, because switching between the disk image and your own build changes the signature and costs you your permissions, and think carefully before enabling the Tailscale client, since it puts that permission set within reach of another machine.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One app holds the permissions so nothing else needs them
The design decision that makes everything else possible is a single intermediary. RemCTL Capability Host is a small signed app that holds the macOS permissions, and every caller, whether the terminal, a script or an AI app, goes through it. You grant access once, to that one app, and none of the callers need permissions of their own.
That solves a problem Apple creates by having no supported scripting surface for Reminders. The feature list is mostly the things Apple does not expose to other apps: sections, tags, subtasks, smart lists and templates, alongside the basics of reminders, lists, due dates, flags and search.
The host is installed into `~/Applications` and kept running in the background, so you never open it. The repository carries a launch agent property list beside the host source, which is how that background presence is registered.
The download route also verifies provenance before installing. Terminal checks that RemCTL is signed by MacStories and notarized by Apple, which is the check that makes an unsigned build obvious. The recorded homepage for the project is the MacStories site rather than a project page, so the publisher and the tool are linked at the domain level.
Full Disk Access has no prompt, so a helper window tells you what to add
Setup asks for three permissions, all of them for the Capability Host: Reminders, Automation for the Reminders app, and Full Disk Access.
The first two behave like any macOS permission request. The third does not, because Full Disk Access is never prompted for, so remctl opens a helper that shows exactly which app to add, leaving you to grant it in System Settings yourself. That is a two-step flow in the middle of an otherwise automated install, and it is the step most likely to be abandoned halfway.
The scope of that grant deserves a moment. Full Disk Access is a system-wide permission, not a Reminders permission, and here it is held by an app that keeps running in the background. Whether it is strictly required for reminders work is not something the visible documentation explains, and the reason to ask is that the same grant would cover unrelated data on the machine.
Verification is one command:
remctl doctorIf setup is quit early there is `remctl onboard` to resume, and if the binary is not on the PATH the installer names the folder to add, which is usually `~/bin`. The source tree carries its own capability policy module and a permissions module in Swift, so the authorization rules live in the repository rather than in a binary blob.
Apple silicon gets a disk image and Intel has to build it
There are two install routes and they are not symmetric.
The recommended one is a download, and it is Apple silicon only. On such a Mac you fetch `RemCTL-arm64.dmg` from the releases page, open it, and double-click Install RemCTL. macOS asks whether to open an app downloaded from the internet, and after that Terminal checks the signature and notarization, installs it, and walks through permissions.
Intel Macs are pointed at the build-it-yourself route, which is free and also the route for anyone who wants to compile locally:
xcode-select --install
git clone https://github.com/viticci/remctl.git
cd remctl
./install.sh --from-source --bootstrapThat builds everything on the machine and signs it with a certificate remctl creates for you. The certificate is not an Apple developer credential and the process never signs in to Apple, which is why no developer account is needed. It lives in `~/Library/Application Support/RemCTL Signing`, and the instruction to keep it is not optional: future updates need the same certificate or the permissions go with it.
Both routes ask for the Mac password once. The runtime Python is installed under `/Library/RemCTL` owned by root, deliberately, so that other applications on the machine cannot modify the interpreter the tool runs on.
Permissions survive an update only if the signature does not change
Because macOS ties granted permissions to code identity, the upgrade path is a five-row lookup table keyed to where your copy came from rather than to a version number alone.
A 2.0 installed from the download gets the new release and the installer again. A 2.0 you built yourself gets a `git pull` and a rerun of the source installer, and a 2.0 prerelease built from the main branch with your own development certificate follows the same path, reusing that certificate so permissions carry over. A 1.7.1 install is recognized by the installer, which asks before replacing it, and 1.7.0 or older has to be uninstalled from the old checkout with configuration kept before installing as new.
The rule underneath is stated plainly: updates that keep the same signature keep your permissions. Crossing from 1.x is the one unavoidable regrant, because 1.x had no Capability Host at all, so the permissions you gave Terminal are not the permissions the new architecture needs.
The trap is switching routes. Going from the downloaded build to your own build, or the reverse, changes the app's signature, and the installer refuses to proceed unless you pass `--migrate-signing`. Even then Full Disk Access has to be granted again. So the first install decision quietly determines your upgrade path for the life of the installation.
A Python CLI on top of Swift, Objective-C and two HTML surfaces
The repository looks like a Python project and is not only one. The CLI, the broker, the MCP server, plugin support, event handling, image handling, serialization, smart lists and the workspace implementation are all Python modules at the repository root, along with an extensionless executable named `remctl`.
The privileged layer is Swift: a capability host, an installer, a permissions module and a bridge, plus two property lists, one for the host's identity and one launch agent that keeps it alive in the background. There is also a single Objective-C source file, which is the kind of artifact that exists because something needs calling into a system framework from a runtime that does not expose it directly.
Two HTML files complete the surface. One is the MCP widget that MCP-capable apps can render, the other backs the Reminders workspace.
Alongside them sit an agent skill file, a plugin directory and its marketplace manifest, a directory of agent configuration, scripts and tests, and separate installation and uninstallation shell scripts.
So the runtime Python being root-owned under `/Library/RemCTL` is only half the containment story. The component that actually holds the permissions is a signed native app, and the Python layer is a client of it.
The MCP server can be served to another machine over Tailscale
remctl includes a Model Context Protocol server, and setup offers to connect whichever supported AI apps it finds on the machine. Wiring it up is one command per target:
remctl mcp install
remctl mcp install --client claude-desktop
remctl mcp bundle --open
remctl mcp statusThe first form covers every supported app, the second targets Claude Desktop and Cowork and asks you to restart Claude afterwards, and the third installs it as a one-click Claude Desktop extension.
What the tools can do is broad: read, create, edit, complete and delete reminders and lists, search with paging, and restore items from Recently Deleted. Apps that support MCP Apps also get an interactive widget.
Then there is the remote case. `remctl mcp install --client tailscale` serves the same tools over a private Tailscale network, explicitly so that Claude Code, Codex, or Claude Desktop on another computer can drive the same reminders. That is the capability worth thinking about before switching it on, because the permission set you granted locally to protect your own Reminders becomes reachable from a second machine over the network, with full delete and create authority. Nothing in the visible documentation describes authentication on that path beyond the private network itself.
If you need the same ground covered elsewhere, the repository carries a separate guide for another agent tool alongside the main MCP guide.
The Claude Code plugin hardcodes ~/bin while custom paths are supported
The Claude Code plugin does two things. It exposes remctl's tools to Claude, and it adds a Today view, described as a mod, which keeps the day's reminders above the prompt. A mod is the part of a plugin that draws in Claude Code's own interface, and Today shows how many tasks are left, how many are overdue, a chip per list in that list's Reminders colour, and the next few tasks with their list and due time. Overdue dates are shown in red, a flag glyph marks a flagged task, and one, two or three exclamation marks indicate priority.
Installation is a marketplace add and an install, either inside Claude Code or from a shell:
/plugin marketplace add viticci/remctl
/plugin install remctl@remctl
/reload-pluginsThe coupling to watch is the path. The plugin starts `~/bin/remctl mcp`, hardcoded, while the installer says the PATH folder is usually `~/bin` but that custom paths are supported and are documented separately. A user who installed to a custom location gets a plugin that looks in the wrong place, and the failure will read as Claude having no reminder tools rather than as a path problem.
That is a small thing to fix and an easy thing to hit, and it is the one place where the convenience layer and the installer disagree about where the binary lives.
Every reminder has a stable id and every read command has JSON
The command surface is small enough to read in one screen, and its shape is what makes it scriptable rather than merely convenient:
remctl today
remctl upcoming 7
remctl show Work --format table
remctl search "invoice" --json
remctl add "Review PR" -l Work -d "tomorrow 10:00" -p high
remctl add "Pay rent" -d 2026-06-01 --recurrence monthly
remctl done 23880 23881
remctl info 23880 --jsonThree conventions do the work. Every reminder has a stable numeric id, so nothing depends on a title that a user is free to edit. Every read command accepts JSON output, so a script never has to parse the formatted table. And completion accepts a batch, with the example showing two ids and the documented limit being fifty at a time.
Two smaller conveniences are worth knowing. The table format returns reminders in the order Reminders itself uses rather than an alphabetical or creation order, so output matches what the user sees in the app. And short aliases exist, with both `rctl` and `reminders` working as alternatives to the full name.
The natural-language date parsing and recurrence handling shown in the add examples are what the CLI guide expands on, along with output formats and inline images.
Editorial conclusion
remctl suits a Mac user who wants reminders operable from scripts and agents and who accepts granting Reminders, Automation and Full Disk Access to a background app. Before installing, decide which route you will stay on, because switching between the disk image and your own build changes the signature and costs you your permissions, and think carefully before enabling the Tailscale client, since it puts that permission set within reach of another machine.
Frequently asked questions
What does remctl add to Apple Reminders?
Beyond the basics of reminders, lists, due dates, flags and search, it covers features Apple does not expose to other apps, including sections, tags, subtasks, smart lists and templates. Every reminder has a stable numeric id and every read command supports JSON output.
Why does remctl need a separate app for permissions?
Because all access goes through RemCTL Capability Host, a small signed app that holds the macOS permissions, and the terminal, scripts and AI apps use it rather than holding their own. The host is installed into ~/Applications and kept running in the background.
Which permissions does remctl ask for?
Three, all for the Capability Host: Reminders, Automation for the Reminders app, and Full Disk Access. The first two are standard prompts, while Full Disk Access has no prompt at all, so remctl opens a helper telling you which app to add. Check the result with remctl doctor.
Can I install remctl on an Intel Mac?
Not from the disk image, since the recommended download is RemCTL-arm64.dmg for Apple silicon. Intel machines use the source route: install the Command Line Tools with xcode-select, clone the repository, and run ./install.sh --from-source --bootstrap.
Why do my remctl permissions disappear after an update?
Because macOS binds permissions to the code signature. Updates that keep the same signature keep your permissions, but switching between the downloaded build and your own build changes the signature, so the installer refuses without --migrate-signing and Full Disk Access must be granted again. Upgrading from 1.x always requires a regrant since that version had no capability host.
Can AI apps on another computer use remctl?
Yes. Running remctl mcp install --client tailscale serves the same tools over a private Tailscale network for Claude Code, Codex, or Claude Desktop on another machine, with the ability to read, create, edit, complete and delete reminders and lists and to restore from Recently Deleted.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/viticci-remctl)