✓ Verified 💻 Development ✓ Enhanced Data

Caldav Skill

Manage CalDAV calendars and events, with special support for Radicale server.

Rating
4.4 (401 reviews)
Downloads
1,902 downloads
Version
1.0.0

Overview

Manage CalDAV calendars and events, with special support for Radicale server.

Complete Documentation

View Source →

CalDAV & Radicale Management

Interact with CalDAV servers (calendars, events, todos) and manage Radicale server configurations.

Overview

CalDAV is a protocol for accessing and managing calendaring information (RFC 4791). Radicale is a lightweight CalDAV/CardDAV server. This skill enables:

  • Calendar CRUD operations (create, list, update, delete)
  • Event management (create, update, delete, query)
  • Todo/task management
  • Radicale server configuration and administration

Prerequisites

Python Library

Install the caldav library:

bash
pip install caldav

For async support:

bash
pip install caldav[async]

Environment Variables (Recommended)

Store credentials securely in environment or config:

bash
export CALDAV_URL="http://localhost:5232"
export CALDAV_USER="your_username"
export CALDAV_PASSWORD="your_password"

Or use a config file at ~/.config/caldav/config.json:

json
{
  "url": "http://localhost:5232",
  "username": "your_username",
  "password": "your_password"
}

Scripts

Calendar Operations

bash
# List all calendars
python3 {baseDir}/scripts/calendars.py list

# Create a new calendar
python3 {baseDir}/scripts/calendars.py create --name "Work Calendar" --id work

# Delete a calendar
python3 {baseDir}/scripts/calendars.py delete --id work

# Get calendar info
python3 {baseDir}/scripts/calendars.py info --id work

Event Operations

bash
# List events (all calendars, next 30 days)
python3 {baseDir}/scripts/events.py list

# List events from specific calendar
python3 {baseDir}/scripts/events.py list --calendar work

# List events in date range
python3 {baseDir}/scripts/events.py list --start 2024-01-01 --end 2024-01-31

# Create an event
python3 {baseDir}/scripts/events.py create \
  --calendar work \
  --summary "Team Meeting" \
  --start "2024-01-15 14:00" \
  --end "2024-01-15 15:00" \
  --description "Weekly sync"

# Create all-day event
python3 {baseDir}/scripts/events.py create \
  --calendar personal \
  --summary "Birthday" \
  --start 2024-02-14 \
  --allday

# Update an event
python3 {baseDir}/scripts/events.py update \
  --uid "event-uid-here" \
  --summary "Updated Title"

# Delete an event
python3 {baseDir}/scripts/events.py delete --uid "event-uid-here"

# Search events by text
python3 {baseDir}/scripts/events.py search --query "meeting"

Todo Operations

bash
# List todos
python3 {baseDir}/scripts/todos.py list [--calendar name]

# Create a todo
python3 {baseDir}/scripts/todos.py create \
  --calendar work \
  --summary "Complete report" \
  --due "2024-01-20"

# Complete a todo
python3 {baseDir}/scripts/todos.py complete --uid "todo-uid-here"

# Delete a todo
python3 {baseDir}/scripts/todos.py delete --uid "todo-uid-here"

Radicale Server Management

bash
# Check Radicale status
python3 {baseDir}/scripts/radicale.py status

# List users (from htpasswd file)
python3 {baseDir}/scripts/radicale.py users list

# Add user
python3 {baseDir}/scripts/radicale.py users add --username newuser

# View Radicale config
python3 {baseDir}/scripts/radicale.py config show

# Validate Radicale config
python3 {baseDir}/scripts/radicale.py config validate

# Check storage integrity
python3 {baseDir}/scripts/radicale.py storage verify

Direct HTTP/DAV Operations

For low-level operations, use curl with CalDAV:

bash
# Discover principal URL
curl -u user:pass -X PROPFIND \
  -H "Depth: 0" \
  -H "Content-Type: application/xml" \
  -d '<d:propfind xmlns:d="DAV:"><d:prop><d:current-user-principal/></d:prop></d:propfind>' \
  http://localhost:5232/

# List calendars
curl -u user:pass -X PROPFIND \
  -H "Depth: 1" \
  -H "Content-Type: application/xml" \
  -d '<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav"><d:prop><d:displayname/><c:calendar-timezone/><d:resourcetype/></d:prop></d:propfind>' \
  http://localhost:5232/user/

# Query events by time range
curl -u user:pass -X REPORT \
  -H "Depth: 1" \
  -H "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="utf-8"?>
<c:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
  <d:prop><d:getetag/><c:calendar-data/></d:prop>
  <c:filter>
    <c:comp-filter name="VCALENDAR">
      <c:comp-filter name="VEVENT">
        <c:time-range start="20240101T000000Z" end="20240131T235959Z"/>
      </c:comp-filter>
    </c:comp-filter>
  </c:filter>
</c:calendar-query>' \
  http://localhost:5232/user/calendar/

# Create calendar (MKCALENDAR)
curl -u user:pass -X MKCALENDAR \
  -H "Content-Type: application/xml" \
  -d '<?xml version="1.0" encoding="utf-8"?>
<d:mkcalendar xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
  <d:set><d:prop>
    <d:displayname>New Calendar</d:displayname>
  </d:prop></d:set>
</d:mkcalendar>' \
  http://localhost:5232/user/new-calendar/

Radicale Configuration

Config File Location

Radicale looks for config in:

  • /etc/radicale/config (system-wide)
  • ~/.config/radicale/config (user)
  • Custom path via --config or RADICALE_CONFIG env

Key Configuration Sections

ini
[server]
hosts = localhost:5232
max_connections = 20
max_content_length = 100000000
timeout = 30
ssl = False

[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = autodetect

[storage]
filesystem_folder = /var/lib/radicale/collections

[rights]
type = owner_only

Authentication Types

TypeDescription
noneNo authentication (development only!)
denyallDeny all (default since 3.5.0)
htpasswdApache htpasswd file
remote_userWSGI-provided username
http_x_remote_userReverse proxy header
ldapLDAP/AD authentication
dovecotDovecot auth socket
imapIMAP server authentication
oauth2OAuth2 authentication
pamPAM authentication

Creating htpasswd Users

bash
# Create new file with SHA-512
htpasswd -5 -c /etc/radicale/users user1

# Add another user
htpasswd -5 /etc/radicale/users user2

Running as Service (systemd)

bash
# Enable and start
sudo systemctl enable radicale
sudo systemctl start radicale

# Check status
sudo systemctl status radicale

# View logs
journalctl -u radicale -f

iCalendar Format Quick Reference

Events use iCalendar (RFC 5545) format:

ics
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp//CalDAV Client//EN
BEGIN:VEVENT
UID:[email protected]
DTSTAMP:20240115T120000Z
DTSTART:20240115T140000Z
DTEND:20240115T150000Z
SUMMARY:Team Meeting
DESCRIPTION:Weekly sync
LOCATION:Conference Room
END:VEVENT
END:VCALENDAR

Common Properties

PropertyDescription
UIDUnique identifier
DTSTARTStart time
DTENDEnd time
DTSTAMPCreation/modification time
SUMMARYEvent title
DESCRIPTIONEvent description
LOCATIONLocation
RRULERecurrence rule
EXDATEExcluded dates
ATTENDEEParticipant
ORGANIZEREvent organizer
STATUSCONFIRMED/TENTATIVE/CANCELLED

Date Formats

text
# DateTime with timezone
DTSTART:20240115T140000Z  ; UTC (Z suffix)
DTSTART;TZID=America/New_York:20240115T090000

# All-day event
DTSTART;VALUE=DATE:20240214

# DateTime local (floating)
DTSTART:20240115T140000

Troubleshooting

Connection Issues

bash
# Test basic connectivity
curl -v http://localhost:5232/

# Check with authentication
curl -v -u user:pass http://localhost:5232/

# Verify CalDAV support
curl -X OPTIONS http://localhost:5232/ -I | grep -i dav

Common Errors

ErrorCauseSolution
401 UnauthorizedWrong credentialsCheck htpasswd file
403 ForbiddenRights restrictionCheck [rights] config
404 Not FoundWrong URL pathCheck principal/calendar path
409 ConflictResource existsUse different UID
415 Unsupported Media TypeWrong Content-TypeUse text/calendar

Debug Mode

Run Radicale with debug logging:

bash
python3 -m radicale --debug

Python API Quick Reference

python
from caldav import DAVClient

# Connect
client = DAVClient(
    url="http://localhost:5232",
    username="user",
    password="pass"
)

# Get principal
principal = client.principal()

# List calendars
for cal in principal.calendars():
    print(f"Calendar: {cal.name} ({cal.url})")

# Create calendar
cal = principal.make_calendar(name="My Calendar", cal_id="my-cal")

# Create event
cal.save_event(
    dtstart="2024-01-15 14:00",
    dtend="2024-01-15 15:00",
    summary="Meeting"
)

# Query events by date range
events = cal.date_search(
    start="2024-01-01",
    end="2024-01-31"
)
for event in events:
    print(event.vobject_instance.vevent.summary.value)

# Get event by UID
event = cal.event_by_uid("event-uid")

# Delete event
event.delete()

# Create todo
todo = cal.save_todo(
    summary="Task",
    due="2024-01-20"
)

Workflow Examples

Create Recurring Event

bash
python3 {baseDir}/scripts/events.py create \
  --calendar work \
  --summary "Weekly Standup" \
  --start "2024-01-15 09:00" \
  --end "2024-01-15 09:30" \
  --rrule "FREQ=WEEKLY;BYDAY=MO,WE,FR"

Export Calendar to ICS

bash
# Via curl
curl -u user:pass http://localhost:5232/user/calendar/ > calendar.ics

# Via script
python3 {baseDir}/scripts/calendars.py export --id work --output work.ics

Sync with Git (Radicale)

Configure Radicale to version changes:

ini
[storage]
hook = git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")

Initialize git in storage folder:

bash
cd /var/lib/radicale/collections
git init
git config user.email "radicale@localhost"

Installation

Terminal bash

openclaw install caldav-skill
    
Copied!

💻Code Examples

pip install caldav[async]

pip-install-caldavasync.txt
### Environment Variables (Recommended)

Store credentials securely in environment or config:

}

.txt
## Scripts

### Calendar Operations

python3 {baseDir}/scripts/radicale.py storage verify

python3-basedirscriptsradicalepy-storage-verify.txt
## Direct HTTP/DAV Operations

For low-level operations, use curl with CalDAV:

http://localhost:5232/user/new-calendar/

-httplocalhost5232usernew-calendar.txt
## Radicale Configuration

### Config File Location

Radicale looks for config in:
- `/etc/radicale/config` (system-wide)
- `~/.config/radicale/config` (user)
- Custom path via `--config` or `RADICALE_CONFIG` env

### Key Configuration Sections

type = owner_only

type--owneronly.txt
### Authentication Types

| Type | Description |
|------|-------------|
| `none` | No authentication (development only!) |
| `denyall` | Deny all (default since 3.5.0) |
| `htpasswd` | Apache htpasswd file |
| `remote_user` | WSGI-provided username |
| `http_x_remote_user` | Reverse proxy header |
| `ldap` | LDAP/AD authentication |
| `dovecot` | Dovecot auth socket |
| `imap` | IMAP server authentication |
| `oauth2` | OAuth2 authentication |
| `pam` | PAM authentication |

### Creating htpasswd Users

journalctl -u radicale -f

journalctl--u-radicale--f.txt
## iCalendar Format Quick Reference

Events use iCalendar (RFC 5545) format:

END:VCALENDAR

endvcalendar.txt
### Common Properties

| Property | Description |
|----------|-------------|
| `UID` | Unique identifier |
| `DTSTART` | Start time |
| `DTEND` | End time |
| `DTSTAMP` | Creation/modification time |
| `SUMMARY` | Event title |
| `DESCRIPTION` | Event description |
| `LOCATION` | Location |
| `RRULE` | Recurrence rule |
| `EXDATE` | Excluded dates |
| `ATTENDEE` | Participant |
| `ORGANIZER` | Event organizer |
| `STATUS` | CONFIRMED/TENTATIVE/CANCELLED |

### Date Formats

DTSTART:20240115T140000

dtstart20240115t140000.txt
## Troubleshooting

### Connection Issues

curl -X OPTIONS http://localhost:5232/ -I | grep -i dav

curl--x-options-httplocalhost5232--i--grep--i-dav.txt
### Common Errors

| Error | Cause | Solution |
|-------|-------|----------|
| 401 Unauthorized | Wrong credentials | Check htpasswd file |
| 403 Forbidden | Rights restriction | Check `[rights]` config |
| 404 Not Found | Wrong URL path | Check principal/calendar path |
| 409 Conflict | Resource exists | Use different UID |
| 415 Unsupported Media Type | Wrong Content-Type | Use `text/calendar` |

### Debug Mode

Run Radicale with debug logging:

)

.txt
## Workflow Examples

### Create Recurring Event

Tags

#devops_and-cloud

Quick Info

Category Development
Model Claude 3.5
Complexity One-Click
Author chakyiu
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install caldav-skill