name: apple-pim description: Native macOS personal information management for calendars, reminders, contacts, and local Mail.app. Use when the user wants to schedule meetings, create events, check their calendar, create or complete reminders, look up contacts, find someone's phone number or email, manage tasks and to-do lists, triage local Mail.app messages, or troubleshoot EventKit, Contacts, or Mail.app permissions on macOS.
Apple PIM (EventKit, Contacts & Mail)
Requirements
- macOS only. Requires Apple frameworks (EventKit, Contacts, Mail.app) — does not run on Linux or Windows.
- Native CLIs:
calendar-cli,reminder-cli,contacts-cli,mail-cli. Build locally from source via./setup.sh(Swift toolchain required); installs to~/.local/bin/. Authoritative declaration is in the plugin manifest underrequires.binariesandplatforms. - TCC permissions for Calendars, Reminders, Contacts (via Privacy & Security). Mail features additionally require Mail.app running and Automation permission granted to your terminal/IDE.
Overview
Apple provides frameworks and scripting interfaces for personal information management:
- EventKit: Calendars and Reminders
- Contacts: Address book management
- Mail.app: Local email via JXA (JavaScript for Automation)
EventKit and Contacts require explicit user permission via privacy prompts. Mail.app requires Automation permission and must be running.
Tools
This plugin provides 5 tools:
| Tool | Actions | Domain |
|---|---|---|
apple_pim_calendar |
list, events, get, search, create, update, delete, batch_create |
Calendar events via EventKit |
apple_pim_reminder |
lists, items, get, search, create, complete, update, delete, batch_create, batch_complete, batch_delete |
Reminders via EventKit |
apple_pim_contact |
groups, list, search, get, create, update, delete |
Contacts framework |
apple_pim_mail |
accounts, mailboxes, messages, get, search, send, reply, update, move, delete, batch_update, batch_delete, auth_check |
Mail.app via JXA/AppleScript |
apple_pim_system |
status, authorize, config_show, config_init |
Authorization & configuration |
Authorization & Permissions
Permission Model
Each PIM domain requires separate macOS authorization:
| Domain | Framework | Permission Section |
|---|---|---|
| Calendars | EventKit | Privacy & Security > Calendars |
| Reminders | EventKit | Privacy & Security > Reminders |
| Contacts | Contacts | Privacy & Security > Contacts |
| Automation (JXA) | Privacy & Security > Automation |
Authorization States
| State | Meaning | Action |
|---|---|---|
notDetermined |
Never requested | Use apple_pim_system with action authorize to trigger prompt |
authorized |
Full access granted | Ready to use |
denied |
User refused access | Must enable in System Settings manually |
restricted |
System policy (MDM, parental) | Cannot override |
writeOnly |
Limited write access (macOS 17+) | Upgrade to Full Access in Settings |
Configuration (PIMConfig)
The PIM CLIs share a configuration system for filtering calendars/reminder lists and setting defaults.
Config File Locations
| Path | Purpose |
|---|---|
~/.config/apple-pim/config.json |
Base configuration |
~/.config/apple-pim/profiles/{name}.json |
Named profile overrides |
Example Config
{
"calendars": {
"enabled": true,
"mode": "blocklist",
"items": ["US Holidays", "Birthdays"],
"default": "Personal"
},
"reminders": {
"enabled": true,
"mode": "allowlist",
"items": ["Tasks", "Shopping", "Work"],
"default": "Tasks"
},
"contacts": { "enabled": true },
"mail": { "enabled": true }
}
Filter Modes
| Mode | Behavior |
|---|---|
all |
No filtering — all calendars/lists are visible (default) |
allowlist |
Only calendars/lists named in items are visible |
blocklist |
All calendars/lists are visible EXCEPT those named in items |
Multi-Agent Isolation
All 5 tools accept optional configDir and profile parameters for per-call workspace isolation:
apple_pim_calendar({ action: "list", configDir: "~/agents/travel/apple-pim" })
apple_pim_calendar({ action: "list", profile: "work" })
In OpenClaw multi-agent setups (v3.1.0+), config is auto-discovered from {workspaceDir}/apple-pim/config.json — no explicit configDir or wrapper scripts needed.
Priority chain: Tool parameter > workspace convention > plugin config > env var > default (~/.config/apple-pim/)
Trusted Senders (auth_check)
The auth_check action verifies sender identity by parsing Authentication-Results headers (DKIM + SPF) against a trusted senders config.
Config file: ~/.config/apple-pim/trusted-senders.json
{
"version": 1,
"trustedSenders": [
{
"name": "Alice",
"emails": ["alice@example.com"],
"expectedDkimDomains": ["example.com"],
"requireDkim": true,
"requireSpf": true
}
]
}
Override path with trustedSenders parameter: apple_pim_mail({ action: "auth_check", id: "<msg-id>", trustedSenders: "~/custom/senders.json" })
Best Practices
Calendar Management
- Use default calendar for new events when user doesn't specify
- Preserve recurrence rules when updating recurring events
- Handle
.thisEventvs.futureEventsspan for recurring event edits - Use
batch_createwhen creating multiple events for efficiency
EKSpan for Recurring Events
| Span | Effect | When to Use |
|---|---|---|
.thisEvent |
Affects only the single occurrence | Default for delete and update |
.futureEvents |
Affects this and all future occurrences | Use when ending a series |
- Delete: Default is
.thisEvent. PassfutureEvents: trueto use.futureEvents. - Update: Default is
.thisEvent. PassfutureEvents: trueto apply to future occurrences. - Remove recurrence: Pass
recurrence: { frequency: "none" }withfutureEvents: true.
Reminder Management
- Default to incomplete reminders when listing
- Use filters:
overduefor urgent,todayfor daily planning,weekfor review - Use batch operations (
batch_complete,batch_delete) for multiple items
Contact Management
- Preserve existing data when updating (only modify changed fields)
- Handle labeled values carefully — don't lose non-primary entries
Mail Management
- Mail.app must be running for all operations
- Use batch operations (
batch_update,batch_delete) for inbox triage - Message IDs are RFC 2822 — stable across mailbox moves
- Use mailbox/account hints for faster lookups
- Send uses AppleScript — supports
to,cc,bcc,from(account selection),subject,body - Reply preserves threading — looks up message by RFC 2822 ID, then uses Mail.app's
replyverb - Auth check verifies DKIM/SPF against
~/.config/apple-pim/trusted-senders.json— returnsverified,suspicious,untrusted, orunknown
Attachment Policy (Send / Reply)
File attachments are disabled by default to prevent local-file exfiltration via prompt-injection. Any attachment argument passed to send or reply will be rejected unless the user has opted in.
To enable, create ~/.config/apple-pim/mail-attachments.json:
{
"enabled": true,
"allowedRoots": ["~/Downloads", "~/Documents/agent-attachments"]
}
Even when enabled, the following are always refused:
- Path components matching
.ssh,.aws,.gnupg,.kube,.docker,.secrets,Keychains - Filenames
id_rsa,id_ed25519,.netrc,.pgpass,.env,authorized_keys, etc. - Filenames matching
*.pem,*.key,*.p12,*.pfx, or containingsecret,password,credential,token
Paths are normalized via realpath before checking, so symlinks and .. traversal can't escape the allowlist. Override the policy file location with APPLE_PIM_MAIL_ATTACHMENTS_CONFIG.
Error Handling
- Check authorization first with
apple_pim_systemactionstatus - Use
apple_pim_systemactionauthorizefornotDetermineddomains - Guide users to System Settings for
denieddomains
Troubleshooting
Permission Issues
- Use
apple_pim_systemwith actionstatusto check all domains - Use
apple_pim_systemwith actionauthorizeto trigger prompts - Check System Settings > Privacy & Security
Binary Not Found
- Run
./setup.sh --installto build and install CLIs to~/.local/bin/ - Or set
binDirin plugin config to point to your build directory
Configuration Issues
- Unexpected filtering: Use
apple_pim_systemactionconfig_showto verify active config - Missing calendars/lists: Use
apple_pim_systemactionconfig_initto discover available items