Calendar Skill
Access calendar data from ICS files, CalDAV servers, and various calendar providers. Query events, check availability, and manage events on writable calendars.
Overview
| Feature | ICS | CalDAV |
|---|---|---|
| Query events | ✅ | ✅ |
| Expand recurrence | ✅ | ✅ |
| Free/busy lookup | ✅ (derived) | ✅ (native) |
| Create event | ❌ | ✅ |
| Update event | ❌ | ✅ |
| Delete event | ❌ | ✅ |
Provider Support:
- •Outlook: ICS share links (read-only)
- •Google Calendar: ICS share links (read-only) or CalDAV (read/write)
- •Nextcloud: ICS share links (read-only) or CalDAV (read/write)
- •Fastmail, iCloud, etc.: CalDAV (read/write)
Quick Start
- •Create a config file at
~/.config/calendar-skill/config.yaml:
default_timezone: "America/Chicago"
calendars:
- name: "Work"
type: ics
url: "https://outlook.office365.com/.../calendar.ics"
mode: read
- •Query today's events:
python -m calendar_skill events --start today --days 1
Configuration
Config File Locations
The skill searches for configuration in order:
- •Path specified via
--configflag - •
~/.config/calendar-skill/config.yaml - •
.calendar-skill.yamlin current directory
Environment Variables
All settings can be set via environment variables with CALENDAR_ prefix:
export CALENDAR_DEFAULT_TIMEZONE="America/New_York" export CALENDAR_DEFAULT_OUTPUT_FORMAT="json"
Secrets
Passwords can be provided via:
- •Config file (not recommended for sensitive data)
- •Environment variables:
CALENDAR_CALENDARS__0__PASSWORD(index-based)
Recommended approach: Use environment variables for passwords:
# config.yaml
calendars:
- name: "Nextcloud"
type: caldav
url: "https://cloud.example.com/remote.php/dav/calendars/user/personal/"
mode: write
username: "user"
# password loaded from environment
# .env or shell export CALENDAR_CALENDARS__0__PASSWORD="your-app-password"
Security tips:
- •Always use app-specific passwords, never your main account password
- •Revoke and regenerate app passwords if they may have been exposed
- •Keep ICS "secret address" URLs private - they grant read access to anyone
Full Config Reference
# Timezone for all output (IANA format)
default_timezone: "UTC"
# Output format: "text" or "json"
default_output_format: text
calendars:
- name: "Display Name" # Required
type: ics | caldav # Required
url: "https://..." # Required (URL or file path)
mode: read | write # Default: read
username: "user" # For CalDAV auth
password: "secret" # For CalDAV auth
calendar_id: "primary" # For CalDAV with multiple calendars
CLI Reference
Query Events
# Today's events calendar-skill events # Next 7 days calendar-skill events --days 7 # Specific date range calendar-skill events --start 2026-01-27 --end 2026-01-31 # From specific calendar calendar-skill events --calendar "Work" --days 3 # JSON output calendar-skill events --format json
Free/Busy Lookup
# Check availability calendar-skill freebusy --start "2026-01-27 09:00" --end "2026-01-27 17:00" # Specific calendar calendar-skill freebusy --start today --end tomorrow --calendar "Work"
Expand Recurring Events
# Get all instances of a recurring event calendar-skill instances --uid "event-uid-123" --start 2026-01-01 --end 2026-03-01
Create Event (CalDAV only)
# Basic event calendar-skill create --summary "Team Meeting" --start "2026-01-27 10:00" --duration 1h # With details calendar-skill create \ --calendar "Work" \ --summary "Project Review" \ --start "2026-01-27 14:00" \ --end "2026-01-27 15:30" \ --location "Conference Room A" \ --description "Quarterly project status review"
Update Event (CalDAV only)
calendar-skill update --calendar "Work" --uid "event-uid" --summary "New Title" calendar-skill update --calendar "Work" --uid "event-uid" --start "2026-01-28 10:00"
Delete Event (CalDAV only)
calendar-skill delete --calendar "Work" --uid "event-uid" calendar-skill delete --calendar "Work" --uid "event-uid" --force # Skip confirmation
Utility Commands
# List configured calendars calendar-skill list-calendars # Validate config and test connections calendar-skill config-check
Agent Usage Patterns
Gathering Context for Daily Updates
# Yesterday's events (for "what I did") calendar-skill events --start yesterday --end today --format json # Today's events (for "what I'm doing") calendar-skill events --start today --end tomorrow --format json
Checking Availability Before Scheduling
# Find free time for a meeting calendar-skill freebusy --start "2026-01-27 09:00" --end "2026-01-27 18:00"
Creating Events from Natural Language
When a user says "Schedule a meeting with John tomorrow at 2pm for 30 minutes":
calendar-skill create \ --calendar "Work" \ --summary "Meeting with John" \ --start "2026-01-28 14:00" \ --duration 30m
Calendar Setup Guides
ICS Files (Local or Remote)
Any .ics file can be used as a read-only calendar source:
calendars:
- name: "Local Calendar"
type: ics
url: "~/calendars/personal.ics"
mode: read
- name: "Remote Calendar"
type: ics
url: "https://example.com/calendar.ics"
mode: read
Outlook (via ICS Share Link)
- •Open Outlook Calendar settings
- •Find "Shared calendars" → "Publish a calendar"
- •Select the calendar and copy the ICS link
- •Add to config:
calendars:
- name: "Outlook Work"
type: ics
url: "https://outlook.office365.com/owa/calendar/.../reachcalendar.ics"
mode: read
Google Calendar (via ICS - Read Only)
For read-only access, use Google Calendar's "Secret address in iCal format":
- •Open Google Calendar → Settings (gear icon)
- •Click on the calendar name under "Settings for my calendars"
- •Scroll to "Integrate calendar"
- •Copy the "Secret address in iCal format"
- •Add to config:
calendars:
- name: "Google"
type: ics
url: "https://calendar.google.com/calendar/ical/YOUR_SECRET_URL/basic.ics"
mode: read
Note: Keep this URL private - anyone with it can read your calendar.
Google Calendar (via CalDAV - Read/Write)
For read/write access, use CalDAV with an app-specific password:
- •Enable 2-Step Verification in your Google Account
- •Go to Security → App passwords → Generate a new app password
- •Add to config:
calendars:
- name: "Google"
type: caldav
url: "https://apidata.googleusercontent.com/caldav/v2/YOUR_EMAIL/events"
mode: write
username: "your-email@gmail.com"
password: "your-app-password"
Nextcloud (via ICS - Read Only)
Nextcloud public share links are web views, not ICS files. Use the DAV export URL:
- •Share your calendar and copy the share link (e.g.,
https://cloud.example.com/apps/calendar/p/ABC123) - •Convert to ICS URL:
https://cloud.example.com/remote.php/dav/public-calendars/ABC123?export - •Add to config:
calendars:
- name: "Nextcloud Shared"
type: ics
url: "https://cloud.example.com/remote.php/dav/public-calendars/ABC123?export"
mode: read
Note: Public share links are read-only. For write access, use authenticated CalDAV.
Nextcloud (via CalDAV - Read/Write)
For full read/write access:
- •Generate an app password in Nextcloud: Settings → Security → Devices & sessions
- •Find your calendar URL: usually
https://cloud.example.com/remote.php/dav/calendars/USERNAME/CALENDAR_NAME/ - •Add to config:
calendars:
- name: "Nextcloud"
type: caldav
url: "https://cloud.example.com/remote.php/dav/calendars/username/personal/"
mode: write
username: "username"
password: "app-password"
Tip: You can find the exact calendar URL in Nextcloud Calendar settings under "Copy private link".
Fastmail
calendars:
- name: "Fastmail"
type: caldav
url: "https://caldav.fastmail.com/dav/calendars/user/EMAIL/"
mode: write
username: "your-email@fastmail.com"
password: "app-password"
Generic CalDAV
Most CalDAV servers follow a similar pattern:
calendars:
- name: "CalDAV Server"
type: caldav
url: "https://caldav.example.com/calendars/username/"
mode: write
username: "username"
password: "password"
calendar_id: "calendar-name" # Optional
Troubleshooting
"No calendars configured"
Create a config file or set environment variables. Run calendar-skill config-check to verify.
Authentication Failed (CalDAV)
- •Verify username/password are correct
- •Many services require app-specific passwords (not your main password)
- •Check that CalDAV access is enabled for your account
Events Not Appearing
- •Check the time range: use
--startand--endexplicitly - •Verify timezone settings match your calendar
- •For ICS URLs, ensure the URL is accessible (try in a browser)
Recurring Events
By default, recurring events return the RRULE without expansion. Use the instances command to expand:
calendar-skill instances --uid "recurring-event-uid" --start 2026-01-01 --end 2026-12-31
Timezone Issues
All times are normalized to the configured timezone. If times seem off:
- •Check
default_timezonein config - •Use
--timezoneflag to override - •Verify your calendar's timezone settings
Nextcloud Public Share Links
Nextcloud public share links (/apps/calendar/p/...) are web views, not ICS files. You need to:
- •Convert the URL to the DAV export format
- •Use
/remote.php/dav/public-calendars/TOKEN?exportinstead
Public shares are read-only. For write access, use authenticated CalDAV with an app password.
CalDAV "Node not found" Errors
If you get "Node with name 'X' could not be found" when creating events:
- •The calendar URL may be incorrect - verify the full path to the calendar
- •For Nextcloud: use
/remote.php/dav/calendars/USERNAME/CALENDAR_NAME/ - •Check permissions - public shares typically don't allow writes