Skip to main content
Glama
calendars.ts7.03 kB
import { z } from "zod" import type { calendar_v3 } from "googleapis" import type { Auth } from "googleapis" import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" function checkAuthentication(oauth2Client: Auth.OAuth2Client) { if (!oauth2Client.credentials.access_token && !oauth2Client.credentials.refresh_token) { throw new Error("Authentication required. Please authenticate first using `generate_oauth_url` and `exchange_auth_code` tools.") } } export function registerCalendarTools( server: McpServer, calendar: calendar_v3.Calendar, oauth2Client: Auth.OAuth2Client, ) { // Tool: List Calendars server.tool( "list_calendars", "List all calendars accessible to the authenticated user", { show_hidden: z .boolean() .optional() .default(false) .describe("Whether to show hidden calendars"), }, async ({ show_hidden }) => { try { // Check authentication only when tool is invoked checkAuthentication(oauth2Client) const response = await calendar.calendarList.list({ showHidden: show_hidden, }) const calendars = response.data.items || [] if (calendars.length === 0) { return { content: [ { type: "text", text: "📅 **No calendars found**\n\nThe authenticated user has no accessible calendars.", }, ], } } let markdown = `# 📅 User Calendars (${calendars.length} found)\n\n` calendars.forEach((cal, index) => { const isPrimary = cal.primary ? " 🌟 **Primary**" : "" const access = cal.accessRole ? ` | **Access:** ${cal.accessRole}` : "" const hidden = cal.hidden ? " | ⛔ **Hidden**" : "" markdown += `## ${index + 1}. ${cal.summary || "Untitled Calendar"}${isPrimary}\n\n` markdown += `- **ID:** \`${cal.id}\`\n` markdown += `- **Description:** ${cal.description || "No description"}\n` markdown += `- **Timezone:** ${cal.timeZone || "Unknown"}\n` markdown += `- **Color:** ${cal.colorId ? `Color ID ${cal.colorId}` : "Default"}${access}${hidden}\n` if (cal.defaultReminders && cal.defaultReminders.length > 0) { markdown += `- **Default Reminders:**\n` cal.defaultReminders.forEach(reminder => { markdown += ` - ${reminder.method}: ${reminder.minutes} minutes before\n` }) } markdown += `\n` }) markdown += `---\n\n**💡 Tip:** Use the calendar ID with event tools to manage events in specific calendars.` return { content: [{ type: "text", text: markdown }], } } catch (e: any) { return { content: [{ type: "text", text: `Error listing calendars: ${e.message}` }], } } }, ) // Tool: Get Calendar Details server.tool( "get_calendar", "Get detailed information about a specific calendar", { calendar_id: z .string() .describe("Calendar ID (use 'primary' for user's primary calendar)"), }, async ({ calendar_id }) => { try { // Check authentication only when tool is invoked checkAuthentication(oauth2Client) const response = await calendar.calendars.get({ calendarId: calendar_id, }) const cal = response.data const markdown = `# 📅 Calendar Details ## ${cal.summary || "Untitled Calendar"} ### Basic Information - **Calendar ID:** \`${cal.id}\` - **Description:** ${cal.description || "No description"} - **Location:** ${cal.location || "Not specified"} - **Timezone:** ${cal.timeZone || "Unknown"} ### Configuration - **Conference Properties:** ${cal.conferenceProperties?.allowedConferenceSolutionTypes?.length ? cal.conferenceProperties.allowedConferenceSolutionTypes.join(", ") : "None configured"} ### Links - **ETag:** \`${cal.etag}\` - **Kind:** ${cal.kind} --- **💡 Use this calendar ID (\`${cal.id}\`) with event management tools to create, read, update, or delete events.**` return { content: [{ type: "text", text: markdown }], } } catch (e: any) { return { content: [{ type: "text", text: `Error getting calendar details: ${e.message}` }], } } }, ) // Tool: Create Calendar server.tool( "create_calendar", "Create a new calendar", { summary: z.string().describe("Calendar name/title"), description: z .string() .optional() .describe("Calendar description"), location: z .string() .optional() .describe("Calendar location"), timezone: z .string() .optional() .describe("Calendar timezone (e.g., 'America/New_York')"), }, async ({ summary, description, location, timezone }) => { try { // Check authentication only when tool is invoked checkAuthentication(oauth2Client) const response = await calendar.calendars.insert({ requestBody: { summary, description, location, timeZone: timezone, }, }) const newCalendar = response.data const markdown = `# ✅ Calendar Created Successfully ## ${newCalendar.summary} ### Details - **Calendar ID:** \`${newCalendar.id}\` - **Description:** ${newCalendar.description || "No description"} - **Location:** ${newCalendar.location || "Not specified"} - **Timezone:** ${newCalendar.timeZone || "Default"} ### Next Steps - Use calendar ID \`${newCalendar.id}\` to manage events in this calendar - The calendar should now appear in your Google Calendar interface - You can set permissions using Google Calendar sharing settings --- **💡 Tip:** Save the calendar ID for future reference when creating events.` return { content: [{ type: "text", text: markdown }], } } catch (e: any) { return { content: [{ type: "text", text: `Error creating calendar: ${e.message}` }], } } }, ) // Tool: Delete Calendar server.tool( "delete_calendar", "Delete a calendar (WARNING: This will delete all events in the calendar)", { calendar_id: z .string() .describe("Calendar ID to delete (cannot delete primary calendar)"), }, async ({ calendar_id }) => { try { // Check authentication only when tool is invoked checkAuthentication(oauth2Client) if (calendar_id === "primary") { return { content: [ { type: "text", text: "❌ **Error**: Cannot delete the primary calendar. You can only delete secondary calendars you've created.", }, ], } } await calendar.calendars.delete({ calendarId: calendar_id, }) const markdown = `# ✅ Calendar Deleted Successfully The calendar with ID \`${calendar_id}\` has been permanently deleted. ## ⚠️ Important Notes - All events in this calendar have been permanently deleted - This action cannot be undone - The calendar will no longer appear in your Google Calendar interface --- **💡 Tip:** Use \`list_calendars\` to verify the calendar has been removed.` return { content: [{ type: "text", text: markdown }], } } catch (e: any) { return { content: [{ type: "text", text: `Error deleting calendar: ${e.message}` }], } } }, ) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/goldk3y/google-calendar-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server