reminders.lua turns the native macOS Reminders app into a typed
computer.cpp API. It is a reference for building APIs around any desktop
app using screenshots, accessibility targets, controlled input, and visual
verification.
The example exposes four commands:
| Command | Purpose |
|---|---|
list-reminders |
Read visible reminder rows from a named list. |
add-reminder |
Create one reminder with an optional notes field and verify it is visible. |
complete-reminder |
Mark a reminder complete by title and verify it is no longer visible as an incomplete row. |
summarize-list |
Read visible reminders and return a short summary. |
The due field is present in the schema but must be empty.
The file returns an ac.app.define object named mac.reminders. Each
app:command declares:
description: human-readable command purpose.input: typed fields accepted bycomputer.cpp app runand HTTP requests.output: typed fields returned by the command.handler: Lua code that drives and verifies the desktop workflow.
The handlers use ac.desktop.vision_task to keep Reminders frontmost, capture
the frontmost window, ask a bounded vision agent to identify visible controls,
and expose only narrow tools such as click_toolbar_plus,
type_requested_reminder_text, complete_reminder_checkbox, and visual
confirmation tools. The tool handlers validate coordinates and state before
issuing real input through the local daemon.
- macOS with the Reminders app available.
- Accessibility and Screen Recording permissions for the built
ComputerCppapp or CLI process. - An LLM provider configured with
computer.cpp configor the tray Settings window. Usecomputer.cpp config pathto locate the editableconfig.toml.
From the tray app, open the tray menu and choose Permissions. Click Request
and then Test for Accessibility, repeat for Screen Recording, and use
Restart ComputerCpp if macOS asks for a restart. If Screen Recording does not
add the app automatically, use the + button in System Settings and select the
running build/debug/ComputerCpp.app.
From the CLI, check or request permissions with:
computer.cpp permissions --requestTo configure the model from the tray app, choose Settings..., edit Providers
and Profiles, click Set Active on the profile to use, then click
Save Changes. The same settings are stored in the TOML file printed by
computer.cpp config path.
Build the project, then run the example with computer.cpp app run:
cmake -S . -B build/debug -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
cmake --build build/debug
./build/debug/computer.cpp app run examples/mac/reminders.luaPrint command-specific help:
./build/debug/computer.cpp app run examples/mac/reminders.lua add-reminder --helpList visible reminders:
./build/debug/computer.cpp --json app run examples/mac/reminders.lua \
list-reminders --list Today --limit 10Add a reminder:
./build/debug/computer.cpp --json app run examples/mac/reminders.lua \
add-reminder --list Today --title "Review release notes" --notes "Before publishing"Complete a reminder:
./build/debug/computer.cpp --json app run examples/mac/reminders.lua \
complete-reminder --list Today --title "Review release notes"Summarize a list:
./build/debug/computer.cpp --json app run examples/mac/reminders.lua \
summarize-list --list Today --limit 25The same Lua app can be served locally as REST and MCP:
./build/debug/computer.cpp app serve examples/mac/reminders.lua --listen 127.0.0.1:8787Inspect the generated schema:
curl http://127.0.0.1:8787/schemaCall a command:
curl -X POST http://127.0.0.1:8787/commands/add-reminder \
-H 'Content-Type: application/json' \
-d '{"list":"Today","title":"Review release notes","notes":"Before publishing"}'List the generated MCP tools:
curl -X POST http://127.0.0.1:8787/mcp \
-H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-H 'MCP-Protocol-Version: 2025-11-25' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'When binding outside localhost, app serve requires --auth-token-env so the
HTTP and MCP APIs are not exposed without a bearer token. When serving through
Caddy or another HTTPS reverse proxy, also pass --allowed-origin for the
public origin that should be allowed to reach /mcp.
Input:
liststring, required: Reminders list name.limitinteger, default25: maximum visible rows to return.
Output:
listcountreminders[]withtitle,completed,due, andnotes.
Input:
liststring, required: Reminders list name.titlestring, required: reminder title.notesstring, default"": optional notes text.duestring, default"": unsupported and must be empty.
Output:
createdlisttitlenotesduevisible_titlevisible_notesevidence
Input:
titlestring, required: reminder title to complete.liststring, default"": optional list to select first.
Output:
completedtitlematched_titleevidence
Input:
liststring, required: Reminders list name.limitinteger, default50: maximum visible rows to include.
Output:
listcountsummaryreminders[]