MCP Personal Assistant Agent

/** * Calendar Module Functions * Provides MCP functions for interacting with calendar services */ import config from '../../config/index.js'; import logger from '../../utils/logger.js'; import { getGoogleCalendarClient } from './providers/google.js'; // Get the default calendar provider from config const defaultProvider = config.modules.calendar.defaultProvider; /** * Get calendar events within a specified time range */ const getEvents = { description: "Get calendar events within a specified time range", parameters: { properties: { startDate: { type: "string", description: "Start date in ISO format (YYYY-MM-DD) or relative format like 'today', 'tomorrow'" }, endDate: { type: "string", description: "End date in ISO format (YYYY-MM-DD) or relative format like 'today', 'tomorrow'" }, calendarId: { type: "string", description: "ID of the calendar to fetch events from (defaults to primary calendar)" }, maxResults: { type: "number", description: "Maximum number of events to return" }, provider: { type: "string", description: "Calendar provider to use (google, apple, outlook)" } }, required: ["startDate"] }, async handler(params) { try { const provider = params.provider || defaultProvider; const calendarId = params.calendarId || 'primary'; // Format dates if they're relative const startDate = formatDate(params.startDate); const endDate = params.endDate ? formatDate(params.endDate) : null; logger.info(`Fetching events from ${startDate} to ${endDate || 'indefinite'} using ${provider} provider`); // Get events based on the provider if (provider === 'google') { const client = await getGoogleCalendarClient(); return await getGoogleEvents(client, { calendarId, startDate, endDate, maxResults: params.maxResults || 10 }); } else { throw new Error(`Calendar provider '${provider}' is not supported or enabled`); } } catch (error) { logger.error(`Failed to get calendar events: ${error.message}`); throw new Error(`Failed to get calendar events: ${error.message}`); } } }; /** * Create a new calendar event */ const createEvent = { description: "Create a new calendar event", parameters: { properties: { summary: { type: "string", description: "Title/summary of the event" }, startDateTime: { type: "string", description: "Start date and time in ISO format or natural language" }, endDateTime: { type: "string", description: "End date and time in ISO format or natural language" }, description: { type: "string", description: "Description of the event" }, location: { type: "string", description: "Location of the event" }, attendees: { type: "array", items: { type: "string" }, description: "List of email addresses of attendees" }, calendarId: { type: "string", description: "ID of the calendar to create the event in (defaults to primary calendar)" }, provider: { type: "string", description: "Calendar provider to use (google, apple, outlook)" } }, required: ["summary", "startDateTime"] }, async handler(params) { try { const provider = params.provider || defaultProvider; const calendarId = params.calendarId || 'primary'; logger.info(`Creating event "${params.summary}" using ${provider} provider`); // Create event based on the provider if (provider === 'google') { const client = await getGoogleCalendarClient(); return await createGoogleEvent(client, { calendarId, summary: params.summary, startDateTime: params.startDateTime, endDateTime: params.endDateTime, description: params.description, location: params.location, attendees: params.attendees }); } else { throw new Error(`Calendar provider '${provider}' is not supported or enabled`); } } catch (error) { logger.error(`Failed to create calendar event: ${error.message}`); throw new Error(`Failed to create calendar event: ${error.message}`); } } }; /** * Update an existing calendar event */ const updateEvent = { description: "Update an existing calendar event", parameters: { properties: { eventId: { type: "string", description: "ID of the event to update" }, summary: { type: "string", description: "New title/summary of the event" }, startDateTime: { type: "string", description: "New start date and time in ISO format or natural language" }, endDateTime: { type: "string", description: "New end date and time in ISO format or natural language" }, description: { type: "string", description: "New description of the event" }, location: { type: "string", description: "New location of the event" }, attendees: { type: "array", items: { type: "string" }, description: "New list of email addresses of attendees" }, calendarId: { type: "string", description: "ID of the calendar containing the event (defaults to primary calendar)" }, provider: { type: "string", description: "Calendar provider to use (google, apple, outlook)" } }, required: ["eventId"] }, async handler(params) { try { const provider = params.provider || defaultProvider; const calendarId = params.calendarId || 'primary'; logger.info(`Updating event ${params.eventId} using ${provider} provider`); // Update event based on the provider if (provider === 'google') { const client = await getGoogleCalendarClient(); return await updateGoogleEvent(client, { calendarId, eventId: params.eventId, summary: params.summary, startDateTime: params.startDateTime, endDateTime: params.endDateTime, description: params.description, location: params.location, attendees: params.attendees }); } else { throw new Error(`Calendar provider '${provider}' is not supported or enabled`); } } catch (error) { logger.error(`Failed to update calendar event: ${error.message}`); throw new Error(`Failed to update calendar event: ${error.message}`); } } }; /** * Delete a calendar event */ const deleteEvent = { description: "Delete a calendar event", parameters: { properties: { eventId: { type: "string", description: "ID of the event to delete" }, calendarId: { type: "string", description: "ID of the calendar containing the event (defaults to primary calendar)" }, provider: { type: "string", description: "Calendar provider to use (google, apple, outlook)" } }, required: ["eventId"] }, async handler(params) { try { const provider = params.provider || defaultProvider; const calendarId = params.calendarId || 'primary'; logger.info(`Deleting event ${params.eventId} using ${provider} provider`); // Delete event based on the provider if (provider === 'google') { const client = await getGoogleCalendarClient(); return await deleteGoogleEvent(client, { calendarId, eventId: params.eventId }); } else { throw new Error(`Calendar provider '${provider}' is not supported or enabled`); } } catch (error) { logger.error(`Failed to delete calendar event: ${error.message}`); throw new Error(`Failed to delete calendar event: ${error.message}`); } } }; /** * List available calendars */ const listCalendars = { description: "List available calendars", parameters: { properties: { provider: { type: "string", description: "Calendar provider to use (google, apple, outlook)" } }, required: [] }, async handler(params) { try { const provider = params.provider || defaultProvider; logger.info(`Listing calendars using ${provider} provider`); // List calendars based on the provider if (provider === 'google') { const client = await getGoogleCalendarClient(); return await listGoogleCalendars(client); } else { throw new Error(`Calendar provider '${provider}' is not supported or enabled`); } } catch (error) { logger.error(`Failed to list calendars: ${error.message}`); throw new Error(`Failed to list calendars: ${error.message}`); } } }; // Helper functions (would be implemented in the actual provider files) async function getGoogleEvents(client, options) { // This would be implemented in the Google provider return { message: "This is a placeholder. Google Calendar integration would be implemented here." }; } async function createGoogleEvent(client, eventData) { // This would be implemented in the Google provider return { message: "This is a placeholder. Google Calendar integration would be implemented here." }; } async function updateGoogleEvent(client, eventData) { // This would be implemented in the Google provider return { message: "This is a placeholder. Google Calendar integration would be implemented here." }; } async function deleteGoogleEvent(client, options) { // This would be implemented in the Google provider return { message: "This is a placeholder. Google Calendar integration would be implemented here." }; } async function listGoogleCalendars(client) { // This would be implemented in the Google provider return { message: "This is a placeholder. Google Calendar integration would be implemented here." }; } /** * Helper function to format relative dates */ function formatDate(dateStr) { if (!dateStr) return null; // Handle relative dates if (dateStr.toLowerCase() === 'today') { const today = new Date(); return today.toISOString().split('T')[0]; } else if (dateStr.toLowerCase() === 'tomorrow') { const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); return tomorrow.toISOString().split('T')[0]; } else if (dateStr.toLowerCase() === 'yesterday') { const yesterday = new Date(); yesterday.setDate(yesterday.getDate() - 1); return yesterday.toISOString().split('T')[0]; } // Return the date as-is if it doesn't match any relative format return dateStr; } export default [ getEvents, createEvent, updateEvent, deleteEvent, listCalendars ];