Skip to main content
Glama
calendars.ts7.03 kB
import axios from 'axios'; // Get port from environment variable or use default 8080 const API_PORT = process.env.MAC_API_BRIDGE_PORT || '8080'; // Base URL for the Calendar API Bridge const API_BASE_URL = `http://localhost:${API_PORT}`; /** * Validate and format a date string for the Calendar API Bridge * Supported formats: * 1. ISO8601 with milliseconds and Z timezone (recommended): 2025-03-09T10:00:00.000Z * 2. ISO8601 without milliseconds: 2025-03-09T10:00:00 * 3. ISO8601 with space instead of T: 2025-03-09 10:00:00 * 4. ISO8601 with forward slashes: 2025/03/09 10:00:00 */ function formatDate(date: Date | string | null): string | null { if (!date) return null; try { // If it's already a Date object, just return ISO string if (date instanceof Date) { if (isNaN(date.getTime())) return null; return date.toISOString(); } // Handle string input const dateStr = date.trim(); // Try parsing the date string as-is first let dateObj = new Date(dateStr); // If the direct parse failed, try alternative formats if (isNaN(dateObj.getTime())) { // Handle forward slash format if (dateStr.includes('/')) { dateObj = new Date(dateStr.replace(/\//g, '-')); } // Handle space instead of T else if (dateStr.includes(' ')) { dateObj = new Date(dateStr.replace(' ', 'T')); } } if (isNaN(dateObj.getTime())) { console.error('Invalid date format:', dateStr); return null; } return dateObj.toISOString(); } catch (error) { console.error('Date formatting error:', error); return null; } } /** * Get all calendars */ export async function getCalendars(): Promise<any[]> { try { const response = await axios.get(`${API_BASE_URL}/calendars`); return response.data; } catch (error) { console.error('Failed to get calendars:', error); throw new Error(`Failed to get calendars: ${error}`); } } /** * Get a specific calendar by ID */ export async function getCalendar(calendarId: string): Promise<any> { try { const response = await axios.get(`${API_BASE_URL}/calendars/${calendarId}`); return response.data; } catch (error) { console.error(`Failed to get calendar with ID "${calendarId}":`, error); throw new Error(`Failed to get calendar: ${error}`); } } /** * Get events from a specific calendar */ export async function getCalendarEvents(calendarId: string): Promise<any[]> { try { const response = await axios.get(`${API_BASE_URL}/calendars/${calendarId}/events`); return response.data; } catch (error) { console.error(`Failed to get events from calendar "${calendarId}":`, error); throw new Error(`Failed to get calendar events: ${error}`); } } /** * Get a specific event by ID */ export async function getCalendarEvent(calendarId: string, eventId: string): Promise<any> { try { const response = await axios.get(`${API_BASE_URL}/calendars/${calendarId}/events/${eventId}`); return response.data; } catch (error) { console.error(`Failed to get event "${eventId}" from calendar "${calendarId}":`, error); throw new Error(`Failed to get calendar event: ${error}`); } } /** * Create a new calendar */ export async function createCalendar(title: string, color?: string): Promise<any> { try { const response = await axios.post(`${API_BASE_URL}/calendars`, { title, color }); return response.data; } catch (error) { console.error(`Failed to create calendar "${title}":`, error); throw new Error(`Failed to create calendar: ${error}`); } } /** * Create a new event in a calendar */ export async function createCalendarEvent( calendarId: string, title: string, startDate: string, endDate: string, location?: string, notes?: string ): Promise<any> { try { // Format dates using our flexible date formatter const formattedStartDate = formatDate(startDate); const formattedEndDate = formatDate(endDate); if (!formattedStartDate || !formattedEndDate) { throw new Error('Invalid date format provided. Please use one of the supported formats.'); } // Create the event data const eventData: any = { title, startDate: formattedStartDate, endDate: formattedEndDate }; // Add optional fields if provided if (location) eventData.location = location; if (notes) eventData.notes = notes; // Send the request const response = await axios.post( `${API_BASE_URL}/calendars/${calendarId}/events`, eventData ); return response.data; } catch (error) { console.error(`Failed to create event "${title}" in calendar "${calendarId}":`, error); throw new Error(`Failed to create calendar event: ${error}`); } } /** * Update an existing event */ export async function updateCalendarEvent( calendarId: string, eventId: string, updates: { title?: string; startDate?: string; endDate?: string; location?: string; notes?: string; } ): Promise<any> { try { const updatedData: any = { ...updates }; // Format dates if provided if (updatedData.startDate) { const formattedStartDate = formatDate(updatedData.startDate); if (!formattedStartDate) { throw new Error('Invalid start date format provided. Please use one of the supported formats.'); } updatedData.startDate = formattedStartDate; } if (updatedData.endDate) { const formattedEndDate = formatDate(updatedData.endDate); if (!formattedEndDate) { throw new Error('Invalid end date format provided. Please use one of the supported formats.'); } updatedData.endDate = formattedEndDate; } console.error('Updating event with data:', JSON.stringify(updatedData)); // Send the request const response = await axios.put( `${API_BASE_URL}/calendars/${calendarId}/events/${eventId}`, updatedData ); return response.data; } catch (error) { console.error(`Failed to update event "${eventId}" in calendar "${calendarId}":`, error); throw new Error(`Failed to update calendar event: ${error}`); } } /** * Delete an event */ export async function deleteCalendarEvent(calendarId: string, eventId: string): Promise<boolean> { try { await axios.delete(`${API_BASE_URL}/calendars/${calendarId}/events/${eventId}`); return true; } catch (error) { console.error(`Failed to delete event "${eventId}" from calendar "${calendarId}":`, error); throw new Error(`Failed to delete calendar event: ${error}`); } } /** * Delete a calendar */ export async function deleteCalendar(calendarId: string): Promise<boolean> { try { await axios.delete(`${API_BASE_URL}/calendars/${calendarId}`); return true; } catch (error) { console.error(`Failed to delete calendar "${calendarId}":`, error); throw new Error(`Failed to delete calendar: ${error}`); } }

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/shadowfax92/apple-calendar-mcp'

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