CLI for Google Calendar API - sync calendars locally, list/create/update/delete events, RSVP. Supports multiple accounts.
- Sync calendars and events locally as JSON for offline access
- Search with DuckDB across all your events instantly
- Multi-account support with easy switching
- CRUD - create, read, update, delete events
- RSVP - respond to event invitations
- Rate limit handling - auto-retry with exponential backoff
- Resumable sync - interrupted syncs continue where they left off
npm install -g @rusintez/gcal
# Requires duckdb for queries
brew install duckdb- Go to Google Cloud Console
- Create a new project (or select existing)
- Go to APIs & Services → Enable APIs → Search "Google Calendar API" → Enable
- Go to APIs & Services → OAuth consent screen:
- Select "External" user type
- Fill in app name, support email
- Add your email as test user (while in testing mode)
- Go to APIs & Services → Credentials:
- Click Create Credentials → OAuth 2.0 Client ID
- Application type: Desktop app
- Copy the Client ID and Client Secret
gcal auth setup <client-id> <client-secret>
gcal auth login # Opens browser for OAuth consentgcal auth login # Repeat for each account
gcal auth list # List all accounts
gcal auth default user@gmail.com # Set defaultNote: While your OAuth app is in "Testing" mode, only emails added as test users can authenticate.
gcal sync # Incremental sync (recent events)
gcal sync --full # Full sync (all events)
gcal sync -a user@gmail.com # Sync specific accountSync is resumable - if interrupted, it continues where it left off.
Data is stored at ~/.local/share/gcal/{account}/
gcal events # Upcoming events
gcal events --today # Today's events
gcal events --week # This week's events
gcal events -n 50 # Limit results
gcal events -c "Work" # Events from specific calendargcal event <id> # Full event detailsgcal create --title "Meeting" --start "2024-03-15T10:00:00" --end "2024-03-15T11:00:00"
gcal create --title "Lunch" --start "2024-03-15T12:00:00" --duration 1h
gcal create --title "Team Sync" --start "2024-03-15T14:00:00" --attendees "a@x.com,b@x.com"
gcal create --title "Weekly" --start "2024-03-15T09:00:00" --recurrence "RRULE:FREQ=WEEKLY"gcal update <id> --title "New Title"
gcal update <id> --start "2024-03-15T11:00:00"
gcal update <id> --attendees "a@x.com,b@x.com"gcal delete <id> # Delete event
gcal delete <id> --notify # Delete and notify attendeesgcal rsvp <id> --accept # Accept invitation
gcal rsvp <id> --decline # Decline invitation
gcal rsvp <id> --tentative # Mark as tentativegcal calendars # List all calendarsgcal sync-status # List synced accounts
gcal sync-status user@gmail.com # Status for specific account
gcal sync-reset user@gmail.com # Reset state (next sync = full)After syncing, query your calendar data with SQL:
cd ~/.local/share/gcal/user_at_gmail_com
duckdb-- Upcoming events this week
SELECT summary, start.dateTime, end.dateTime
FROM read_json_auto('events/*.json')
WHERE start.dateTime >= current_date
AND start.dateTime < current_date + INTERVAL 7 DAY
ORDER BY start.dateTime;
-- Events by calendar
SELECT calendarId, count(*) as count
FROM read_json_auto('events/*.json')
GROUP BY 1 ORDER BY 2 DESC;
-- Events with attendees
SELECT summary, start.dateTime, len(attendees) as attendee_count
FROM read_json_auto('events/*.json')
WHERE attendees IS NOT NULL
ORDER BY attendee_count DESC LIMIT 10;
-- Recurring events
SELECT summary, recurrence
FROM read_json_auto('events/*.json')
WHERE recurrence IS NOT NULL;See schema.md for full data schema and more query examples.
gcal events # Markdown table (default)
gcal events -f json # JSON - for scripting
gcal events -f minimal # Tab-separatedgcal -a work@company.com events # Use specific account
gcal -a personal@gmail.com calendars- Config:
~/.config/gcal-cli/config.json - Synced data:
~/.local/share/gcal/ - Schema: schema.md
MIT