UNPKG

@coretext-ai/qa-gsuite-f47ac10b-58cc-4372-a567-0e02b2c3d479

Version:

MCP server with GSuite (Contacts, Drive, Gmail, Calendar) integration

624 lines 28.3 kB
import { Logger } from '../services/logger.js'; export class GoogleCalendarTools { constructor(client) { this.initialized = false; this.client = client; // Get logger from client if available, otherwise create fallback this.logger = client.logger || new Logger({ logLevel: 'ERROR', component: 'tools', enableConsole: true, enableShipping: false, serverName: '' }); } async ensureInitialized() { if (!this.initialized) { // Log tools initialization now that client is ready this.logger.info('TOOLS_INIT', 'Tools instance initialization started', { integration: 'google-calendar', isOAuth: true }); this.logger.info('CLIENT_INITIALIZATION', 'Starting client initialization', { isOAuth: true }); await this.client.initialize(); this.initialized = true; this.logger.info('CLIENT_INITIALIZATION', 'Client initialization completed', { initialized: this.initialized }); } } getToolDefinitions() { return [ { name: 'google-calendar_list_calendars', description: 'Returns the calendars on the user's calendar list', inputSchema: { type: 'object', properties: { maxResults: { type: 'number', description: 'Maximum number of entries returned (default 100, max 250)' }, minAccessRole: { type: 'string', description: 'The minimum access role for the user in the returned entries (freeBusyReader, reader, writer, owner)' }, pageToken: { type: 'string', description: 'Token specifying which result page to return' }, showDeleted: { type: 'boolean', description: 'Whether to include deleted calendar list entries in the result' }, showHidden: { type: 'boolean', description: 'Whether to show hidden entries' }, }, required: [] } }, { name: 'google-calendar_get_calendar', description: 'Returns metadata for a calendar', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, }, required: ['calendarId'] } }, { name: 'google-calendar_create_calendar', description: 'Creates a secondary calendar', inputSchema: { type: 'object', properties: { summary: { type: 'string', description: 'Title of the calendar' }, description: { type: 'string', description: 'Description of the calendar' }, location: { type: 'string', description: 'Geographic location of the calendar' }, timeZone: { type: 'string', description: 'The time zone of the calendar (e.g., 'America/New_York')' }, }, required: ['summary',] } }, { name: 'google-calendar_update_calendar', description: 'Updates metadata for a calendar', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier' }, summary: { type: 'string', description: 'Title of the calendar' }, description: { type: 'string', description: 'Description of the calendar' }, location: { type: 'string', description: 'Geographic location of the calendar' }, timeZone: { type: 'string', description: 'The time zone of the calendar' }, }, required: ['calendarId',] } }, { name: 'google-calendar_delete_calendar', description: 'Deletes a secondary calendar', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier' }, }, required: ['calendarId'] } }, { name: 'google-calendar_list_events', description: 'Returns events on the specified calendar', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, maxResults: { type: 'number', description: 'Maximum number of events returned (default 250, max 2500)' }, orderBy: { type: 'string', description: 'Order by the start time or last modification time (startTime, updated)' }, pageToken: { type: 'string', description: 'Token specifying which result page to return' }, q: { type: 'string', description: 'Free text search terms to find events' }, showDeleted: { type: 'boolean', description: 'Whether to include deleted events' }, singleEvents: { type: 'boolean', description: 'Whether to expand recurring events into instances' }, timeMax: { type: 'string', description: 'Upper bound for event's start time (RFC3339 timestamp)' }, timeMin: { type: 'string', description: 'Lower bound for event's end time (RFC3339 timestamp)' }, timeZone: { type: 'string', description: 'Time zone used in the response' }, }, required: ['calendarId',] } }, { name: 'google-calendar_get_event', description: 'Returns an event', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, eventId: { type: 'string', description: 'Event identifier' }, timeZone: { type: 'string', description: 'Time zone used in the response' }, }, required: ['calendarId', 'eventId',] } }, { name: 'google-calendar_create_event', description: 'Creates an event', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, summary: { type: 'string', description: 'Title of the event' }, description: { type: 'string', description: 'Description of the event' }, location: { type: 'string', description: 'Geographic location of the event' }, start: { type: 'object', description: 'Start time of the event. Use 'date' for all-day events or 'dateTime' with timeZone' }, end: { type: 'object', description: 'End time of the event. Use 'date' for all-day events or 'dateTime' with timeZone' }, attendees: { type: 'array', description: 'List of attendees with email addresses' }, reminders: { type: 'object', description: 'Information about the event's reminders' }, recurrence: { type: 'array', description: 'List of RRULE, EXRULE, RDATE and EXDATE lines for recurring event' }, sendNotifications: { type: 'boolean', description: 'Whether to send notifications about the creation of the new event' }, sendUpdates: { type: 'string', description: 'Whether to send notifications to attendees (all, externalOnly, none)' }, }, required: ['calendarId', 'summary', 'start', 'end',] } }, { name: 'google-calendar_update_event', description: 'Updates an event', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, eventId: { type: 'string', description: 'Event identifier' }, summary: { type: 'string', description: 'Title of the event' }, description: { type: 'string', description: 'Description of the event' }, location: { type: 'string', description: 'Geographic location of the event' }, start: { type: 'object', description: 'Start time of the event' }, end: { type: 'object', description: 'End time of the event' }, attendees: { type: 'array', description: 'List of attendees' }, sendNotifications: { type: 'boolean', description: 'Whether to send notifications about the update' }, sendUpdates: { type: 'string', description: 'Whether to send notifications to attendees (all, externalOnly, none)' }, }, required: ['calendarId', 'eventId',] } }, { name: 'google-calendar_delete_event', description: 'Deletes an event', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, eventId: { type: 'string', description: 'Event identifier' }, sendNotifications: { type: 'boolean', description: 'Whether to send notifications about the deletion' }, sendUpdates: { type: 'string', description: 'Whether to send notifications to attendees (all, externalOnly, none)' }, }, required: ['calendarId', 'eventId',] } }, { name: 'google-calendar_quick_add', description: 'Creates an event based on a simple text string', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, text: { type: 'string', description: 'The text describing the event to be created (e.g., 'Meeting at Somewhere on June 3rd 10am-10:25am')' }, sendNotifications: { type: 'boolean', description: 'Whether to send notifications about the creation of the event' }, sendUpdates: { type: 'string', description: 'Whether to send notifications to attendees (all, externalOnly, none)' }, }, required: ['calendarId', 'text',] } }, { name: 'google-calendar_get_free_busy', description: 'Returns free/busy information for a set of calendars', inputSchema: { type: 'object', properties: { timeMin: { type: 'string', description: 'The start of the interval (RFC3339 timestamp)' }, timeMax: { type: 'string', description: 'The end of the interval (RFC3339 timestamp)' }, timeZone: { type: 'string', description: 'Time zone used in the response (default UTC)' }, items: { type: 'array', description: 'List of calendars and groups to query. Each item should have an 'id' field' }, }, required: ['timeMin', 'timeMax', 'items'] } }, { name: 'google-calendar_list_acl', description: 'Returns the rules in the access control list for the calendar', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, maxResults: { type: 'number', description: 'Maximum number of entries returned (default 100, max 250)' }, pageToken: { type: 'string', description: 'Token specifying which result page to return' }, showDeleted: { type: 'boolean', description: 'Whether to include deleted ACLs in the result' }, }, required: ['calendarId',] } }, { name: 'google-calendar_create_acl', description: 'Creates an access control rule', inputSchema: { type: 'object', properties: { calendarId: { type: 'string', description: 'Calendar identifier. Use 'primary' for the primary calendar' }, role: { type: 'string', description: 'The role assigned to the scope (none, freeBusyReader, reader, writer, owner)' }, scope: { type: 'object', description: 'The scope of the rule. Must include 'type' (user, group, domain, public) and 'value' (email or domain)' }, sendNotifications: { type: 'boolean', description: 'Whether to send notifications about the sharing' }, }, required: ['calendarId', 'role', 'scope',] } } ]; } canHandle(toolName) { const supportedTools = [ 'google-calendar_list_calendars', 'google-calendar_get_calendar', 'google-calendar_create_calendar', 'google-calendar_update_calendar', 'google-calendar_delete_calendar', 'google-calendar_list_events', 'google-calendar_get_event', 'google-calendar_create_event', 'google-calendar_update_event', 'google-calendar_delete_event', 'google-calendar_quick_add', 'google-calendar_get_free_busy', 'google-calendar_list_acl', 'google-calendar_create_acl' ]; return supportedTools.includes(toolName); } async executeTool(name, args) { const startTime = Date.now(); this.logger.logToolStart(name, args); await this.ensureInitialized(); // Validate tool is supported if (!this.canHandle(name)) { this.logger.error('TOOL_ERROR', 'Unknown tool requested', { tool: name, supportedTools: ['google-calendar_list_calendars', 'google-calendar_get_calendar', 'google-calendar_create_calendar', 'google-calendar_update_calendar', 'google-calendar_delete_calendar', 'google-calendar_list_events', 'google-calendar_get_event', 'google-calendar_create_event', 'google-calendar_update_event', 'google-calendar_delete_event', 'google-calendar_quick_add', 'google-calendar_get_free_busy', 'google-calendar_list_acl', 'google-calendar_create_acl'] }); throw new Error(`Unknown tool: ${name}`); } // Validate required parameters this.logger.debug('PARAM_VALIDATION', 'Validating tool parameters', { tool: name, providedArgs: Object.keys(args || {}) }); try { let result; switch (name) { case 'google-calendar_list_calendars': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_list_calendars', clientMethod: 'listCalendars' }); result = await this.client.listCalendars(args); break; case 'google-calendar_get_calendar': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_get_calendar', clientMethod: 'getCalendar' }); result = await this.client.getCalendar(args); break; case 'google-calendar_create_calendar': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_create_calendar', clientMethod: 'createCalendar' }); result = await this.client.createCalendar(args); break; case 'google-calendar_update_calendar': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_update_calendar', clientMethod: 'updateCalendar' }); result = await this.client.updateCalendar(args); break; case 'google-calendar_delete_calendar': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_delete_calendar', clientMethod: 'deleteCalendar' }); result = await this.client.deleteCalendar(args); break; case 'google-calendar_list_events': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_list_events', clientMethod: 'listEvents' }); result = await this.client.listEvents(args); break; case 'google-calendar_get_event': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_get_event', clientMethod: 'getEvent' }); result = await this.client.getEvent(args); break; case 'google-calendar_create_event': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_create_event', clientMethod: 'createEvent' }); result = await this.client.createEvent(args); break; case 'google-calendar_update_event': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_update_event', clientMethod: 'updateEvent' }); result = await this.client.updateEvent(args); break; case 'google-calendar_delete_event': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_delete_event', clientMethod: 'deleteEvent' }); result = await this.client.deleteEvent(args); break; case 'google-calendar_quick_add': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_quick_add', clientMethod: 'quickAdd' }); result = await this.client.quickAdd(args); break; case 'google-calendar_get_free_busy': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_get_free_busy', clientMethod: 'getFreeBusy' }); result = await this.client.getFreeBusy(args); break; case 'google-calendar_list_acl': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_list_acl', clientMethod: 'listAcl' }); result = await this.client.listAcl(args); break; case 'google-calendar_create_acl': this.logger.debug('TOOL_EXECUTE', 'Calling client method', { tool: 'google-calendar_create_acl', clientMethod: 'createAcl' }); result = await this.client.createAcl(args); break; default: throw new Error(`Unknown tool: ${name}`); } const duration = Date.now() - startTime; this.logger.logToolSuccess(name, duration, result); // Format the result for MCP (OAuth templates only) return { content: [ { type: 'text', text: typeof result === 'string' ? result : JSON.stringify(result, null, 2) } ] }; } catch (error) { const duration = Date.now() - startTime; const errorMessage = error instanceof Error ? error.message : String(error); this.logger.logToolError(name, error, duration, args); return { content: [ { type: 'text', text: `Error: ${errorMessage}` } ], isError: true }; } } } //# sourceMappingURL=google-calendar-tools.js.map