calendar
CalDAV calendar access as a capability — list and inspect events, create, update, or delete them through an approval ladder, with an append-only audit trail. Works with Google, iCloud, Fastmail, and Nextcloud.
What the agent can do
- Read — list events in a time range, and fetch one by id.
- Write — create, update, and delete events, gated by
write_mode. - Audit — every write is appended to a changelog the agent can review, with before/after snapshots.
Connecting a calendar
Two paths, depending on the provider. Google uses OAuth; everything else uses CalDAV with an app-specific password.
- Create a Google Cloud project with the Calendar API enabled.
- Create an OAuth 2.0 Web-application client; register the redirect URI the admin shows you.
- Paste the Client ID and Secret into the admin, then run the consent flow.
- The flow writes the refresh token and account email into
secrets.jsonfor you.
secrets.json
{
"PROVIDER": "google",
"GOOGLE_CLIENT_ID": "...",
"GOOGLE_CLIENT_SECRET": "...",
"GOOGLE_REFRESH_TOKEN": "...",
"GOOGLE_EMAIL": "you@gmail.com"
}For iCloud, Fastmail, or Nextcloud: the server URL, your username, and an app-specific password.
secrets.json
{
"PROVIDER": "caldav",
"CALDAV_URL": "https://caldav.icloud.com",
"CALDAV_USERNAME": "you@icloud.com",
"CALDAV_PASSWORD": "app-specific-password"
}Configuration
capabilities.json
{
"extensions": {
"calendar": {
"enabled": true,
"write_mode": "approval",
"calendars": ["Work"]
}
}
}| Field | Type | Default | Effect |
|---|---|---|---|
| write_mode | disabled | approval | personal | full | disabled | Approval ladder for create / update / delete. Reads never prompt. |
| calendars | string[] | [] | Calendar display names to operate on, resolved over CalDAV. |
| calendar_urls | string[] | [] | Pre-resolved CalDAV URLs — required for Google, and takes priority over names. |
The read window is set by view_past (default 30d) and view_future (default 365d), as durations like 7d or 3m.
The write ladder has four rungs:
| Mode | Behavior |
|---|---|
| disabled | Write tools aren't registered — read-only. |
| approval | Every write prompts for approval. |
| personal | Personal writes run without prompting; writes with attendees still prompt, since attendees trigger real invitations. |
| full | All writes run without prompting. |
Tools
calendar__list(after?, before?)
List calendar events in a time range, sorted by start time.
Parameters
- optional
after[ISO date]Only events after this timestamp. - optional
before[ISO date]Only events before this timestamp.
Returns
UID: UID Title: TITLE Time: START — END Location: LOCATION Description: DESCRIPTION Attendees: EMAIL, EMAIL, … Recurrence: RECURRENCE Status: STATUS
No events found.
Calendar error: ERROR
calendar__get(uid)
Retrieve a single calendar event by UID with full details.
Parameters
uid[string]Event UID.
Returns
UID: UID Title: TITLE Time: START — END …
Event not found.
Calendar error: ERROR
calendar__changes(limit?)
List recent calendar changes (create, update, delete) from the audit log.
Parameters
- optional
limit[integer, default 50]Max entries to return.
Returns
[ISO_TIMESTAMP] CREATE — UID After: TITLE (START) [ISO_TIMESTAMP] UPDATE — UID Before: TITLE (START) After: TITLE (START)
No changes recorded.
Calendar error: ERROR
calendar__create(title, start, end, allDay?, location?, description?, attendees?)
Create a calendar event. Approval/auto-execution depends on write_mode.
Parameters
title[string]Event title.start[ISO datetime or YYYY-MM-DD]Start time. Use date-only for all-day events.end[ISO datetime or YYYY-MM-DD]End time. Use date-only for all-day events.- optional
allDay[boolean, default false]Mark as an all-day event. - optional
location[string]Event location. - optional
description[string]Event description. - optional
attendees[string[]]Attendee email addresses. In personal mode, presence of attendees forces an approval prompt.
Returns
Created: TITLE (START — END) UID: UID
Missing required arguments: title, start, end
Calendar error: ERROR
calendar__update(uid, title?, start?, end?, allDay?, location?, description?, attendees?)
Update a calendar event by UID. Only specified fields are changed.
Parameters
uid[string]Event UID.- optional
title[string]New title. - optional
start[ISO datetime or YYYY-MM-DD]New start. - optional
end[ISO datetime or YYYY-MM-DD]New end. - optional
allDay[boolean]Mark as all-day. - optional
location[string]New location. - optional
description[string]New description. - optional
attendees[string[]]Replaces the existing attendee list.
Returns
Updated: TITLE (START — END)
Missing required argument: uid
Calendar error: ERROR
calendar__delete(uid)
Delete a calendar event by UID.
Parameters
uid[string]Event UID.
Returns
Deleted event: UID
Missing required argument: uid
Calendar error: ERROR
Notes & gotchas
write_mode at disabled and step up to approval when the agent is actively scheduling. Reserve personal and full for when you mean it — full sends meeting invitations without asking.