-
released this
2026-08-09 16:44:19 -05:00 | 100 commits to main since this releaseEditing and deleting, addressed by an opaque handle. 0.7.0 could put things on
the calendar and never take them off again.Added
-
update_event— changes the fields it is given on one stored event and
leaves the rest alone. It mutates the stored resource rather than rebuilding
it, which is the difference between an edit and a quiet amputation: a
rebuild from the handful of fields this server models would discard the VALARM
reminders, attendees, categories and Apple X-properties it does not, and
nothing in the response would say so.Moving an event preserves its length, so a start on its own is enough. Whether
an event is all-day is read from the stored event, never from the shape of the
argument — converting a day off into a 30-minute appointment because a caller
passed a time is not a thing a caller should be able to do by accident. -
delete_event, which requiresexpected_titleand refuses on a mismatch.
It costs one argument the caller already has, and it converts the failure that
cannot be undone — two ids transposed out of one response — into a refusal
that names both titles. The response carries the whole deleted event, since
that is the only remaining record of what was there. -
event_id, an opaque handle on every addressable event. Not the resource
URL, which carries the account DSID and must never reach the model; not the
uid, which every occurrence of a series shares; and not(calendar, uid)as
two arguments, which lets a model pair the right uid with the wrong calendar
or assemble one from parts it half-remembers. One string, produced by a read,
passed back verbatim.Its absence is the signal. No
event_idmeans nothing here can be edited
or deleted: repeating events, subscriptions, and everything on a calendar that
is readable but not writable. WithWRITABLE_CALENDARSunset no event carries
one at all, so the read surface still matches the read-only releases exactly.Deliberately unsigned. The write allowlist is checked against the calendar
named inside the handle before iCloud is contacted, so forging one buys
access to exactly the calendars the operator already opted in to. Signing
would add a key with theMCP_OAUTH_SIGNING_KEYfailure mode — rotate it and
every handle issued earlier in a conversation stops resolving, which reads as
the events having vanished.
Changed
-
Every error envelope out of a write tool now states
created,updatedor
deletedasfalse. They were present on the failures raised from the
client and absent on the ones caught during argument validation. A missing key
is not the same signal as a false one, and the gap was on exactly the paths
where the model has the least other evidence. -
The server instructions name the new capabilities and their limits together,
because stating the capability alone invites the model to offer the rest.
Security
-
Repeating events are refused, and the refusal is checked against the stored
resource rather than against anything a read inferred. ARECURRENCE-ID
override carries no RRULE of its own, so a moved instance of a weekly meeting
reads as a one-off — and editing it by UID resolves to the resource holding
the whole series. Deleting is the same story with a worse ending: one DELETE
against a series master removes every occurrence, past and future, and returns
the same 204 as removing a single event. -
A concurrent edit is refused, not overwritten. caldav sends
If-Match
from the ETag of an object it loaded, so an event changed on a phone between
the read and the write comes back 412 and is left alone. -
Upgrading grants deletion to anyone who had
WRITABLE_CALENDARSset for
0.7.0, with no configuration change. This is the roadmap's shared gate
working as agreed, and it is worth saying out loud: the opt-in that previously
meant "may add events" now also means "may remove them". Clearing the variable
is still the off switch.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-