# GCal CLI

Calendars, events, freebusy, and slots from the terminal.

## Install

```bash
cmdhub get gcal
```

## Authentication

OAuth2

## Agent-Readable Catalog

- Machine-readable command catalog: `/cli/gcal/catalog.json`
- Stable command anchors use the `cmd-...` IDs listed under each command.
- Inspect this catalog before planning tool use for command paths, examples, flags, mutation markers, and dry-run support.

## Overview

```bash
# Turn a transformed email into a calendar event
gmail message list --label INBOX --limit 1 --jsonl \
  | agent adapt --to "gcal event create"
```

## CLI Overview

Google Calendar adapter CLI

Work with Google Calendar calendars, events, free/busy windows, and open slots.

The intended workflow is:
- list calendars or events first
- follow up with a short ref such as c1 or e1, or pipe jsonl into the next command
- use resolve when you need to inspect what a short ref expands to

Use --jsonl for self-pipe flows such as:
  gcal event list --today --jsonl | gcal event get
  gcal event search --query dentist --jsonl | gcal event delete

## Generated Coverage

- Command groups: `14`
- Total documented command nodes: `37`
- Live examples: `5`
- Lifecycle surfaces: `auth`, `doctor`, `capabilities`, `schema`, `resolve`, `version`
- Machine-readable output: `--json`, `--jsonl`
- Human views: `summary`, `full`

## Auth Contract

- Auth mode: OAuth2
- Provider permission model: Google OAuth
- Auth scopes: `openid`, `email`, `profile`, `https://www.googleapis.com/auth/calendar`
- Scope note: Used for calendars, events, and availability.
- Standard commands: `auth login`, `auth logout`, `auth refresh`, `auth status`, `auth whoami`
- `auth status --json` reports `tool`, `profile`, `provider`, `authenticated`, and `suggested_next_step`.
- `auth whoami --json` is the stable way to answer identity questions.

## Agent Safety Notes

- Discovery commands such as `list`, `search`, `get`, `resolve`, `schema`, `doctor`, `capabilities`, `status`, and `whoami` are the safest commands to run first.
- Treat commands marked as mutating as state-changing local or provider operations.
- Mutating command paths: `gcal auth login`, `gcal auth logout`, `gcal auth refresh`, `gcal event create`, `gcal event delete`, `gcal event quick-add`, `gcal event update`, `gcal login`, `gcal logout`, `gcal profile create`, `gcal profile delete`, `gcal profile use`
- No generated `--dry-run` flag was detected for this CLI. Use discovery commands before mutating commands.

## Global Flags

- `--json` (bool): Emit JSON machine output
- `--jsonl` (bool): Emit JSONL records for piping
- `--output` (string): Compatibility output mode: json|jsonl. Prefer --json or --jsonl
- `--view` (string): View mode: summary|full Default: `summary`.
- `--profile` (string): Config/auth profile Default: `default`.
- `--config` (string): Config path override
- `--quiet` (bool): Suppress non-essential diagnostics
- `--debug` (bool): Enable debug diagnostics
- `--limit` (int): Maximum items to emit Default: `50`.
- `--page-size` (int): Requested upstream page size Default: `50`.
- `--cursor` (string): Continuation cursor
- `--no-paginate` (bool): Fetch only one page
- `--version` (bool): Print version information

## Command Reference

### `gcal auth`

- Anchor: `cmd-gcal-auth`
- Mutates state: `no`
- Supports dry run: `no`

Manage Google Calendar authentication

#### `gcal auth login`

- Anchor: `cmd-gcal-auth-login`
- Mutates state: `yes`
- Supports dry run: `no`

Authenticate with Google Calendar

Example:

```bash
gcal auth login
gcal auth login --help
gcal auth status
```

#### `gcal auth logout`

- Anchor: `cmd-gcal-auth-logout`
- Mutates state: `yes`
- Supports dry run: `no`

Remove stored credentials

Example:

```bash
gcal auth login
gcal auth logout
gcal auth logout --help
```

#### `gcal auth refresh`

- Anchor: `cmd-gcal-auth-refresh`
- Mutates state: `yes`
- Supports dry run: `no`

Refresh stored token

Example:

```bash
gcal auth refresh
gcal auth refresh --help
gcal auth status
```

#### `gcal auth status`

- Anchor: `cmd-gcal-auth-status`
- Mutates state: `no`
- Supports dry run: `no`

Show auth status

Example:

```bash
gcal auth status
gcal auth status --help
gcal auth status --view full
```

#### `gcal auth whoami`

- Anchor: `cmd-gcal-auth-whoami`
- Mutates state: `no`
- Supports dry run: `no`

Show current calendar identity

Example:

```bash
gcal auth whoami
gcal auth whoami --help
gcal auth whoami --json
```

### `gcal calendar`

- Anchor: `cmd-gcal-calendar`
- Mutates state: `no`
- Supports dry run: `no`

Manage calendars

#### `gcal calendar get`

- Anchor: `cmd-gcal-calendar-get`
- Mutates state: `no`
- Supports dry run: `no`

Get a calendar

Example:

```bash
gcal calendar get
gcal calendar get c1
gcal calendar get c1 c2
gcal calendar get primary --view full
gcal calendar list --jsonl | gcal calendar get
```

#### `gcal calendar list`

- Anchor: `cmd-gcal-calendar-list`
- Mutates state: `no`
- Supports dry run: `no`

List calendars

Example:

```bash
gcal calendar list
gcal calendar list --jsonl | gcal calendar get
gcal calendar list --view full
```

#### `gcal calendar search`

- Anchor: `cmd-gcal-calendar-search`
- Mutates state: `no`
- Supports dry run: `no`

Search calendars by summary

Example:

```bash
gcal calendar search
gcal calendar search --query holidays
gcal calendar search --query work --view full
```

Flags:

- `--query` (string): Search text

### `gcal capabilities`

- Anchor: `cmd-gcal-capabilities`
- Mutates state: `no`
- Supports dry run: `no`

Describe capabilities

Example:

```bash
gcal capabilities --help
```

### `gcal config`

- Anchor: `cmd-gcal-config`
- Mutates state: `no`
- Supports dry run: `no`

Inspect local configuration

#### `gcal config explain`

- Anchor: `cmd-gcal-config-explain`
- Mutates state: `no`
- Supports dry run: `no`

Explain resolved configuration

Example:

```bash
gcal config explain --help
```

### `gcal doctor`

- Anchor: `cmd-gcal-doctor`
- Mutates state: `no`
- Supports dry run: `no`

Run gcal diagnostics

Example:

```bash
gcal doctor
gcal doctor --help
gcal doctor --view full
```

### `gcal event`

- Anchor: `cmd-gcal-event`
- Mutates state: `no`
- Supports dry run: `no`

Manage calendar events

#### `gcal event create`

- Anchor: `cmd-gcal-event-create`
- Mutates state: `yes`
- Supports dry run: `no`

Create an event

Example:

```bash
gcal event create --calendar c1 --title "Planning" --start +1h --end +2h --location "Room 4"
gcal event create --help
gcal event create --title "Company holiday" --start 2026-05-01 --all-day
gcal event create --title "Project review" --start "tomorrow 14:00" --duration 45m
gcal event create --title "Review" --start "tomorrow 14:00" --duration 45m --attendee alex@example.com --send-updates none
```

Flags:

- `--all-day` (bool): All-day event
- `--attendee` (stringArray): Attendee email; repeatable
- `--calendar` (string): Calendar selector Default: `primary`.
- `--description` (string): Description
- `--duration` (string): Duration
- `--end` (string): Event end
- `--location` (string): Location
- `--optional-attendee` (stringArray): Optional attendee email; repeatable
- `--resource` (stringArray): Room/resource attendee email; repeatable
- `--send-updates` (string): Guest notification policy: all, externalOnly, or none
- `--start` (string): Event start
- `--title` (string): Event title
- `--yes` (bool): Accepted for compatibility; this command is already non-interactive

#### `gcal event delete`

- Anchor: `cmd-gcal-event-delete`
- Mutates state: `yes`
- Supports dry run: `no`

Delete an event

Example:

```bash
gcal event delete --all --yes e1 e2
gcal event delete --help
gcal event delete e1 --yes
gcal event search --query cmdhub-human-audit --jsonl | gcal event delete --all --yes
```

Flags:

- `--all` (bool): Confirm batch event delete
- `--calendar` (string): Optional calendar selector
- `--yes` (bool): Confirm destructive event delete

#### `gcal event get`

- Anchor: `cmd-gcal-event-get`
- Mutates state: `no`
- Supports dry run: `no`

Get an event

Example:

```bash
gcal event get
gcal event get e1
gcal event get e1 --view full
gcal event get e1 e2
gcal event list --today --jsonl | gcal event get
```

Flags:

- `--calendar` (string): Optional calendar selector

#### `gcal event list`

- Anchor: `cmd-gcal-event-list`
- Mutates state: `no`
- Supports dry run: `no`

List events

List events in a time window. Relative --from and --to values such as +8h and +9h are both relative to now.

Example:

```bash
gcal event list
gcal event list --calendar c1 --from now --to +72h
gcal event list --from +8h --to +9h
gcal event list --today
gcal event list --week --view full
```

Flags:

- `--calendar` (string): Calendar selector Default: `primary`.
- `--from` (string): Start time
- `--to` (string): End time
- `--today` (bool): Today window
- `--tomorrow` (bool): Tomorrow window
- `--week` (bool): Week window

#### `gcal event quick-add`

- Anchor: `cmd-gcal-event-quick-add`
- Mutates state: `yes`
- Supports dry run: `no`

Create an event from natural text

Example:

```bash
gcal event quick-add --calendar c1 --text "Planning review today 3pm"
gcal event quick-add --help
gcal event quick-add --text "Lunch with Sam tomorrow 12pm"
```

Flags:

- `--calendar` (string): Calendar selector Default: `primary`.
- `--send-updates` (string): Guest notification policy: all, externalOnly, or none
- `--text` (string): Quick-add text
- `--yes` (bool): Accepted for compatibility; this command is already non-interactive

#### `gcal event search`

- Anchor: `cmd-gcal-event-search`
- Mutates state: `no`
- Supports dry run: `no`

Search events

Search events in a time window. Relative --from and --to values such as +8h and +9h are both relative to now.

Example:

```bash
gcal event search
gcal event search --query "project review" --from today --to tomorrow
gcal event search --query audit --jsonl | gcal event get
gcal event search --query dentist
gcal event search --query review --from +8h --to +9h
```

Flags:

- `--calendar` (string): Calendar selector Default: `primary`.
- `--from` (string): Start time
- `--query` (string): Search query
- `--to` (string): End time

#### `gcal event update`

- Anchor: `cmd-gcal-event-update`
- Mutates state: `yes`
- Supports dry run: `no`

Update an event

Example:

```bash
gcal event search --query review --jsonl | gcal event update --location "Room 4"
gcal event update --help
gcal event update e1 --add-attendee alex@example.com --send-updates none
gcal event update e1 --start "tomorrow 15:00" --duration 30m
gcal event update e1 --title "Updated title"
```

Flags:

- `--add-attendee` (stringArray): Add attendee email; repeatable
- `--all-day` (bool): All-day event
- `--attendee` (stringArray): Compatibility alias for --add-attendee; repeatable
- `--calendar` (string): Optional calendar selector
- `--description` (string): Description
- `--duration` (string): Duration
- `--end` (string): Event end
- `--location` (string): Location
- `--remove-attendee` (stringArray): Remove attendee email; repeatable
- `--send-updates` (string): Guest notification policy: all, externalOnly, or none
- `--set-optional-attendee` (stringArray): Replace attendees with optional attendee email; repeatable
- `--set-required-attendee` (stringArray): Replace attendees with required attendee email; repeatable
- `--start` (string): Event start
- `--title` (string): Event title
- `--yes` (bool): Accepted for compatibility; this command is already non-interactive

### `gcal freebusy`

- Anchor: `cmd-gcal-freebusy`
- Mutates state: `no`
- Supports dry run: `no`

Inspect busy windows

#### `gcal freebusy get`

- Anchor: `cmd-gcal-freebusy-get`
- Mutates state: `no`
- Supports dry run: `no`

Get busy windows for calendars

Get busy windows for calendars. Relative --from and --to values such as +8h and +9h are both relative to now.

Example:

```bash
gcal freebusy get
gcal freebusy get --calendar c1 --from today --to tomorrow
gcal freebusy get --from "tomorrow 09:00" --to "tomorrow 17:00" --view full
gcal freebusy get --from +8h --to +9h
gcal freebusy get --from now --to +4h
```

Flags:

- `--calendar` (stringSlice): Calendar selectors Default: `[primary]`.
- `--from` (string): Start time
- `--to` (string): End time

### `gcal login`

- Anchor: `cmd-gcal-login`
- Mutates state: `yes`
- Supports dry run: `no`

Authenticate with Google Calendar

Example:

```bash
gcal auth status
gcal login
```

### `gcal logout`

- Anchor: `cmd-gcal-logout`
- Mutates state: `yes`
- Supports dry run: `no`

Remove stored credentials

Example:

```bash
gcal auth login
gcal logout
```

### `gcal profile`

- Anchor: `cmd-gcal-profile`
- Mutates state: `no`
- Supports dry run: `no`

Manage provider profiles

#### `gcal profile create`

- Anchor: `cmd-gcal-profile-create`
- Mutates state: `yes`
- Supports dry run: `no`

Create an unauthenticated provider profile

Example:

```bash
gcal profile create --help
```

#### `gcal profile delete`

- Anchor: `cmd-gcal-profile-delete`
- Mutates state: `yes`
- Supports dry run: `no`

Delete a local provider profile

Example:

```bash
gcal profile delete --help
```

#### `gcal profile list`

- Anchor: `cmd-gcal-profile-list`
- Mutates state: `no`
- Supports dry run: `no`

List provider profiles

Example:

```bash
gcal profile list --help
```

#### `gcal profile rename`

- Anchor: `cmd-gcal-profile-rename`
- Mutates state: `no`
- Supports dry run: `no`

Rename a local provider profile

Example:

```bash
gcal profile rename --help
```

#### `gcal profile use`

- Anchor: `cmd-gcal-profile-use`
- Mutates state: `yes`
- Supports dry run: `no`

Set the default provider profile

Example:

```bash
gcal profile use --help
```

### `gcal resolve`

- Anchor: `cmd-gcal-resolve`
- Mutates state: `no`
- Supports dry run: `no`

Resolve a marker or short id

Example:

```bash
gcal resolve --help
gcal resolve c1
gcal resolve e1
gcal resolve u1
```

### `gcal schema`

- Anchor: `cmd-gcal-schema`
- Mutates state: `no`
- Supports dry run: `no`

Emit gcal schema hints

Example:

```bash
gcal schema
gcal schema --help
gcal schema event.create
gcal schema event.create --input
```

Flags:

- `--in` (bool): Show input schema
- `--input` (bool): Show input schema
- `--out` (bool): Show output schema

### `gcal slot`

- Anchor: `cmd-gcal-slot`
- Mutates state: `no`
- Supports dry run: `no`

Find open slots

#### `gcal slot find`

- Anchor: `cmd-gcal-slot-find`
- Mutates state: `no`
- Supports dry run: `no`

Find open slots across calendars

Find open slots across calendars. Relative --from and --to values such as +8h and +9h are both relative to now.

Example:

```bash
gcal slot find
gcal slot find --calendar c1 --from today --to tomorrow --duration 1h
gcal slot find --from "tomorrow 09:00" --to "tomorrow 17:00" --view full
gcal slot find --from +8h --to +9h --duration 30m
gcal slot find --from now --to +4h --duration 30m
```

Flags:

- `--calendar` (stringSlice): Calendar selectors Default: `[primary]`.
- `--duration` (string): Minimum slot duration Default: `30m`.
- `--from` (string): Start time
- `--to` (string): End time

### `gcal version`

- Anchor: `cmd-gcal-version`
- Mutates state: `no`
- Supports dry run: `no`

Show gcal version information

Example:

```bash
gcal version --help
```

## Live Examples

### Auth

#### Check current identity

Returns the active calendar identity.

_Example metadata: requires auth; provider state: live._

```bash
gcal auth whoami
```

```text
Authenticated as kestrelphilip@gmail.com

Next steps:
- Calendars:    gcal calendar list
- Events:       gcal event list --{day}
- Capabilities: gcal capabilities
```

### Calendars

#### List calendars

Lists visible calendars.

_Example metadata: requires auth; provider state: live._

```bash
gcal calendar list --limit 5
```

```text
REF  TITLE                    HANDLE   TIME_ZONE  STATUS             ROLE
c1   kestrelphilip@gmail.com  primary  UTC        primary, selected  owner

Next steps:
- Open:      gcal calendar get c1
- Search:    gcal calendar search --query "work"
- Calendars: gcal calendar list
- Events:    gcal event list --{day}
```

### Events

#### List today's events

Lists events happening today.

_Example metadata: requires auth; provider state: live._

```bash
gcal event list --today --limit 5
```

```text
No event found.

Next steps:
- Search:    gcal event search --query "planning"
- Create help:    gcal event create --help
- Status:    gcal auth status
- Calendars: gcal calendar list
```

#### Search events

Searches events by text.

_Example metadata: requires auth; provider state: live._

```bash
gcal event search --query eval --limit 5
```

```text
REF  TITLE                                                        STATUS     WHEN                                                       CALENDAR  LOCATION
e1   All Day Target eval-gcal-allday-minute-straight-sorry        confirmed  2026-06-02 to 2026-06-03 (all day)                         primary   
e2   All Day Target eval-gcal-allday-someone-chinese-space        confirmed  2026-06-02 to 2026-06-03 (all day)                         primary   
e3   All Day Target eval-gcal-allday-situation-included-june      confirmed  2026-06-02 to 2026-06-03 (all day)                         primary   
e4   Location Timezone Target eval-gcal-loc-touch-change-service  confirmed  Tue 02 Jun 10:00-10:30 SAST (UTC+02:00) (UTC 08:00-08:30)  primary   Room ervice
e5   Location Timezone Target eval-gcal-loc-street-husband-woman  confirmed  Tue 02 Jun 10:00-10:30 SAST (UTC+02:00) (UTC 08:00-08:30)  primary   Room -woman

Next steps:
- Open:      gcal event get e1
- List:      gcal event list
- Calendars: gcal calendar list
- Events:    gcal event list --{day}
```

### Freebusy

#### Inspect busy windows

Shows busy windows on the primary calendar.

_Example metadata: requires auth; provider state: live._

```bash
gcal freebusy get --calendar primary --from today 09:00 --to today 17:00
```

```text
description: Time zone: Local
resource: freebusy
status: free
title: Busy windows
type: freebusy
when: Sat 30 May 09:00-17:00 SAST (UTC+02:00) (UTC 07:00-15:00)

Next steps:
- Calendars:    gcal calendar list
- Events:       gcal event list --{day}
- Capabilities: gcal capabilities
- Check:         gcal freebusy get --calendar primary --from now --to +4h
```
