Skip to content

Commit 6feba6d

Browse files
authored
feat(calendar): introduce eventType (Out of Office, Focus Time, Working Location) in Calendar Service (#290)
* feat(calendar): introduce eventType (Out of Office, Focus Time, Working Location) in Calendar Service * fix: apply feedback from @allenhutchison to merge 3 eventType tools into one * feat(google-calendar): update SKILL.md to use new eventTypes * fix: formatting and feedback from @allenhutchison
1 parent a9fadce commit 6feba6d

File tree

4 files changed

+1003
-35
lines changed

4 files changed

+1003
-35
lines changed

skills/google-calendar/SKILL.md

Lines changed: 140 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ Should I create this event?
9898

9999
- **`calendarId`****Always pass `"primary"`**. Use `calendar.list` to
100100
discover other calendars when needed.
101-
- **`start` / `end`** — Must include timezone offset in ISO 8601 format (e.g.,
102-
`2025-01-15T10:00:00-05:00`)
101+
- **`start` / `end`** — Two formats:
102+
- **Timed events**: `{ dateTime: "2025-01-15T10:00:00-05:00" }` — ISO 8601
103+
with timezone offset
104+
- **All-day events**: `{ date: "2025-01-15" }` — YYYY-MM-DD format. The end
105+
date is exclusive (use the next day).
103106
- **`attendees`** — Array of email addresses
104107
- **`addGoogleMeet`** — Set to `true` to automatically generate a Google Meet
105108
link (available in response's `hangoutLink` field)
@@ -110,8 +113,14 @@ Should I create this event?
110113
- `"all"` — Notify all attendees (default when attendees are provided)
111114
- `"externalOnly"` — Only notify non-organization attendees
112115
- `"none"` — No notifications
116+
- **`eventType`** — The type of event (see
117+
[Calendar Status Events](#calendar-status-events) below):
118+
- `"default"` — Regular event (default if omitted)
119+
- `"focusTime"` — Focus time block
120+
- `"outOfOffice"` — Out-of-office event
121+
- `"workingLocation"` — Working location indicator
113122

114-
### Example
123+
### Example — Regular Timed Event
115124

116125
```
117126
calendar.createEvent({
@@ -131,6 +140,124 @@ calendar.createEvent({
131140
})
132141
```
133142

143+
### Example — All-Day Event
144+
145+
```
146+
calendar.createEvent({
147+
calendarId: "primary",
148+
summary: "Team Offsite",
149+
start: { date: "2025-01-15" },
150+
end: { date: "2025-01-17" },
151+
description: "Two-day team offsite"
152+
})
153+
```
154+
155+
## Calendar Status Events
156+
157+
`calendar.createEvent` supports creating focus time, out-of-office, and working
158+
location events via the `eventType` parameter. These are all created through the
159+
same tool — there are no separate tools for each type.
160+
161+
### Focus Time
162+
163+
Blocks concentrated work periods. Can auto-decline conflicting meetings.
164+
165+
> **Constraint:** Focus time events **cannot be all-day events** — they must use
166+
> `dateTime`, not `date`.
167+
168+
```
169+
calendar.createEvent({
170+
calendarId: "primary",
171+
eventType: "focusTime",
172+
start: { dateTime: "2025-01-15T09:00:00-05:00" },
173+
end: { dateTime: "2025-01-15T12:00:00-05:00" },
174+
focusTimeProperties: {
175+
chatStatus: "doNotDisturb",
176+
autoDeclineMode: "declineOnlyNewConflictingInvitations",
177+
declineMessage: "In focus mode, will respond later"
178+
}
179+
})
180+
```
181+
182+
- **`summary`** defaults to `"Focus Time"` if omitted
183+
- **`focusTimeProperties.chatStatus`**`"doNotDisturb"` (default) or
184+
`"available"`
185+
- **`focusTimeProperties.autoDeclineMode`**
186+
`"declineOnlyNewConflictingInvitations"` (default),
187+
`"declineAllConflictingInvitations"`, or `"declineNone"`
188+
- **`focusTimeProperties.declineMessage`** — optional message sent when
189+
declining
190+
191+
### Out of Office
192+
193+
Signals unavailability and auto-declines conflicting meetings.
194+
195+
> **Constraint:** Out-of-office events **cannot be all-day events** — they must
196+
> use `dateTime`, not `date`.
197+
198+
```
199+
calendar.createEvent({
200+
calendarId: "primary",
201+
eventType: "outOfOffice",
202+
summary: "Vacation",
203+
start: { dateTime: "2025-01-15T00:00:00-05:00" },
204+
end: { dateTime: "2025-01-19T00:00:00-05:00" },
205+
outOfOfficeProperties: {
206+
autoDeclineMode: "declineAllConflictingInvitations",
207+
declineMessage: "I am on vacation until Jan 19"
208+
}
209+
})
210+
```
211+
212+
- **`summary`** defaults to `"Out of Office"` if omitted
213+
- **`outOfOfficeProperties.autoDeclineMode`**
214+
`"declineOnlyNewConflictingInvitations"` (default),
215+
`"declineAllConflictingInvitations"`, or `"declineNone"`
216+
- **`outOfOfficeProperties.declineMessage`** — optional message sent when
217+
declining
218+
219+
### Working Location
220+
221+
Indicates where the user is working from. Supports both timed and all-day
222+
events.
223+
224+
```
225+
calendar.createEvent({
226+
calendarId: "primary",
227+
eventType: "workingLocation",
228+
start: { date: "2025-01-15" },
229+
end: { date: "2025-01-16" },
230+
workingLocationProperties: {
231+
type: "homeOffice"
232+
}
233+
})
234+
```
235+
236+
- **`summary`** defaults to `"Working Location"` if omitted
237+
- **`workingLocationProperties`** is **required** when `eventType` is
238+
`"workingLocation"`
239+
- **`workingLocationProperties.type`**`"homeOffice"`, `"officeLocation"`, or
240+
`"customLocation"`
241+
- **`officeLocation`**`{ buildingId?: string, label?: string }` (when type is
242+
`"officeLocation"`)
243+
- **`customLocation`**`{ label: string }` (when type is `"customLocation"`)
244+
245+
### Listing Events by Type
246+
247+
Use the `eventTypes` parameter on `calendar.listEvents` to filter by event type:
248+
249+
```
250+
calendar.listEvents({
251+
calendarId: "primary",
252+
timeMin: "2025-01-15T00:00:00-05:00",
253+
timeMax: "2025-01-17T23:59:59-05:00",
254+
eventTypes: ["focusTime", "outOfOffice", "workingLocation"]
255+
})
256+
```
257+
258+
Available types: `"default"`, `"focusTime"`, `"outOfOffice"`,
259+
`"workingLocation"`, `"birthday"`, `"fromGmail"`.
260+
134261
## Updating Events
135262

136263
Use `calendar.updateEvent` for modifications. Only the fields you provide will
@@ -252,13 +379,13 @@ Users may have multiple calendars (personal, work, shared team calendars).
252379

253380
## Tool Quick Reference
254381

255-
| Tool | Action | Key Parameters |
256-
| :------------------------ | :-------------------------- | :-------------------------------------------------------------------------------- |
257-
| `calendar.list` | List all calendars | _(none)_ |
258-
| `calendar.listEvents` | List events | `calendarId`, `timeMin`, `timeMax` |
259-
| `calendar.getEvent` | Get event details | `eventId`, `calendarId` |
260-
| `calendar.createEvent` | Create a new event | `calendarId`, `summary`, `start`, `end`, `addGoogleMeet`, `attachments` |
261-
| `calendar.updateEvent` | Modify an existing event | `eventId`, `summary`, `start`, `end`, `attendees`, `addGoogleMeet`, `attachments` |
262-
| `calendar.deleteEvent` | Delete an event | `eventId`, `calendarId` |
263-
| `calendar.respondToEvent` | Accept/decline an invite | `eventId`, `responseStatus` |
264-
| `calendar.findFreeTime` | Find available meeting time | `attendees`, `timeMin`, `timeMax`, `duration` |
382+
| Tool | Action | Key Parameters |
383+
| :------------------------ | :------------------------------- | :----------------------------------------------------------------------------------- |
384+
| `calendar.list` | List all calendars | _(none)_ |
385+
| `calendar.listEvents` | List events (filterable by type) | `calendarId`, `timeMin`, `timeMax`, `eventTypes` |
386+
| `calendar.getEvent` | Get event details | `eventId`, `calendarId` |
387+
| `calendar.createEvent` | Create event (all types) | `calendarId`, `summary`, `start`, `end`, `eventType`, `addGoogleMeet`, `attachments` |
388+
| `calendar.updateEvent` | Modify an existing event | `eventId`, `summary`, `start`, `end`, `attendees`, `addGoogleMeet`, `attachments` |
389+
| `calendar.deleteEvent` | Delete an event | `eventId`, `calendarId` |
390+
| `calendar.respondToEvent` | Accept/decline an invite | `eventId`, `responseStatus` |
391+
| `calendar.findFreeTime` | Find available meeting time | `attendees`, `timeMin`, `timeMax`, `duration` |

0 commit comments

Comments
 (0)