Skip to main content
Glama

Enhanced Outlook MCP Server

by jibberish69
delete-event.js6.34 kB
const config = require('../config'); const logger = require('../utils/logger'); const { GraphApiClient } = require('../utils/graph-api'); /** * Delete a calendar event * @param {Object} params - Tool parameters * @returns {Promise<Object>} - Deletion result */ async function deleteEventHandler(params = {}) { const userId = params.userId || 'default'; const eventId = params.eventId; if (!eventId) { return { status: 'error', message: 'Event ID is required' }; } try { logger.info(`Deleting calendar event ${eventId} for user ${userId}`); const graphClient = new GraphApiClient(userId); // Delete the event await graphClient.delete(`/me/events/${eventId}`); return { status: 'success', message: 'Event deleted successfully', eventId }; } catch (error) { logger.error(`Error deleting calendar event: ${error.message}`); return { status: 'error', message: `Failed to delete calendar event: ${error.message}` }; } } /** * Cancel a calendar event * @param {Object} params - Tool parameters * @returns {Promise<Object>} - Cancellation result */ async function cancelEventHandler(params = {}) { const userId = params.userId || 'default'; const eventId = params.eventId; if (!eventId) { return { status: 'error', message: 'Event ID is required' }; } try { logger.info(`Cancelling calendar event ${eventId} for user ${userId}`); const graphClient = new GraphApiClient(userId); // Create cancellation data const cancellationData = { comment: params.comment || 'Event cancelled' }; // Cancel the event (sends cancellation notifications to attendees) await graphClient.post(`/me/events/${eventId}/cancel`, cancellationData); return { status: 'success', message: 'Event cancelled successfully', eventId }; } catch (error) { logger.error(`Error cancelling calendar event: ${error.message}`); return { status: 'error', message: `Failed to cancel calendar event: ${error.message}` }; } } /** * Find available meeting times * @param {Object} params - Tool parameters * @returns {Promise<Object>} - Available meeting times */ async function findMeetingTimesHandler(params = {}) { const userId = params.userId || 'default'; try { logger.info(`Finding available meeting times for user ${userId}`); const graphClient = new GraphApiClient(userId); // Build meeting time suggestions request const findTimesRequest = { attendees: formatAttendees(params.attendees), timeConstraint: { timeSlots: [ { start: { dateTime: params.startDateTime || new Date().toISOString(), timeZone: params.timeZone || 'UTC' }, end: { dateTime: params.endDateTime || getDefaultEndDateTime(), timeZone: params.timeZone || 'UTC' } } ] }, meetingDuration: params.duration || 'PT30M', // ISO8601 duration format returnSuggestionReasons: true, minimumAttendeePercentage: params.minimumAttendeePercentage || 100 }; // If locations are provided if (params.locations && Array.isArray(params.locations)) { findTimesRequest.locationConstraint = { isRequired: params.isLocationRequired === true, suggestLocation: params.suggestLocation === true, locations: params.locations.map(location => ({ displayName: typeof location === 'string' ? location : location.displayName || location.name, locationEmailAddress: typeof location === 'object' ? location.email : undefined })) }; } // Find meeting times const response = await graphClient.post('/me/findMeetingTimes', findTimesRequest); return { status: 'success', meetingTimeSuggestions: response.meetingTimeSuggestions || [], emptySuggestionsReason: response.emptySuggestionsReason }; } catch (error) { logger.error(`Error finding meeting times: ${error.message}`); return { status: 'error', message: `Failed to find meeting times: ${error.message}` }; } } /** * Get default end date time (7 days from now) * @returns {string} - ISO string for 7 days from now */ function getDefaultEndDateTime() { const now = new Date(); const sevenDaysLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000); return sevenDaysLater.toISOString(); } /** * Format attendees for API * @param {Array|string|Object} attendees - Attendees in various formats * @returns {Array} - Formatted attendees */ function formatAttendees(attendees) { if (!attendees) { return []; } // Handle string with comma or semicolon separators if (typeof attendees === 'string') { attendees = attendees.split(/[,;]/).map(a => a.trim()).filter(Boolean); } // Ensure it's an array if (!Array.isArray(attendees)) { attendees = [attendees]; } // Format each attendee return attendees.map(attendee => { // If already in the correct format if (typeof attendee === 'object' && attendee.emailAddress) { return attendee; } // Handle string in format "Name <email@example.com>" if (typeof attendee === 'string') { const match = attendee.match(/^(.*?)\s*<([^>]+)>$/); if (match) { return { emailAddress: { name: match[1].trim(), address: match[2].trim() }, type: 'required' }; } // Just an email address return { emailAddress: { address: attendee.trim() }, type: 'required' }; } // Handle object with name and email properties if (typeof attendee === 'object' && attendee.email) { return { emailAddress: { name: attendee.name || '', address: attendee.email }, type: attendee.type || 'required' }; } // Default case return { emailAddress: { address: String(attendee) }, type: 'required' }; }); } module.exports = { deleteEventHandler, cancelEventHandler, findMeetingTimesHandler };

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/jibberish69/enhanced-outlook-mcp'

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