/** * List events functionality */ const config = require('../config'); const { callGraphAPI } = require('../utils/graph-api'); const { ensureAuthenticated } = require('../auth'); /** * List events handler * @param {object} args - Tool arguments * @returns {object} - MCP response */ async function handleListEvents(args) { const count = Math.min(parseInt(args.count, 10) || 10, config.MAX_RESULT_COUNT); // Resolve date range — accept plain YYYY-MM-DD or full ISO datetime const toISO = (dateStr, endOfDay = false) => { if (!dateStr) return null; // If just a date (no T), append time component if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) { return endOfDay ? `${dateStr}T23:59:59Z` : `${dateStr}T00:00:00Z`; } return new Date(dateStr).toISOString(); }; const startISO = toISO(args.startDate) || new Date().toISOString(); const endISO = toISO(args.endDate, true); try { // Get access token const accessToken = await ensureAuthenticated(); // Build API endpoint let endpoint = 'me/events'; // Build date filter const filterParts = [`start/dateTime ge '${startISO}'`]; if (endISO) filterParts.push(`end/dateTime le '${endISO}'`); // Add query parameters const queryParams = { $top: count, $orderby: 'start/dateTime', $filter: filterParts.join(' and '), $select: config.CALENDAR_SELECT_FIELDS }; // Make API call const response = await callGraphAPI(accessToken, 'GET', endpoint, null, queryParams); if (!response.value || response.value.length === 0) { return { content: [{ type: "text", text: "No calendar events found." }] }; } // Format results const eventList = response.value.map((event, index) => { const startDate = new Date(event.start.dateTime).toLocaleString(event.start.timeZone); const endDate = new Date(event.end.dateTime).toLocaleString(event.end.timeZone); const location = event.location.displayName || 'No location'; return `${index + 1}. ${event.subject} - Location: ${location}\nStart: ${startDate}\nEnd: ${endDate}\nSubject: ${event.subject}\nSummary: ${event.bodyPreview}\nID: ${event.id}\n`; }).join("\n"); return { content: [{ type: "text", text: `Found ${response.value.length} events:\n\n${eventList}` }] }; } catch (error) { if (error.message === 'Authentication required') { return { content: [{ type: "text", text: "Authentication required. Please use the 'authenticate' tool first." }] }; } return { content: [{ type: "text", text: `Error listing events: ${error.message}` }] }; } } module.exports = handleListEvents;