Generates Google Calendar‑compatible .ics files from structured event data.
--- name: ics-generator description: Generates Google Calendar‑compatible .ics files from structured event data. --- # ics‑generator ## When to use When you need to convert a schedule, study plan, or task list into an **iCalendar (.ics)** file that can be imported into Google Calendar or any other iCalendar‑compatible client. ## Workflow Overview 1. **Collect structured events** – each event must contain: - `summary` (string) - `description` (string, optional) - `start` (ISO‑8601 date/time or JS `Date`) - `end` (ISO‑8601 date/time or JS `Date`) - `colorId` (Google Calendar colour ID, optional) 2. **Chunking / sequential dates** - **First chunk** – supply the intended start date (e.g., `2026‑05‑31T09:00:00Z`). - **Subsequent chunks** – pass the **last date of the previous chunk** (via the `lastDate` field). The skill will automatically shift the next chunk’s start date forward by one day, guaranteeing a clean “one‑day‑gap” between chunks. 3. **Run the skill** – invoke the `run` function exported by `index.js` with the event array and optional `lastDate`. ## Implementation Notes | Feature | Details | |---------|---------| | **Google‑Calendar compatibility** | Automatically injects the required headers:<br>`PRODID:-//Google Inc//Google Calendar 70.6//EN` <br>`CALSCALE:GREGORIAN` | | **UTC enforcement** | All start/end times are normalized to **UTC** and formatted as `YYYYMMDDTHHMMSSZ`. Google Calendar accepts this exact format without further conversion. | | **Unique identifiers** | Each event receives a UUID‑v4‑derived UID (`event-<uuid>`) so calendar clients can correctly sync updates. | | **Color handling** | If a `colorId` is supplied, it’s added as `X‑GOOGLE‑CALENDAR‑COLOR:<id>` inside the VEVENT block. | | **Output** | Returns a complete `.ics` string wrapped in `BEGIN:VCALENDAR … END:VCALENDAR`. Every `VEVENT` ends with `END:VEVENT` and the final block ends with `END:VCALENDAR`. | | **Dependencies** | Node ≥ 20 (for `crypto.randomUUID()`). No external npm packages—pure JavaScript plus Node’s built‑in `crypto` module. | | **License** | MIT – free to copy, modify, and share. | ### Why the specific `PRODID` / `CALSCALE`? From community feedback, Google Calendar only imported the generated file **when** those exact values were present. A generic `PRODID` caused the “Unable to launch event” error; `CALSCALE:GREGORIAN` tells Google Calendar which calendar system to assume (Gregorian), which is required for proper time‑zone handling.
don't have the plugin yet? install it then click "run inline in claude" again.
added explicit inputs section with runtime requirements, broke workflow into numbered procedure steps with input/output contracts, extracted decision logic into dedicated section covering empty arrays, missing fields, parsing errors, invalid colorId, and sequential batching, formalized output contract with file format and HTTP headers, and defined outcome signal with import validation and timestamp verification.
converts structured event data into RFC 5545-compliant iCalendar (.ics) files that import cleanly into Google Calendar, Outlook, Apple Calendar, or any iCalendar client. use this when you have a schedule, study plan, task list, or event array that needs calendar portability without manual entry or third-party sync services.
event array (required)
summary (string): event title, requireddescription (string): event details, optionalstart (ISO-8601 string or JavaScript Date): event start time, required, will be normalized to UTCend (ISO-8601 string or JavaScript Date): event end time, required, will be normalized to UTCcolorId (string): Google Calendar color ID (1-11), optional, ignored by non-Google clientslastDate (optional)
environment / runtime
crypto.randomUUID())crypto modulevalidate input array
summary (string) and start/end (ISO-8601 or Date)normalize timestamps to UTC
start and end fieldsYYYYMMDDTHHMMSSZ (RFC 5545 UTC format, Z suffix required)start and end strings for each eventapply lastDate offset (if supplied)
lastDate parameter, normalized start/end times from step 2lastDate is provided: calculate offset as the number of days between lastDate and the first event's start; add that offset (in seconds) to all event start and end times in the batchlastDate is not provided: skip this stepgenerate unique identifiers
crypto.randomUUID()event-<uuid>@calendar.local (ensures globally unique UID per RFC 5545)build VCALENDAR header
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Google Inc//Google Calendar 70.6//EN
CALSCALE:GREGORIAN
build each VEVENT block
BEGIN:VEVENT
UID:<generated-UID>
SUMMARY:<summary-text>
DTSTART:<normalized-UTC-start>
DTEND:<normalized-UTC-end>
[DESCRIPTION:<description-text>]
[X-GOOGLE-CALENDAR-COLOR:<colorId>]
END:VEVENT
build VCALENDAR footer
END:VCALENDARconcatenate and return
\n, not CRLF)text/calendar; charset=utf-8if event array is empty:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Google Inc//Google Calendar 70.6//EN
CALSCALE:GREGORIAN
END:VCALENDAR
if required field (summary, start, end) is missing or null:
if start/end timestamp cannot be parsed (malformed ISO-8601 or invalid Date):
if start time is after end time:
if lastDate is supplied:
if colorId is supplied but is not a valid Google Calendar color ID (1-11):
if the event array is very large (10,000+ events):
success output: .ics file content
\n)BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Google Inc//Google Calendar 70.6//EN
CALSCALE:GREGORIAN
END:VCALENDAR
how to write to disk
fs.writeFileSync(filename, icsContent, 'utf8') or equivalentevents-<YYYYMMDD>.ics or similarhow to serve over HTTP
Content-Type: text/calendar; charset=utf-8Content-Disposition: attachment; filename="events.ics"validation notes
the skill worked if:
BEGIN:VCALENDAR and END:VCALENDARBEGIN:VEVENT … END:VEVENT blockYYYYMMDDTHHMMSSZ (UTC).ics file without error.ics file imports into Google Calendar, Outlook, Apple Calendar, or equivalent without error messages like "Unable to launch event" or "Invalid calendar data"lastDate was supplied, the first event of the new batch starts exactly one day after the lastDate valuethe skill failed if:
BEGIN:VCALENDAR or END:VCALENDAR