Skip to content

calendar: events have no location field (write path and listEvents mask) #432

Description

@MatiasBarboza

Summary

There is no way to set an event's location through this server. calendar.createEvent and calendar.updateEvent expose summary, description, start, end, attendees, attachments and the three special event types, but not the plain location string that has been on the Calendar v3 Event resource for years.

The only location-shaped fields available are workingLocationProperties, which apply exclusively to eventType: "workingLocation" and are not an address.

Why it matters

Maps apps open location. An address written into description is text; it is not navigable, and it does not show up as the event's place anywhere in the Calendar UI. For any client whose only calendar path is this server — a headless agent, a bot surface, anything that cannot fall back to the web UI — an event's address is simply unreachable today.

There is a read half too, and it is easy to miss

Adding location to the write path alone is not enough. listEvents sends a hard-coded fields mask that does not name location, so an event could carry an address that listEvents would never return. That is the same class as #384; this issue is one concrete instance of it.

Patch

Verified against the live API and covered by tests. Three small pieces:

1. Input typesCalendarService.ts

export interface CreateEventInput {
  calendarId?: string;
  summary?: string;
  description?: string;
  location?: string;   // <-- added
  start: { dateTime?: string; date?: string };
  // ...
}

export interface UpdateEventInput {
  eventId: string;
  calendarId?: string;
  summary?: string;
  description?: string;
  location?: string;   // <-- added
  // ...
}

2. Write pathCalendarService.ts

// createEvent: destructure `location` from input, then, after the event body
// is built. Only write it when the caller passed one, so the body does not
// claim an intent the caller never expressed.
if (location !== undefined) event.location = location;

// updateEvent: same undefined-vs-empty distinction as every field above it.
// Omitting it leaves the address alone; passing "" clears it on purpose.
if (location !== undefined) requestBody.location = location;

3. Read pathCalendarService.ts, the listEvents field mask

         fields:
-          'items(id,summary,start,end,description,htmlLink,attendees,status,eventType,focusTimeProperties,outOfOfficeProperties,workingLocationProperties,attachments(fileId,fileUrl,title,mimeType,iconLink))',
+          'items(id,summary,start,end,description,location,htmlLink,attendees,status,eventType,focusTimeProperties,outOfOfficeProperties,workingLocationProperties,attachments(fileId,fileUrl,title,mimeType,iconLink))',

4. Tool schemasindex.ts, on both calendar.createEvent and calendar.updateEvent

location: z
  .string()
  .optional()
  .describe(
    'The geographic location of the event as free-form text (e.g. an address). This is what a maps app opens; do not bury an address in the description instead.',
  ),

Verification

  • Full suite green with the change (6 added tests). The two new write assertions were watched fail first, by neutralising both location assignments — 4 red out of 4 expected. The two conservation assertions ('location' in body === false when none is passed, and when only attendees change) correctly stay green under that mutation, since they assert that something is not written.
  • Two pre-existing tests that assert the listEvents field mask went red on the mask change and were updated. That mask is genuinely covered.
  • Live against the Google API with a freshly spawned server: event created with an address, address survives adding an attendee, updateEvent changes it without touching summary or attendees, and listEvents returns it.

Happy to open a PR if that is preferred, though the CLA is a gate on our side — the patch above is complete either way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions