← Back to Skills Marketplace
chakyiu

Caldav

by Chakyiu · GitHub ↗ · v1.0.0
cross-platform ⚠ suspicious
578
Downloads
0
Stars
1
Active Installs
1
Versions
Install in OpenClaw
/install caldav-skill
Description
Manage CalDAV calendars and events, with special support for Radicale server. Use when the user wants to create, update, delete, or query calendar events, ma...
README (SKILL.md)

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:

pip install caldav

For async support:

pip install caldav[async]

Environment Variables (Recommended)

Store credentials securely in environment or config:

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:

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

Scripts

Calendar Operations

# 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

# 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

# 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

# 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:

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

# List calendars
curl -u user:pass -X PROPFIND \
  -H "Depth: 1" \
  -H "Content-Type: application/xml" \
  -d '\x3Cd:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">\x3Cd:prop>\x3Cd:displayname/>\x3Cc:calendar-timezone/>\x3Cd:resourcetype/>\x3C/d:prop>\x3C/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 '\x3C?xml version="1.0" encoding="utf-8"?>
\x3Cc:calendar-query xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav">
  \x3Cd:prop>\x3Cd:getetag/>\x3Cc:calendar-data/>\x3C/d:prop>
  \x3Cc:filter>
    \x3Cc:comp-filter name="VCALENDAR">
      \x3Cc:comp-filter name="VEVENT">
        \x3Cc:time-range start="20240101T000000Z" end="20240131T235959Z"/>
      \x3C/c:comp-filter>
    \x3C/c:comp-filter>
  \x3C/c:filter>
\x3C/c:calendar-query>' \
  http://localhost:5232/user/calendar/

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

[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

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

# 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)

# 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:

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

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

# 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

# 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

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:

python3 -m radicale --debug

Python API Quick Reference

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

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

# 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:

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

Initialize git in storage folder:

cd /var/lib/radicale/collections
git init
git config user.email "radicale@localhost"
Usage Guidance
This skill includes real Python scripts that manage CalDAV resources and administer a Radicale server; that means it will read local config files (e.g., ~/.config/caldav/config.json, /etc/radicale/*), inspect storage under /var/lib/radicale, and call system utilities (systemctl, pgrep, htpasswd, curl). Before installing or running it: - Expect to grant it access to local Radicale configuration and storage; run it only on systems you control and where you expect these admin actions. - Note the manifest only lists python3, but the scripts call other system binaries; ensure those tools exist and consider privilege requirements (some operations may need sudo). - Avoid using curl -u user:pass examples on shared machines or in logs — passing credentials on the command line can expose them via shell history/process lists. Prefer environment variables or protected config files. - Review the included scripts yourself (they are bundled) if you have concerns; they do not perform network exfiltration or obfuscated behavior in the provided code, but they do read system files and may modify htpasswd or storage. - If you lack experience managing system services or Radicale, test this skill in an isolated environment or container first. If you want, I can point out the exact lines where system calls and path reads occur or produce a short checklist of commands to run safely when evaluating this skill.
Capability Analysis
Type: OpenClaw Skill Name: caldav-skill Version: 1.0.0 The skill is classified as suspicious due to a critical shell injection vulnerability found in `scripts/radicale.py`. The `cmd_users_add` function passes the `args.username` directly to the `htpasswd` command via `subprocess.run` without proper sanitization, allowing for arbitrary command execution if an attacker can control the username input. Additionally, `scripts/calendars.py` has potential arbitrary file read/write vulnerabilities in its `cmd_export` and `cmd_import` functions, as it uses user-supplied paths (`--output`, `--file`) without apparent path validation, which could lead to path traversal or overwriting/reading sensitive files.
Capability Assessment
Purpose & Capability
Name and description match the included Python scripts: calendars, events, todos, and Radicale management. The functionality (calendar CRUD, event/todo operations, Radicale admin) is coherent with the stated purpose. However, the SKILL metadata only declares python3 as a required binary while the scripts invoke other system utilities (systemctl, pgrep, htpasswd, curl) and access system paths (/etc/radicale, /var/lib/radicale). The presence of those system-level operations is reasonable for Radicale administration but is more privileged than the declared single dependency, which is a mismatch.
Instruction Scope
SKILL.md and the scripts instruct the agent/user to: install the caldav library; place credentials in environment variables or a config file; run the included Python scripts; and (for low-level ops) run curl commands with user:pass. The runtime code reads config files (~/ .config/caldav/config.json, /etc/caldav/config.json), Radicale config (/etc/radicale/config, ~/.config/radicale/config), users file (/etc/radicale/users), storage path (/var/lib/radicale/collections), and may write files (export ICS, import ICS, modify htpasswd via htpasswd). That scope is consistent with Radicale admin but includes access to system files and running system commands. The SKILL.md examples that show curl -u user:pass risk exposing credentials in shell history and process lists; this is an operational security concern but not unexpected for a CalDAV skill.
Install Mechanism
There is no automated install spec (instruction-only install), which minimizes the risk of arbitrary remote code fetch during install. The SKILL.md tells users to pip install the caldav library (and caldav[async] optionally) — a straightforward, expected dependency. Because code files are included in the skill bundle, no additional install steps are required by the skill itself. No remote download URLs or extract operations are present in the manifest.
Credentials
The skill does not declare required environment variables in its registry metadata, yet the SKILL.md and utils.load_config() use CALDAV_URL, CALDAV_USER, CALDAV_PASSWORD and allow a config file. That alone is not malicious, but the Radicale management scripts read system configuration paths (/etc/radicale/config, /etc/radicale/users) and storage directories and run system commands which may require elevated privileges. The code does not request unrelated cloud or secret credentials, but it will read local sensitive files (htpasswd) and could expose configuration state. The mismatch between declared env requirements and the script behavior is notable.
Persistence & Privilege
The skill is not always-enabled and does not request any platform-level persistence privileges. It does perform administrative actions on the local system (reading/writing Radicale files, calling htpasswd, checking systemctl), which requires appropriate OS permissions, but it does not modify other skills or the agent runtime configuration.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install caldav-skill
  3. After installation, invoke the skill by name or use /caldav-skill
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of the CalDAV skill for managing calendars, events, todos, and Radicale server. - Supports CRUD operations for calendars, events, and todos over CalDAV. - Includes script-based management for calendars, events, todos, and Radicale server administration. - Provides both high-level automation and direct CalDAV/DAV HTTP operation examples. - Features configuration and usage guides for both end users and administrators. - Adds special support for Radicale server configuration, user management, and status checks.
Metadata
Slug caldav-skill
Version 1.0.0
License
All-time Installs 1
Active Installs 1
Total Versions 1
Frequently Asked Questions

What is Caldav?

Manage CalDAV calendars and events, with special support for Radicale server. Use when the user wants to create, update, delete, or query calendar events, ma... It is an AI Agent Skill for Claude Code / OpenClaw, with 578 downloads so far.

How do I install Caldav?

Run "/install caldav-skill" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Caldav free?

Yes, Caldav is completely free (open-source). You can download, install and use it at no cost.

Which platforms does Caldav support?

Caldav is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Caldav?

It is built and maintained by Chakyiu (@chakyiu); the current version is v1.0.0.

💬 Comments