Radicale logo

Radicale

Community
jmagar
radicale

This skill should be used when managing calendars and contacts on a self-hosted Radicale CalDAV/CardDAV server. Use when the user asks to "list my calendar", "what's on my calendar this week", "show me my events", "when is my next event", "add to my calendar", "create an event", "schedule a meeting", "schedule an event", "delete an event", "cancel event", "remove event", "find a contact", "what's someone's email", "search my contacts", "who is", "add a contact", "save contact", "save someone's phone number", or mentions Radicale, CalDAV, CardDAV, calendar events, or contact management operations.

Overview

Publisherjmagar
Repositoryclaude-homelab
Skill nameradicale
Stars
87
Forks
11
Bundled files
5
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 5 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by jmagar on GitHub. Read the source before you install it.

Installation

Install the Radicale AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/jmagar/claude-homelab/tree/main/skills/radicale
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/jmagar/claude-homelab.git /tmp/claude-homelab
mkdir -p .claude/skills
cp -r /tmp/claude-homelab/skills/radicale .claude/skills/radicale
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Radicale in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Radicale on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Radicale is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Radicale CalDAV/CardDAV Management

⚠️ MANDATORY SKILL INVOCATION ⚠️

YOU MUST invoke this skill (NOT optional) when the user mentions ANY of these triggers:

  • "list my calendar", "what's on my calendar", "show me my events", "calendar this week", "when is my next event"
  • "add to my calendar", "create an event", "schedule event", "schedule a meeting"
  • "delete an event", "cancel event", "remove event"
  • "find a contact", "what's someone's email", "search my contacts", "who is"
  • "add a contact", "create contact", "save contact", "save someone's phone number"
  • Any mention of Radicale, CalDAV, CardDAV, calendar events, or contact management

Failure to invoke this skill when triggers occur violates your operational requirements.


Manage calendars (events) and contacts on a self-hosted Radicale server using CalDAV and CardDAV protocols.

Type: Read & Write (calendar events and contacts)

Purpose

This skill enables comprehensive calendar and contact management through a self-hosted Radicale server. It provides read and write access to:

  • Calendars - List, view, create, update, and delete calendar events
  • Contacts - List, search, create, update, and delete contacts in addressbooks

All operations use the Python caldav library which implements the CalDAV (RFC 4791) and CardDAV (RFC 6352) protocols.

Setup

Prerequisites

Install required Python libraries:

bash
pip install caldav vobject icalendar

Script Permissions:

The Python script can be made executable (optional but recommended):

bash
chmod +x ~/claude-homelab/skills/radicale/scripts/radicale-api.py

You can then run it directly:

bash
./scripts/radicale-api.py --help

Or without executable permissions using Python:

bash
python scripts/radicale-api.py --help

Credentials

Add to ~/.claude-homelab/.env:

bash
RADICALE_URL="http://localhost:5232"
RADICALE_USERNAME="admin"
RADICALE_PASSWORD="password"

Security:

  • .env file is gitignored (never commit credentials)
  • Set permissions: chmod 600 ~/.claude-homelab/.env

Core Operations

All operations use the scripts/radicale-api.py wrapper script. Output is JSON format for easy parsing.

Calendar Operations

List Calendars
bash
python scripts/radicale-api.py calendars list

Returns array of calendars with name, URL, and ID.

View Events

List events in a calendar within a date range:

bash
python scripts/radicale-api.py events list \
  --calendar "Personal" \
  --start "2026-02-08" \
  --end "2026-02-15"

Parameters:

  • --calendar (required) - Calendar name (case-sensitive)
  • --start (optional) - Start date (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS)
  • --end (optional) - End date (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS)

Default behavior: If start/end not specified, uses current date + 7 days.

Returns array of events with UID, summary, description, location, start, end, and timestamps.

Create Event
bash
python scripts/radicale-api.py events create \
  --calendar "Personal" \
  --title "Meeting" \
  --start "2026-02-10T14:00:00" \
  --end "2026-02-10T15:00:00" \
  --location "Conference Room" \
  --description "Team sync"

Required parameters:

  • --calendar - Calendar name
  • --title - Event title/summary
  • --start - Start datetime (YYYY-MM-DDTHH:MM:SS)
  • --end - End datetime (YYYY-MM-DDTHH:MM:SS)

Optional parameters:

  • --location - Event location
  • --description - Event description

Important: Use ISO 8601 datetime format (YYYY-MM-DDTHH:MM:SS). End must be after start.

Delete Event
bash
python scripts/radicale-api.py events delete \
  --calendar "Personal" \
  --uid "event-uid-here"

Get UID from events list output.

Contact Operations

List Addressbooks
bash
python scripts/radicale-api.py contacts addressbooks

Returns array of addressbooks with name, URL, and ID.

List Contacts
bash
python scripts/radicale-api.py contacts list \
  --addressbook "Contacts"

Returns array of contacts with UID, name, email, and phone.

Search Contacts
bash
python scripts/radicale-api.py contacts search \
  --addressbook "Contacts" \
  --query "David"

Search behavior: Case-insensitive substring match against name and email fields.

Create Contact
bash
python scripts/radicale-api.py contacts create \
  --addressbook "Contacts" \
  --name "John Doe" \
  --email "john@example.com" \
  --phone "+1-555-1234"

Required parameter:

  • --name - Contact full name

Optional parameters:

  • --email - Email address
  • --phone - Phone number
Delete Contact
bash
python scripts/radicale-api.py contacts delete \
  --addressbook "Contacts" \
  --uid "contact-uid-here"

Get UID from contacts list or contacts search output.

Natural Language Translation

When users make natural language requests, translate them to script commands:

Calendar Examples

User: "What's my calendar look like this week?"

Action:

  1. Calculate current week date range
  2. Run: python scripts/radicale-api.py events list --calendar "Personal" --start "YYYY-MM-DD" --end "YYYY-MM-DD"
  3. Present events in human-readable format

User: "Add to my calendar Billy Strings in Athens, GA 02/07/2026 7PM EST"

Action:

  1. Parse: title="Billy Strings", location="Athens, GA", start="2026-02-07T19:00:00", end="2026-02-07T23:00:00" (assume 4hr concert)
  2. Run: python scripts/radicale-api.py events create --calendar "Personal" --title "Billy Strings" --start "2026-02-07T19:00:00" --end "2026-02-07T23:00:00" --location "Athens, GA"
  3. Confirm creation

Contact Examples

User: "What's David Ryan's work email?"

Action:

  1. Run: python scripts/radicale-api.py contacts search --addressbook "Contacts" --query "David Ryan"
  2. Extract email field from results
  3. Present: "David Ryan's email is david.ryan@example.com"

User: "Add John Doe to my contacts, email john@example.com"

Action:

  1. Run: python scripts/radicale-api.py contacts create --addressbook "Contacts" --name "John Doe" --email "john@example.com"
  2. Confirm creation

Decision Tree

When user mentions calendars or contacts:

  1. Determine operation type:

    • Calendar query ("show", "list", "what's on") → Use events list
    • Calendar create ("add", "create event", "schedule") → Use events create
    • Calendar delete ("remove", "delete", "cancel") → Use events delete
    • Contact query ("find", "search", "what's", "who is") → Use contacts search
    • Contact create ("add contact", "save contact") → Use contacts create
    • Contact delete ("remove contact", "delete contact") → Use contacts delete
  2. Identify target:

    • Calendar operations → Ask which calendar (default: "Personal")
    • Contact operations → Ask which addressbook (default: "Contacts")
  3. Extract parameters:

    • For events: Parse title, location, date/time from natural language
    • For contacts: Parse name, email, phone from natural language
  4. Execute command:

    • Run appropriate script command
    • Parse JSON output
  5. Present results:

    • Format JSON as human-readable text
    • Include relevant details (event times, contact info)
    • Confirm successful operations

Date/Time Handling

Important considerations:

  • All times are local to the Radicale server timezone
  • Use ISO 8601 format for consistency: YYYY-MM-DDTHH:MM:SS
  • When user specifies "7PM EST", convert to 24-hour local time
  • For all-day events, use same date for start/end with different times
  • Default event duration: 1 hour (if user doesn't specify end time)

Common translations:

  • "this week" → Calculate Mon-Sun dates from current date
  • "next week" → Calculate Mon-Sun dates for following week
  • "today" → Current date
  • "tomorrow" → Current date + 1 day
  • "7PM" → "19:00:00"
  • "noon" → "12:00:00"

Bundled Resources

scripts/radicale-api.py

Complete Python wrapper for CalDAV/CardDAV operations. Uses caldav library to connect to Radicale server and perform all calendar/contact operations.

Key features:

  • Loads credentials from .env file
  • JSON output for all operations
  • Error handling with clear messages
  • Supports all CalDAV/CardDAV operations

Direct usage: Can be called directly with command-line arguments (see examples above).

references/caldav-library.md

In-depth guide to the Python caldav library including:

  • Authentication patterns
  • Calendar operations (create, read, update, delete)
  • Event operations with iCalendar format
  • Contact operations with vCard format
  • Error handling patterns
  • Best practices

When to reference: When implementing custom operations beyond the wrapper script, or when debugging library-specific issues.

references/quick-reference.md

Quick command examples for all operations with sample inputs and outputs.

When to reference: When user needs examples or when uncertain about command syntax.

references/troubleshooting.md

Common errors and solutions including:

  • Installation issues
  • Connection problems
  • Authentication failures
  • Calendar/contact not found errors
  • Date/time format issues
  • Permission problems

When to reference: When operations fail or user reports errors.

Error Handling

All operations return JSON with status. Check for:

Connection errors:

  • ERROR: .env file not found → Guide user to create .env file
  • ERROR: Failed to connect to Radicale → Check Radicale is running, verify URL
  • ERROR: Authentication failed → Verify credentials in .env

Resource errors:

  • ERROR: Calendar 'X' not found → List available calendars with calendars list
  • ERROR: Addressbook 'X' not found → List addressbooks with contacts addressbooks

Data errors:

  • ValueError: Invalid isoformat string → Fix datetime format to ISO 8601
  • End time before start time → Adjust end time to be after start

Notes

Read-Write Operations:

  • All operations modify data on the Radicale server
  • Event creation is immediate (no confirmation prompt)
  • Contact creation is immediate (no confirmation prompt)
  • Deletions are permanent (no undo)

Performance:

  • Use date ranges for event queries to avoid loading all events
  • Search contacts instead of listing all when looking for specific person
  • Calendar/contact listing can be slow with large datasets

Limitations:

  • No timezone support in current implementation (uses local time)
  • No recurring event support yet
  • Contact fields limited to name, email, phone (vCard supports more)
  • No event reminders/alarms

Security:

  • All credentials stored in .env file (gitignored)
  • API script never logs credentials
  • Connection uses HTTP basic auth (HTTPS recommended for production)

Reference Documentation

Bundled references (load as needed):

  • references/caldav-library.md - Python caldav library guide
  • references/quick-reference.md - Command examples
  • references/troubleshooting.md - Error solutions

External documentation:


🔧 Agent Tool Usage Requirements

CRITICAL: When invoking scripts from this skill via the zsh-tool, ALWAYS use pty: true.

Without PTY mode, command output will not be visible even though commands execute successfully.

Correct invocation pattern:

typescript
<invoke name="mcp__plugin_zsh-tool_zsh-tool__zsh">
<parameter name="command">python ./skills/radicale/scripts/radicale-api.py [args]</parameter>
<parameter name="pty">true</parameter>
</invoke>

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Radicale AI skill do?

This skill should be used when managing calendars and contacts on a self-hosted Radicale CalDAV/CardDAV server. Use when the user asks to "list my calendar", "what's on my calendar this week", "show me my events", "when is my next event", "add to my calendar", "create an event", "schedule a meeting", "schedule an event", "delete an event", "cancel event", "remove event", "find a contact", "what's someone's email", "search my contacts", "who is", "add a contact", "save contact", "save someone's phone number", or mentions Radicale, CalDAV, CardDAV, calendar events, or contact management opera...

Why use Radicale on TypingMind?

Because you install it once and use it with any model. Radicale is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Radicale in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/jmagar/claude-homelab/tree/main/skills/radicale. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Radicale?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Radicale?

As many as you like. As long as a model supports skills, you can use Radicale with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Radicale AI skill free?

Yes. It is published on GitHub by jmagar under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇