diff --git a/src/__pycache__/caldav_client.cpython-314.pyc b/src/__pycache__/caldav_client.cpython-314.pyc index eea7ef1..c5ea334 100644 Binary files a/src/__pycache__/caldav_client.cpython-314.pyc and b/src/__pycache__/caldav_client.cpython-314.pyc differ diff --git a/src/caldav_client.py b/src/caldav_client.py index 11202cc..2c23075 100644 --- a/src/caldav_client.py +++ b/src/caldav_client.py @@ -71,17 +71,43 @@ class CalDAVClient: }) return results - def create_event(self, calendar_name: str, summary: str, start_time: Union[datetime, date], end_time: Union[datetime, date], description: str = "", recurrence: Optional[Dict] = None) -> str: + def create_event(self, calendar_name: str, summary: str, start_time: Union[datetime, date], end_time: Union[datetime, date], description: str = "", recurrence: Optional[Dict] = None, alarm_minutes: Optional[int] = None) -> str: calendar = self._get_calendar(calendar_name) - event = calendar.save_event( - dtstart=start_time, - dtend=end_time, - summary=summary, - description=description, - rrule=recurrence - ) - # Re-parse to get the UID, though library might provide it - ical = icalendar.Calendar.from_ical(event.data) + + # Build raw ical for better control + cal = icalendar.Calendar() + cal.add('prodid', '-//MCP CalDAV Server//EN') + cal.add('version', '2.0') + + event = icalendar.Event() + event.add('summary', summary) + event.add('description', description) + + if isinstance(start_time, datetime): + event.add('dtstart', start_time) + event.add('dtend', end_time) + else: + event.add('dtstart', start_time) + event.add('dtend', end_time) + + if recurrence: + event.add('rrule', recurrence) + + if alarm_minutes is not None: + alarm = icalendar.Alarm() + alarm.add('action', 'DISPLAY') + alarm.add('description', f'Reminder: {summary}') + # Use a proper timedelta or iCalendar DURATION string + from datetime import timedelta + alarm.add('trigger', timedelta(minutes=-alarm_minutes)) + event.add_component(alarm) + + cal.add_component(event) + + saved_event = calendar.save_event(cal.to_ical()) + + # Re-parse to get the UID + ical = icalendar.Calendar.from_ical(saved_event.data) for component in ical.walk(): if component.name == "VEVENT": return str(component.get("uid")) diff --git a/src/server.py b/src/server.py index c9745b5..77ca134 100644 --- a/src/server.py +++ b/src/server.py @@ -72,7 +72,7 @@ def parse_rrule(rrule_str: str) -> dict: return rrule @mcp.tool() -def create_event(calendar_name: str, summary: str, start_time: str, end_time: str, description: str = "", all_day: bool = False, recurrence: Optional[str] = None) -> str: +def create_event(calendar_name: str, summary: str, start_time: str, end_time: str, description: str = "", all_day: bool = False, recurrence: Optional[str] = None, alarm_minutes: Optional[int] = None) -> str: """ Creates a new event. @@ -84,6 +84,7 @@ def create_event(calendar_name: str, summary: str, start_time: str, end_time: st description: Event description. all_day: Set to True for all-day events (start/end time will be treated as dates). recurrence: RRULE string, e.g., "FREQ=DAILY;COUNT=10". + alarm_minutes: Minutes before the event to trigger an alarm/reminder. """ if not client: return "Error: CalDAV client not initialized" @@ -98,7 +99,7 @@ def create_event(calendar_name: str, summary: str, start_time: str, end_time: st rrule_dict = parse_rrule(recurrence) if recurrence else None - result = client.create_event(calendar_name, summary, dt_start, dt_end, description, rrule_dict) + result = client.create_event(calendar_name, summary, dt_start, dt_end, description, rrule_dict, alarm_minutes) return f"Event created: {result}" except Exception as e: return f"Error creating event: {str(e)}"