Skip to main content
ClaudeWave
Skill341 repo starsupdated today

google-calendar

The google-calendar skill uses the `gws` command-line tool to interact with Google Calendar, enabling listing of events, creation and updating of calendar entries, discovery of free time slots, and management of calendar access controls. Use it when you need to read, modify, or search a user's Google Calendar data, provided the user has authenticated with Google Workspace and granted the appropriate OAuth scopes.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/Lilac-Labs/gini-agent /tmp/google-calendar && cp -r /tmp/google-calendar/skills/google/google-calendar ~/.claude/skills/google-calendar
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Google Calendar

Use `gws calendar` to list events, create and update events, look up free/busy windows, and manage calendar ACLs. The CLI wraps the Calendar v3 API and produces structured JSON.

## Prerequisites

- `gws` installed and authenticated. If `gws` is not on PATH OR `gws auth status` reports no authenticated user, do NOT silently call setup. Instead, in a single short reply to the user:
  1. State plainly what's missing — e.g. "Google Workspace access isn't set up on this machine yet" or "your Google sign-in has expired."
  2. Ask one sentence: "Want me to walk you through setting it up?" Wait for the user's answer.
  3. If they say yes, call `read_skill` with name `google-workspace-setup` and run that skill's onboarding flow turn-by-turn. If they say no or ask to defer, acknowledge briefly and stop — do not retry the original request.
- Apply the same flow when any `gws calendar ...` call fails mid-task with `command not found` / ENOENT, HTTP 401, "no credentials", or "scope required". Don't report the failure as a dead end — surface the missing prerequisite and ask if the user wants to set it up before moving on.
- OAuth scopes the user picked at login must cover the verbs the agent will use:
  - Read-only agenda / free-busy: `calendar.readonly`
  - Create, update, delete events: `calendar.events` (or full `calendar`)
  - Manage calendar lists, ACLs, and secondary calendars: full `calendar`

## Selecting a Google account

The connected Google accounts (each with its tag, email, and config dir) are listed in your system context under **"Connected Google accounts"**. To target a specific account, prefix the command with its config dir:

```bash
GOOGLE_WORKSPACE_CLI_CONFIG_DIR="<configDir>" gws calendar events list
```

Selection rule: one account connected → just use it. Two or more:

- The user named or clearly implied one account (a tag, an email, or unambiguous context) → use only that account.
- A read/lookup/search the user didn't tie to an account (e.g. listing events, searching mail, finding a doc) → run it against **every** connected account (one `gws` call per config dir) and aggregate, labeling each result by its tag and email. Don't pick just one, and don't ask — the user wants the whole picture across accounts.
- A write (send, create, edit, delete) with no account named → ASK which account first; never guess.

If no accounts are connected yet, fall back to the setup flow in Prerequisites (`read_skill` with `google-workspace-setup`).

## When to Use

- The user asks Gini to look at, summarize, or modify their calendar.
- Scheduling a one-off meeting or a recurring event.
- Finding a free slot across the user's own calendars or comparing free/busy with another attendee.
- Adding a Google Meet link to an invite.
- Pulling today's, tomorrow's, or this-week's agenda.

## When NOT to Use

- Personal to-dos the user wants to see on their iPhone — use `apple-reminders` for time-bound to-dos, not Calendar events.
- One-off agent alerts ("ping me in an hour") — use the cronjob tool, not a self-invite.
- Cross-device personal note-taking — use `apple-notes` or `obsidian`.
- Meeting *content* (agenda doc, shared notes) — use `google-docs` for the doc and attach it to the event with a Drive link.
- Project task tracking — use the project's issue tracker; Calendar is for time-bound events, not durable to-dos.

## Quick Reference

The Calendar surface is the auto-generated v3 API (`gws calendar events list`, `gws calendar events insert`, `gws calendar freebusy query`, …) plus two curated helpers: `+agenda` for digests and `+insert` for creating events without hand-rolling the JSON body.

### Agenda

```bash
gws calendar +agenda                              # next ~7 days, all calendars
gws calendar +agenda --today
gws calendar +agenda --tomorrow
gws calendar +agenda --week --format table
gws calendar +agenda --days 14
gws calendar +agenda --today --calendar 'Work'
gws calendar +agenda --today --timezone America/New_York
```

`+agenda` is read-only and uses the user's Google account timezone by default. Override with `--timezone <IANA>` when the user is travelling.

### Create an event

```bash
gws calendar +insert \
  --summary 'Standup' \
  --start '2026-06-17T09:00:00-07:00' \
  --end   '2026-06-17T09:30:00-07:00'

# With attendees + Meet link
gws calendar +insert \
  --summary 'Design review' \
  --start '2026-06-17T14:00:00-07:00' \
  --end   '2026-06-17T15:00:00-07:00' \
  --attendee alice@example.com \
  --attendee bob@example.com \
  --meet \
  --location 'Room 4' \
  --description 'Walk through the v2 mocks.'
```

Times are RFC 3339 / ISO 8601. Always include the offset (`-07:00`, `+02:00`, `Z`) — naked local times round-trip incorrectly across DST.

For natural-language event creation, the API surface also offers `events.quickAdd`:

```bash
gws calendar events quickAdd \
  --params '{"calendarId":"primary","text":"Coffee with Pat tomorrow 3pm-3:30pm"}'
```

### List, get, update, delete events

```bash
gws calendar events list \
  --params '{"calendarId":"primary","timeMin":"2026-06-17T00:00:00Z","timeMax":"2026-06-18T00:00:00Z","singleEvents":true,"orderBy":"startTime"}'

gws calendar events get \
  --params '{"calendarId":"primary","eventId":"<EVENT_ID>"}'

gws calendar events patch \
  --params '{"calendarId":"primary","eventId":"<EVENT_ID>"}' \
  --json '{"location":"Room 5"}'

gws calendar events delete \
  --params '{"calendarId":"primary","eventId":"<EVENT_ID>"}'
```

### Respond to an invite (RSVP)

Google does not expose a dedicated RSVP method — you respond by patching the event and updating the current user's entry in the `attendees` array. That means the agent needs three things first: the `eventId`, the user's own email address (so it can find its attendee entry), and the full existing `attendees` array (so the patch can preserve everyone else).

```bash
# 1. Look up the signed-in user's email — `gws auth status` returns
#    structured JSON; the email l