Use porteden calendar to list, search, and read Google Calendar events in the active account. Use -jc flags for AI-optimized output.
If porteden is not installed: brew install porteden/tap/porteden (or go install github.com/porteden/cli/cmd/porteden@latest).
porteden auth login — opens browser, sign in with the Google account, credentials stored in system keyringporteden auth login --token — stored in system keyringporteden auth statusPE_API_KEY is set in the environment, the CLI uses it automatically (no login needed).create, update, delete, and respond change shared state and often send notifications to attendees. Before running any of them, echo back the target profile/account, the calendar ID and event ID (or summary + time for create), the attendee list if it's changing, and the intended change, then wait for the user to confirm. By default update --notify is true (notifications are sent); pass --notify=false to suppress. delete notifies attendees by default; pass --no-notify to skip the cancellation message.--profile (or PE_PROFILE) to isolate Google Calendar accounts so a task touches only the calendar it needs. Prefer the narrowest Google scope at login. When a task is done — especially on a shared machine — run porteden auth logout to clear the keyring entry, and revoke access from the Google account's security page (myaccount.google.com → Security → Third-party access) if a token may have been exposed.porteden calendar calendars -jc--tomorrow, --week, --days N): porteden calendar events --today -jcporteden calendar events --from 2026-02-01 --to 2026-02-07 -jcporteden calendar events --week --all -jcporteden calendar events --week --include-cancelled -jcporteden calendar events -q "meeting" --today -jcporteden calendar events --week --attendees "alice@example.com,bob@example.com" -jcporteden calendar by-contact "user@example.com" -jc (or --name "John")porteden calendar event -jc porteden calendar freebusy --week -jc (or --calendars 123,456 for specific calendars)porteden calendar create --calendar --summary "Meeting" --from "..." --to "..." --location "Room A" --attendees "a@b.com,c@d.com" porteden calendar create --calendar --summary "Standup" --from "..." --to "..." --recurrence "RRULE:FREQ=WEEKLY;COUNT=10" porteden calendar create --calendar --summary "Holiday" --from "2026-07-04T00:00:00Z" --to "2026-07-05T00:00:00Z" --all-day porteden calendar update --summary "New Title" (also: --from, --to, --location)porteden calendar update --add-attendees "new@example.com" (or --remove-attendees; default sends notifications, use --notify=false to suppress)porteden calendar delete (add --no-notify to skip attendee cancellation emails)porteden calendar respond accepted (or: declined, tentative)Two distinct fields are returned on events — don't conflate them.
Event-level status (returned in event.status):
confirmed — normal/scheduled eventtentative — provider-side tentative (rare on Google)cancelled — event was cancelled or deleted (only shown with --include-cancelled)Attendee-level response (returned in event.attendees[].response):
needs_action — invitee has not yet respondedaccepted — RSVP'd yestentative — RSVP'd maybedeclined — RSVP'd norespond returns 409 CANNOT_RSVP_AS_ORGANIZER when the active user is the organizer (organizers don't RSVP to their own events) and 409 NOT_AN_ATTENDEE when the active user isn't in the attendee list. Both are non-retryable preconditions — surface the message to the user instead of looping.
2026-02-01T10:00:00Z--all-day flag — the API returns allDay: true and durationMinutes: 1440startUtc, endUtc, durationMinutes, status, allDay, organizer, attendees[], joinUrl, and metaPE_PROFILE=work to avoid repeating --profile.-jc is shorthand for --json --compact: filters noise, truncates descriptions, limits attendees, reduces tokens.--all to auto-fetch all pages. The response meta block carries count, totalCount, hasMore, limit, offset, from, to on both /events and /events/by-contact. Manual: --limit 100 --offset 0, then --offset 100, etc.724), not the email-formatted Google native IDs. Get the integer ID via porteden calendar calendars -jc. The corresponding Google calendar email (primary, your account email, or @group.calendar.google.com ) shows up in the externalId field.by-contact matches the positional email arg as a partial substring (so "@acme.com" matches anyone at that domain). --name matches against the attendee's display name when present, otherwise falls back to the local-part of the email (so --name alice matches alice@example.com, but --name acme does not match alice@acme.com). Google attendees outside the user's contacts often have a null displayName, so the local-part fallback is the common case.porteden calendar calendars -jc.QUOTA_EXCEEDED (monthly cap) and 429 RATE_LIMITED (transient) are differentiated by the code field in the body; the response also carries x-monthly-limit/x-monthly-used/x-monthly-remaining headers. Quota-blocked requests do not consume quota.PE_API_KEY, PE_PROFILE, PE_TIMEZONE, PE_FORMAT, PE_COLOR, PE_VERBOSE.共 3 个版本