calendar-list-events
Retrieve calendar events with filters for time range, recurrence, and sorting to manage schedules and track appointments.
Instructions
List calendar events with optional filters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| calendarId | No | Calendar ID - Available options: 'primary' (Primary Calendar) | primary |
| timeMin | No | Lower bound for event start time (ISO format) | |
| timeMax | No | Upper bound for event start time (ISO format) | |
| maxResults | No | Maximum number of events to return | |
| singleEvents | No | Whether to expand recurring events | |
| orderBy | No | Order of events | startTime |
Implementation Reference
- src/calendar.ts:345-406 (handler)The handler function for listing calendar events. Queries Google Calendar API with provided filters, maps the response, formats as markdown, and returns in MCP format.
export async function listEvents( params: z.infer<ReturnType<typeof listEventsSchema>> ) { try { const auth = createCalendarAuth(); const calendar = google.calendar({ version: "v3", auth }); const listParams: any = { calendarId: params.calendarId, maxResults: params.maxResults, singleEvents: params.singleEvents, orderBy: params.orderBy, }; if (params.timeMin) listParams.timeMin = params.timeMin; if (params.timeMax) listParams.timeMax = params.timeMax; // If no timeMin is specified, default to current time if (!params.timeMin) { listParams.timeMin = new Date().toISOString(); } const response = await calendar.events.list(listParams); const events = response.data.items?.map((event) => ({ id: event.id, summary: event.summary, description: event.description, location: event.location, start: event.start, end: event.end, attendees: event.attendees?.map((a) => ({ email: a.email, responseStatus: a.responseStatus, })), htmlLink: event.htmlLink, status: event.status, created: event.created, updated: event.updated, })); return { content: [ { type: "text" as const, text: formatEventListToMarkdown(events || [], events?.length || 0), }, ], }; } catch (error) { return { content: [ { type: "text" as const, text: `Error listing events: ${ error instanceof Error ? error.message : String(error) }`, }, ], }; } } - src/calendar.ts:166-194 (schema)Zod schema defining the input parameters for the listEvents tool, including calendarId, time filters, maxResults, etc.
export const listEventsSchema = () => z.object({ calendarId: z .string() .default("primary") .describe(getCalendarDescription()), timeMin: z .string() .optional() .describe("Lower bound for event start time (ISO format)"), timeMax: z .string() .optional() .describe("Upper bound for event start time (ISO format)"), maxResults: z .number() .min(1) .max(250) .default(10) .describe("Maximum number of events to return"), singleEvents: z .boolean() .default(true) .describe("Whether to expand recurring events"), orderBy: z .enum(["startTime", "updated"]) .default("startTime") .describe("Order of events"), }); - src/index.ts:224-231 (registration)Registers the 'calendar-list-events' tool with the MCP server, using listEventsSchema and listEvents handler.
server.tool( "calendar-list-events", "List calendar events with optional filters", listEventsSchema().shape, async (params) => { return await listEvents(params); } ); - src/calendar.ts:45-77 (helper)Helper function to format the list of events into a readable markdown list, used by the listEvents handler.
function formatEventListToMarkdown(events: any[], totalResults: number): string { if (!events.length) return "# No Upcoming Events\n\nNo events found in the specified time range."; let markdown = `# Upcoming Events (${totalResults})\n\n`; events.forEach((event, index) => { const startDate = event.start?.dateTime ? new Date(event.start.dateTime) : null; const endDate = event.end?.dateTime ? new Date(event.end.dateTime) : null; markdown += `## ${index + 1}. ${event.summary || 'Untitled Event'}\n`; if (startDate) { if (endDate && startDate.toDateString() === endDate.toDateString()) { // Same day event markdown += `When: ${startDate.toLocaleDateString()} ${startDate.toLocaleTimeString()} - ${endDate.toLocaleTimeString()} \n`; } else { markdown += `Start: ${startDate.toLocaleString()} \n`; if (endDate) markdown += `End: ${endDate.toLocaleString()} \n`; } } if (event.location) markdown += `Location: ${event.location} \n`; if (event.description) markdown += `Description: ${event.description} \n`; if (event.attendees && event.attendees.length > 0) { markdown += `Attendees: ${event.attendees.length} people \n`; } if (event.id) markdown += `ID: \`${event.id}\` \n`; markdown += `\n---\n\n`; }); return markdown; }