Radicale CalDAV MCP Server
by mvelak
README.md
# Radicale CalDAV MCP Server
A Model Context Protocol (MCP) server built with [FastMCP](https://github.com/jlowin/fastmcp) / the official MCP Python SDK that bridges LLM agents (such as Nous Hermes, Claude, OpenAI) to a self-hosted [Radicale](https://radicale.org/) CalDAV calendar and task manager.
---
## Features
### 📅 Calendar Events (`VEVENT`)
- **`get_events`**: Query events within date/time ranges with optional keyword search across summary, description, and location.
- **`get_free_busy_slots`**: Calculate open, unbooked time slots during configurable business hours (e.g. 9:00 AM - 5:00 PM) in any IANA timezone.
- **`create_event`**: Schedule new events with automatic ISO validation, attendee invitations, and overlap/conflict detection.
- **`update_event`**: Modify existing events by UID without overwriting untouched fields.
- **`delete_event`**: Remove events by UID.
### 📝 Tasks & To-Dos (`VTODO`)
- **`list_todos`**: Fetch pending or completed tasks filtered by status (`NEEDS-ACTION`, `COMPLETED`, `IN-PROCESS`, `CANCELLED`, `ALL`).
- **`create_todo`**: Create tasks with due dates, priority levels (1-9), and descriptions.
- **`complete_todo`**: Mark tasks as completed with automatic completion timestamps.
### 🚀 Transports & Deployment
- **STDIO Transport**: Default transport for local execution (e.g. Claude Desktop, local agents).
- **SSE (Server-Sent Events) Transport**: Over HTTP for remote, always-on deployments (e.g. Coolify, Docker).
---
## Configuration
Configure the server via environment variables or a `.env` file:
| Variable | Default | Description |
|---|---|---|
| `RADICALE_BASE_URL` | `http://localhost:5232` | Base URL to Radicale (e.g. `https://radicale.dubblu.app`) |
| `RADICALE_USERNAME` | `mvela581` | CalDAV username |
| `RADICALE_PASSWORD` | `""` | CalDAV password |
| `RADICALE_CALENDAR_SLUG` | `seuspeptides` | Target calendar slug / collection name |
| `DEFAULT_TIMEZONE` | `America/New_York` | Default IANA timezone |
| `MCP_TRANSPORT` | `stdio` | Transport protocol: `stdio` or `sse` |
| `MCP_HOST` | `0.0.0.0` | Host interface for SSE mode |
| `MCP_PORT` | `8000` | Port number for SSE mode |
---
## Local Quickstart
### 1. Installation
```bash
# Clone and enter directory
cd radicale-mcp-server
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
```
### 2. Configure Environment
Copy `.env.example` to `.env` and set your credentials:
```bash
cp .env.example .env
```
### 3. Run Locally
#### STDIO Mode (Local Pipe)
```bash
python server.py --stdio
```
#### SSE Mode (HTTP Server)
```bash
python server.py --sse --host 0.0.0.0 --port 8000
```
### 4. Run Test Client
```bash
# Test via STDIO
python test_client.py --mode stdio
# Test via SSE (when server is running)
python test_client.py --mode sse --sse-url http://localhost:8000/sse
```
### 5. Run Automated Tests
```bash
pytest -v
```
---
## Coolify Deployment
Deploy the MCP server on [Coolify](https://coolify.io) with zero configuration:
1. Create a new service in Coolify: **Docker Compose** or **Dockerfile**.
2. Point it to this repository or paste the `docker-compose.yml`.
3. Set the following environment variables in Coolify UI:
- `RADICALE_BASE_URL=https://radicale.dubblu.app`
- `RADICALE_USERNAME=mvela581`
- `RADICALE_PASSWORD=your_password`
- `RADICALE_CALENDAR_SLUG=seuspeptides`
- `DEFAULT_TIMEZONE=America/New_York`
- `MCP_TRANSPORT=sse`
- `MCP_PORT=8000`
4. Expose port `8000` via Coolify reverse proxy with your domain (e.g. `https://mcp-calendar.yourdomain.com`).
5. Your SSE endpoint will be accessible at:
```
https://mcp-calendar.yourdomain.com/sse
```
---
## LLM Agent Integration (Nous Hermes / Claude Desktop)
### Claude Desktop Configuration
Add the following to your `claude_desktop_config.json`:
#### Local STDIO:
```json
{
"mcpServers": {
"radicale_calendar": {
"command": "/path/to/radicale-mcp-server/.venv/bin/python",
"args": ["/path/to/radicale-mcp-server/server.py", "--stdio"],
"env": {
"RADICALE_BASE_URL": "https://radicale.dubblu.app",
"RADICALE_USERNAME": "mvela581",
"RADICALE_PASSWORD": "your_password",
"RADICALE_CALENDAR_SLUG": "seuspeptides",
"DEFAULT_TIMEZONE": "America/New_York"
}
}
}
}
```
#### Remote SSE (Coolify):
```json
{
"mcpServers": {
"radicale_calendar": {
"url": "https://mcp-calendar.yourdomain.com/sse"
}
}
}
```
### Nous Hermes Agent Integration
Tool definitions are auto-generated from docstrings with type specifications. Sample prompt usage:
```json
{
"name": "get_free_busy_slots",
"arguments": {
"start_date": "2026-08-26",
"end_date": "2026-08-28",
"slot_duration_minutes": 30,
"working_hours_start": 9,
"working_hours_end": 17,
"timezone": "America/New_York"
}
}
```
---
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues