update_calendar_event
Modify calendar event details including date, time, title, description, or location to keep your schedule current and accurate.
Instructions
Update/move a calendar event (change date, time, title, or description)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| date | No | ||
| description | No | ||
| duration_minutes | No | ||
| event_id | Yes | ||
| location | No | ||
| time | No | ||
| title | No |
Implementation Reference
- src/obsidian_mcp/server.py:1213-1342 (handler)MCP tool handler for update_calendar_event: orchestrates event retrieval, parameter parsing, calls CalendarService.update_event, updates linked Obsidian note frontmatter, and preserves Obsidian links in descriptions.name="update_calendar_event", description="Update/move a calendar event (change date, time, title, or description)", ) async def update_calendar_event( event_id: str, title: str = "", date: str = "", time: str = "", duration_minutes: int = 0, description: str = "", location: str = "", confirm: bool = False, ) -> str: """ Update a calendar event. Args: event_id: Calendar event ID to update title: New event title (optional) date: New date YYYY-MM-DD (optional) time: New time HH:MM (optional) duration_minutes: New duration in minutes (optional) description: New description (optional) location: New location (optional) confirm: Must be set to true to confirm event update Returns: Success message with updated details """ if not confirm: return ( "Error: Calendar event update requires explicit confirmation. " "Please set confirm=true to proceed with updating this event." ) if not event_id or not event_id.strip(): return "Error: Event ID cannot be empty" context = _get_context() try: calendar = context.get_calendar() # Get current event to preserve existing values current_event = calendar.get_event(event_id) # Parse new date/time if provided new_start = None new_end = None if date and time: try: event_datetime = datetime.strptime(f"{date} {time}", "%Y-%m-%d %H:%M") if duration_minutes > 0: new_end = event_datetime + timedelta(minutes=duration_minutes) else: # Preserve original duration current_start = current_event.get("start", {}) current_end = current_event.get("end", {}) if "dateTime" in current_start and "dateTime" in current_end: old_start = datetime.fromisoformat( current_start["dateTime"].replace("Z", "+00:00") ) old_end = datetime.fromisoformat( current_end["dateTime"].replace("Z", "+00:00") ) duration = (old_end - old_start).seconds // 60 new_end = event_datetime + timedelta(minutes=duration) new_start = event_datetime except ValueError as e: return f"Error: Invalid date/time format: {e}. Use YYYY-MM-DD and HH:MM" # Prepare update - preserve obsidian:// link if in description new_description = None if description: current_desc = current_event.get("description", "") # Check if there's an obsidian link to preserve if context.config.obsidian_url_base in current_desc: link_start = current_desc.find(context.config.obsidian_url_base) link_end = current_desc.find("\n", link_start) if link_end == -1: link_end = len(current_desc) obsidian_link = current_desc[link_start:link_end].strip() new_description = f"{description}\n\n{obsidian_link}" else: new_description = description # Update event updated_event = calendar.update_event( event_id=event_id, summary=title if title else None, start_datetime=new_start, end_datetime=new_end, description=new_description, location=location if location else None, ) # Update note frontmatter if date changed and we can find the linked note if new_start: current_desc = current_event.get("description", "") if context.config.obsidian_url_base in current_desc: link_start = current_desc.find(context.config.obsidian_url_base) note_path = current_desc[link_start + len(context.config.obsidian_url_base) :] note_path = note_path.split()[0] if note_path else "" if note_path and context.vault.note_exists(note_path): note = await context.vault.read_note(note_path) if note.frontmatter and "calendar_event_id" in note.frontmatter: await context.vault.update_frontmatter( note_path, { "calendar_event_date": new_start.strftime("%Y-%m-%d"), "calendar_event_time": new_start.strftime("%H:%M"), }, ) result = ["✅ Calendar event updated!"] result.append(f"Event: {updated_event.get('summary', 'Untitled')}") result.append(f"Link: {updated_event.get('htmlLink')}") if new_start: result.append(f"New time: {new_start.strftime('%Y-%m-%d %H:%M')}") return "\n".join(result) except CalendarError as e: logger.exception("Error updating calendar event") return f"Error: {e}" except Exception as e: logger.exception("Error updating calendar event") return f"Error updating calendar event: {e}"
- src/obsidian_mcp/calendar.py:218-278 (helper)Core implementation in CalendarService: fetches existing event via Google Calendar API, applies provided updates to summary, times, description, location, and executes the update.def update_event( self, event_id: str, summary: str | None = None, start_datetime: datetime | None = None, end_datetime: datetime | None = None, description: str | None = None, location: str | None = None, ) -> dict[str, Any]: """ Update an existing calendar event. Args: event_id: Event ID to update summary: New event title start_datetime: New start time end_datetime: New end time description: New description location: New location Returns: Updated event details Raises: CalendarError: If update fails """ service = self.get_service() try: # Get existing event event = service.events().get(calendarId=self.calendar_id, eventId=event_id).execute() # Update fields if summary is not None: event["summary"] = summary if start_datetime is not None: event["start"] = { "dateTime": start_datetime.isoformat(), "timeZone": "UTC", } if end_datetime is not None: event["end"] = { "dateTime": end_datetime.isoformat(), "timeZone": "UTC", } if description is not None: event["description"] = description if location is not None: event["location"] = location # Update event updated_event = ( service.events() .update(calendarId=self.calendar_id, eventId=event_id, body=event) .execute() ) logger.info(f"Updated calendar event: {event_id}") return updated_event # type: ignore[no-any-return] except HttpError as e: raise CalendarError(f"Failed to update event: {e}") from e
- src/obsidian_mcp/server.py:1213-1216 (registration)MCP tool registration decorator specifying the tool name and description.name="update_calendar_event", description="Update/move a calendar event (change date, time, title, or description)", ) async def update_calendar_event(