diff --git a/skills/google-calendar/SKILL.md b/skills/google-calendar/SKILL.md index 180820b..24abd8e 100644 --- a/skills/google-calendar/SKILL.md +++ b/skills/google-calendar/SKILL.md @@ -31,71 +31,89 @@ OpenClaw assigns Google Calendar colors automatically based on event titles or e --- -## 🛠️ MCP Tools +## 🛠️ MCP Tools & CLI Fallbacks -You have access to 8 dedicated calendar tools: +> [!IMPORTANT] +> **OpenClaw Tool Naming:** In OpenClaw, MCP tools from the `calendar` server are prefixed with `calendar__`: +> - `calendar__calendar_list_events` +> - `calendar__calendar_check_conflicts` +> - `calendar__calendar_create_event` +> - `calendar__calendar_update_event` +> - `calendar__calendar_delete_event` +> - `calendar__calendar_move_event` +> - `calendar__calendar_find_free_slots` +> - `calendar__calendar_get_event` +> +> If MCP execution is unavailable or fails with `Tool not found`, ALWAYS fall back to the direct Python CLI: +> ```bash +> # Suchen: +> /home/node/.openclaw/mcp-venv/bin/python3 /home/node/mop-skills/mop-skills/skills/google-calendar/scripts/google_calendar.py list --calendar regensburg --query "Suchbegriff" +> +> # Löschen (inkl. Serie): +> /home/node/.openclaw/mcp-venv/bin/python3 /home/node/mop-skills/mop-skills/skills/google-calendar/scripts/google_calendar.py delete --calendar regensburg --series +> ``` -1. `calendar_list_events(calendar="family"|"regensburg", time_min=None, time_max=None, query=None, category=None, color_id=None, max_results=25)`: - - Lists appointments within a timeframe including start/end, color name, location, recurrence status, and description. - - `time_min` / `time_max`: ISO format (e.g. `2026-09-20` or `2026-09-20T08:00:00`). Defaults to start of today until 30 days ahead. Automatically expands recurring events into individual occurrences. - - `category` / `color_id`: Filter by person or category (e.g. `category="arzt"` or `color_id="11"`). - - `query`: Text filter to search summaries and descriptions. +### 1. `calendar__calendar_list_events(calendar="family"|"regensburg", time_min=None, time_max=None, query=None, category=None, color_id=None, max_results=25)`: +- Lists appointments within a timeframe including start/end, color name, location, recurrence status, and description. +- `time_min` / `time_max`: ISO format (e.g. `2026-09-20` or `2026-09-20T08:00:00`). Defaults to start of today until 30 days ahead. Automatically expands recurring events into individual occurrences. +- `category` / `color_id`: Filter by person or category (e.g. `category="arzt"` or `color_id="11"`). +- `query`: Text filter to search summaries and descriptions. -2. `calendar_check_conflicts(calendar="family"|"regensburg", start_time, end_time=None, buffer_minutes=15)`: - - Proactively checks if a proposed slot conflicts with existing events or leaves less than `buffer_minutes` travel buffer. - - Returns `has_conflict`, `direct_conflicts`, `has_buffer_warning`, and `buffer_warnings`. +### 2. `calendar__calendar_check_conflicts(calendar="family"|"regensburg", start_time, end_time=None, buffer_minutes=15)`: +- Proactively checks if a proposed slot conflicts with existing events or leaves less than `buffer_minutes` travel buffer. +- Returns `has_conflict`, `direct_conflicts`, `has_buffer_warning`, and `buffer_warnings`. -3. `calendar_create_event(calendar="family"|"regensburg", summary, start_time, end_time=None, recurrence=None, show_as_busy=True, transparency=None, reminder_minutes=None, category=None, color_id=None, description=None, location=None, all_day=False, inclusive_end=True, check_conflicts=True)`: - - Adds a new appointment with automatic color coding, recurrence, transparency, phone reminders, and overlap detection. - - **`recurrence`**: Standard RFC 5545 rule or shortcuts: - - `recurrence="RRULE:FREQ=WEEKLY;BYDAY=SA"` (weekly Saturday market) - - `recurrence="RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA;UNTIL=20261231T230000Z"` (daily except Sun until year end) - - Shortcuts: `"weekly"`, `"daily"`, `"monthly"`, `"workdays"`. - - **`show_as_busy` / `transparency`**: - - For **Regensburg city events, markets, festivals, exhibitions**: set `show_as_busy=False` or `transparency="transparent"` so they are visible on the calendar without blocking family schedule slots or triggering false conflict warnings! - - **`reminder_minutes`**: List of popup alert minutes before event (e.g. `[15, 60]` or `1440` for 1 day before). - - **`inclusive_end`**: For multi-day all-day events, automatically includes the end date without off-by-one errors. +### 3. `calendar__calendar_create_event(calendar="family"|"regensburg", summary, start_time, end_time=None, recurrence=None, show_as_busy=True, transparency=None, reminder_minutes=None, category=None, color_id=None, description=None, location=None, all_day=False, inclusive_end=True, check_conflicts=True)`: +- Adds a new appointment with automatic color coding, recurrence, transparency, phone reminders, and overlap detection. +- **`recurrence`**: Standard RFC 5545 rule or shortcuts: + - `recurrence="RRULE:FREQ=WEEKLY;BYDAY=SA"` + - Shortcuts: `"weekly"`, `"daily"`, `"monthly"`, `"workdays"`. +- **`show_as_busy` / `transparency`**: + - For **Regensburg city events, festivals, exhibitions**: set `show_as_busy=False` or `transparency="transparent"` so they are visible on the calendar without blocking family schedule slots or triggering false conflict warnings! +- **`reminder_minutes`**: List of popup alert minutes before event (e.g. `[15, 60]` or `1440` for 1 day before). +- **`inclusive_end`**: For multi-day all-day events, automatically includes the end date without off-by-one errors. -4. `calendar_update_event(calendar="family"|"regensburg", event_id, summary=None, start_time=None, end_time=None, recurrence=None, show_as_busy=None, transparency=None, reminder_minutes=None, update_series=False, category=None, color_id=None, description=None, location=None)`: - - Updates fields, recurrence, transparency, reminders, or recolors an existing event. - - `update_series=True`: If event is an occurrence of a series, updates the entire master series instead of just this single occurrence. +### 4. `calendar__calendar_update_event(calendar="family"|"regensburg", event_id, summary=None, start_time=None, end_time=None, recurrence=None, show_as_busy=None, transparency=None, reminder_minutes=None, update_series=False, category=None, color_id=None, description=None, location=None)`: +- Updates fields, recurrence, transparency, reminders, or recolors an existing event. +- `update_series=True`: If event is an occurrence of a series, updates the entire master series instead of just this single occurrence. -5. `calendar_delete_event(calendar="family"|"regensburg", event_id, delete_series=False)`: - - Deletes an event. - - `delete_series=True`: If event is part of a recurring series, deletes the entire recurring series instead of just this single occurrence. +### 5. `calendar__calendar_delete_event(calendar="family"|"regensburg", event_id, delete_series=False)`: +- Deletes an event. +- `delete_series=True`: If event is part of a recurring series, deletes the entire recurring series instead of just this single occurrence. -6. `calendar_move_event(event_id, source_calendar="family", destination_calendar="regensburg")`: - - Moves an event atomically from one calendar to another (e.g. turning an interesting city event from Regensburg into a fixed family plan, or correcting a wrongly booked calendar). +### 6. `calendar__calendar_move_event(event_id, source_calendar="family", destination_calendar="regensburg")`: +- Moves an event atomically from one calendar to another. -7. `calendar_find_free_slots(calendar="family"|"regensburg"|"both", time_min=None, time_max=None, duration_minutes=60, day_start_hour=8, day_end_hour=20)`: - - Queries `freebusy` to find open, available time windows across calendars. - - Perfect for answering questions like: *"Wann haben wir diese Woche am Nachmittag 2 Stunden frei für einen Ausflug?"*. +### 7. `calendar__calendar_find_free_slots(calendar="family"|"regensburg"|"both", time_min=None, time_max=None, duration_minutes=60, day_start_hour=8, day_end_hour=20)`: +- Queries `freebusy` to find open, available time windows across calendars. -8. `calendar_get_event(calendar="family"|"regensburg", event_id)`: - - Retrieves full event metadata. +### 8. `calendar__calendar_get_event(calendar="family"|"regensburg", event_id)`: +- Retrieves full event metadata. --- ## 🧭 Routing & Best Practices for OpenClaw +### ⚠️ Strikte Guardrails: +1. **STRIKTE REGEL: NIEMALS ERFOLG VORTÄUSCHEN (NO FAKE CONFIRMATIONS)!** Wenn ein Tool fehlschlägt oder `not found` meldet, behaupte **niemals**, dass der Termin gelöscht oder erstellt wurde! Nutze den CLI-Fallback oder berichte den Fehler wahrheitsgemäß. +2. **STRIKTE REGEL: KEINE MÄRKTE IN DEN KALENDER EINTRAGEN!** Weder Wochenmärkte (Katharinenmarkt, Neupfarrplatz, etc.) noch Bio-Bauernmärkte dürfen in die Kalender eingetragen werden. Dies überfrachtet den Kalender. + ### 1. Conflict Guard (Terminkonflikte & Puffer) -- When a user asks to add an event, check `calendar_check_conflicts` or inspect the `conflict_warning` from `calendar_create_event`. -- If an overlap or tight buffer (< 15 Min.) exists, explicitly warn the user: - > *„⚠️ Achtung: Am Freitag um 17:30 Uhr hat Moritz schon 'Moritz Gartenparty Arbeit' (17:30 - 18:30). Dein Termin 'Spielplatz' würde sich damit überschneiden. Soll ich ihn trotzdem eintragen?“* +- When a user asks to add an event, check `calendar__calendar_check_conflicts` or inspect the `conflict_warning` from `calendar__calendar_create_event`. +- If an overlap or tight buffer (< 15 Min.) exists, explicitly warn the user. ### 2. Informational Events vs. Family Commitments (Transparency) -- When adding city events, festivals, or weekly markets to the **`regensburg`** calendar, always pass `show_as_busy=False` (or `transparency="transparent"`). +- When adding city events, festivals, or exhibitions to the **`regensburg`** calendar, always pass `show_as_busy=False` (or `transparency="transparent"`). - This keeps the event clearly visible on the calendar while allowing family appointments to be scheduled in parallel without false conflict alerts. ### 3. Recurring Series (RRULE) -- When the user asks to add recurring appointments (e.g. weekly markets, sports training, trash collection): +- When the user asks to add recurring appointments (e.g. sports training, trash collection): - Use `recurrence="RRULE:FREQ=WEEKLY;BYDAY=..."` or convenient shortcuts. - - Do NOT create manual cron scripts or multiple single events when a native Google Calendar recurrence series can be used. ### 4. Smart Location & Google Maps Integration - If a place or venue is mentioned (e.g. *"Dr. Müller in Prüfening"*, *"Westbad"*): - Resolve the full address or ask the user, and store it in `location`. - - This activates Google Maps departure alerts on their smartphone (*„Aufbruch in 15 Min. wegen Verkehr“*). + - This activates Google Maps departure alerts on their smartphone. ### 5. Proaktive Rückfragen & Checklisten (Mental Load Entlastung) - When booking medical/baby appointments (e.g. *Kinderarzt*, *U-Untersuchungen*, *Zahnarzt*):