On macOS, Saturn works through the apps themselves, so what it does shows up where you'd look for it. Each app tool runs AppleScript through osascript. Readers are read_only and untrusted: a shared note, an invitation, or an email is someone else's text, so it's scanned and fenced like a web page. Writers ask first.
::the apps
Notes
search and read notes; create one; append to an existing note. An append writes only to the note with exactly that title (or its id), never a near match, and leaves a locked note or one with attachments alone.
Calendar
list events (today, tomorrow, next monday, and in 1 week work); create, move, rename, or delete one. A repeating event changes only as a whole series, and you're told when attendees may be notified. A bare time like "3pm" keeps an event on its own day. Reading every calendar takes several seconds, so narrowing to named calendars is faster.
list, search, and read; draft_mail and reply_mail open an unsent draft in the right thread with the original quoted, and you press Send. update_mail marks read/unread, flags, moves, or trashes a whole list of messages in one approval. Listings say whether you've replied.
Contacts
a name becomes the addresses, numbers, and birthday on the card, so a reply or a text goes to a real address. An exact name ranks first, and a typo gets the closest names back.
Reminders
"remind me to call the dentist tomorrow at 9" creates a reminder that reaches your phone. List what's open or overdue, tick one off. Reminders can't be made to repeat or trigger at a place from here, and Saturn says so when you ask.
Messages
read your history, find group chats, and text someone. See below.
Shortcuts
run any shortcut you've built ("lights off", a Focus mode, a HomeKit scene). It asks first unless you allow that one shortcut by name with /policy shortcut <name>. A shortcut is a process Saturn can't see inside, so each run is recorded as untracked, and under the air-gap every shortcut asks.
the browser tab
read_browser_tab reads the front tab of the browser you used last. In Safari it reads the page text itself, with nothing fetched. In Chrome it gets the address and title unless you turn on *View › Developer › Allow JavaScript from Apple Events*. A closed browser is never launched.
Finder
finder_selection gives Saturn the files you have selected. A file outside the folders it can reach comes back with the /add-dir that would allow it.
notifications
schedule_notification hands a one-off alert to launchd, so it fires at the set time whether or not Saturn is running, and survives a reboot. /notify lists and cancels them.
::texting
"Text Sam I'm 15 minutes late": Saturn looks Sam up in Contacts and sends an iMessage through Messages. A send is the one action that always asks. You see the number, whose number it is, and the exact text every time. No setting, no always-allow, and no --yolo skips it, and headless mode refuses it outright. Every send is on the egress ledger, and the air-gap blocks it.
- –
send_messagegoes to one person (a number or address, never a bare name) or to one existing group chat, by a reference onlyfind_group_chatshands out. Saturn never creates a group. A group text's prompt lists every member and their number, and the ledger records each recipient. - –"Text Sam" means Sam alone, even when Sam is in groups. When several groups could be meant, Saturn asks which one.
- –A number or address that appears in nothing you typed and nothing a tool returned is refused before you're asked. So is a group reference the model made up.
- –A send is reported as handed to Messages, not delivered. A recipient who isn't on iMessage fails inside Messages, where Saturn can't see it.
- –
read_messagesfinds one person's messages however far back they go. A text search covers the newest 4,000 messages and says so when that isn't the whole history.
::permissions
The first time a tool reaches an app, macOS asks whether your terminal may control it: one dialog per app (Notes, Calendar, Mail, Contacts, Reminders, Messages, your browser, Finder). The dialog names the terminal app you launched Saturn from, not Saturn, and a grant made in one terminal doesn't carry over to another. If you said no, the tool tells you where to change it: *System Settings › Privacy & Security › Automation*.
full disk access for messages
Reading your Messages history means reading ~/Library/Messages/chat.db, which macOS opens only for an app with Full Disk Access. Grant it to your terminal (Terminal, iTerm, Visual Studio Code…), not to Messages, under *System Settings › Privacy & Security › Full Disk Access*, then restart the terminal. Saturn names the right app when access is missing. Sending a text and finding group chats don't need it.
notifications
The first alert appears under "Script Editor", the built-in notifier Saturn calls. Run /notify test once to grant the permission macOS asks for. notify.menubar: true (off by default) adds a menu bar icon that lists what's pending; its "Quit Saturn…" stops the agent and cancels every notification.
note
What isn't built yet, said plainly: mail is drafted, never sent; every fact Saturn learns still needs your accept; and the macOS permission dialogs name your terminal, not Saturn.