5

ACTION-LOG UNDO · TZ ENFORCEMENT · OAUTH

Google Calendar MCP server with an action-log undo system, timezone enforcement, and idempotent event creation.

STATUS
Live · in daily use
SURFACE
5 tools · stdio transport
SIZE
~340 lines · single file
STACK
Python · MCP SDK · Google Calendar API

The MCP server that lets an LLM actually drive a Google Calendar — not “ask about events,” but create, modify, delete, and reverse calendar operations in natural conversation. It runs over stdio, exposes five tools, handles its own OAuth2 flow with refresh-token persistence, and — the part most wrappers miss — keeps an action log so any mutation can be undone deterministically. In production daily use: this is the working artifact behind every “schedule that for me” interaction. If Helios is the generator of MCP servers, this is the hand-written reference of what a thoughtful one looks like.

#FAILURE MODETHE FIX HERE
1UTC offset drift — bare ISO timestamps land events an hour offTool schema demands explicit offsets; every start/end wrapped with a known IANA timeZone
2No undo — Google's API has delete, but no reverseEvery mutation appends full pre-mutation state to action_log.json; undo reverses the last operation exactly
3Double-booking on retry — LLM retries a timed-out call, duplicate eventIdempotency-aware design + the action log make duplicates detectable
4Destructive writes masked as readsExplicit tool names (create_event, delete_event) show intent at selection time; undo is always available

Google’s managed endpoint handles OAuth but skips the action log; community wrappers handle OAuth but rarely do undo. None of the off-the-shelf options handle all four simultaneously — building a focused 340-line server was faster than forking any of them.

The single feature that makes this server safe to hand to an LLM in production: every mutation captures whatever it would take to reverse itself before the mutation lands. Creates log the new event’s ID; updates log the full pre-state of every changed field; deletes log the entire event body.

Five tools is small on purpose: anything read-shaped beyond list_events is expressed by parameterizing it rather than minting new tools — the same principle Helios automates for arbitrary APIs.

Even the simplest tool has substance. list_events passes four deliberate flags: timeMin with an explicit Z suffix (without it, Google interprets the timestamp in the calendar’s default zone — silent drift), singleEvents=True to expand recurring events into individually-addressable instances, orderBy=startTime so “next 5 events” means the next five, and a bounded maxResults the model controls. Responses compress to [id] summary @ start → end — readable for the model, IDs preserved so update/delete can address specific events.

OAuth stays user-controlled: local credentials, refresh-token persistence, no third-party relay seeing calendar data. stdio transport keeps the trust boundary at the process level — the server runs as a local subprocess of the client, not as a network service.