sqlite-explorer-fastmcp-mcp-server

by hannesrudolph
Verified
from googleapiclient.discovery import build from . import gauth import logging import traceback from datetime import datetime import pytz class CalendarService(): def __init__(self, user_id: str): credentials = gauth.get_stored_credentials(user_id=user_id) if not credentials: raise RuntimeError("No Oauth2 credentials stored") self.service = build('calendar', 'v3', credentials=credentials) # Note: using v3 for Calendar API def list_calendars(self) -> list: """ Lists all calendars accessible by the user. Returns: list: List of calendar objects with their metadata """ try: calendar_list = self.service.calendarList().list().execute() calendars = [] for calendar in calendar_list.get('items', []): if calendar.get('kind') == 'calendar#calendarListEntry': calendars.append({ 'id': calendar.get('id'), 'summary': calendar.get('summary'), 'primary': calendar.get('primary', False), 'time_zone': calendar.get('timeZone'), 'etag': calendar.get('etag'), 'access_role': calendar.get('accessRole') }) return calendars except Exception as e: logging.error(f"Error retrieving calendars: {str(e)}") logging.error(traceback.format_exc()) return [] def get_events(self, time_min=None, time_max=None, max_results=250, show_deleted=False, calendar_id: str ='primary'): """ Retrieve calendar events within a specified time range. Args: time_min (str, optional): Start time in RFC3339 format. Defaults to current time. time_max (str, optional): End time in RFC3339 format max_results (int): Maximum number of events to return (1-2500) show_deleted (bool): Whether to include deleted events Returns: list: List of calendar events """ try: # If no time_min specified, use current time if not time_min: time_min = datetime.now(pytz.UTC).isoformat() # Ensure max_results is within limits max_results = min(max(1, max_results), 2500) # Prepare parameters params = { 'calendarId': calendar_id, 'timeMin': time_min, 'maxResults': max_results, 'singleEvents': True, 'orderBy': 'startTime', 'showDeleted': show_deleted } # Add optional time_max if specified if time_max: params['timeMax'] = time_max # Execute the events().list() method events_result = self.service.events().list(**params).execute() # Extract the events events = events_result.get('items', []) # Process and return the events processed_events = [] for event in events: processed_event = { 'id': event.get('id'), 'summary': event.get('summary'), 'description': event.get('description'), 'start': event.get('start'), 'end': event.get('end'), 'status': event.get('status'), 'creator': event.get('creator'), 'organizer': event.get('organizer'), 'attendees': event.get('attendees'), 'location': event.get('location'), 'hangoutLink': event.get('hangoutLink'), 'conferenceData': event.get('conferenceData'), 'recurringEventId': event.get('recurringEventId') } processed_events.append(processed_event) return processed_events except Exception as e: logging.error(f"Error retrieving calendar events: {str(e)}") logging.error(traceback.format_exc()) return [] def create_event(self, summary: str, start_time: str, end_time: str, location: str | None = None, description: str | None = None, attendees: list | None = None, send_notifications: bool = True, timezone: str | None = None, calendar_id : str = 'primary') -> dict | None: """ Create a new calendar event. Args: summary (str): Title of the event start_time (str): Start time in RFC3339 format end_time (str): End time in RFC3339 format location (str, optional): Location of the event description (str, optional): Description of the event attendees (list, optional): List of attendee email addresses send_notifications (bool): Whether to send notifications to attendees timezone (str, optional): Timezone for the event (e.g. 'America/New_York') Returns: dict: Created event data or None if creation fails """ try: # Prepare event data event = { 'summary': summary, 'start': { 'dateTime': start_time, 'timeZone': timezone or 'UTC', }, 'end': { 'dateTime': end_time, 'timeZone': timezone or 'UTC', } } # Add optional fields if provided if location: event['location'] = location if description: event['description'] = description if attendees: event['attendees'] = [{'email': email} for email in attendees] # Create the event created_event = self.service.events().insert( calendarId=calendar_id, body=event, sendNotifications=send_notifications ).execute() return created_event except Exception as e: logging.error(f"Error creating calendar event: {str(e)}") logging.error(traceback.format_exc()) return None def delete_event(self, event_id: str, send_notifications: bool = True, calendar_id: str = 'primary') -> bool: """ Delete a calendar event by its ID. Args: event_id (str): The ID of the event to delete send_notifications (bool): Whether to send cancellation notifications to attendees Returns: bool: True if deletion was successful, False otherwise """ try: self.service.events().delete( calendarId=calendar_id, eventId=event_id, sendNotifications=send_notifications ).execute() return True except Exception as e: logging.error(f"Error deleting calendar event {event_id}: {str(e)}") logging.error(traceback.format_exc()) return False