Skip to main content

caldav-blade-mcp

A precision CalDAV MCP server that gives AI agents structured access to calendar data. Built for the Model Context Protocol with token efficiency as a first-class design goal.

Why another calendar MCP?

Most calendar integrations dump entire iCalendar blobs into the context window. A single week view can burn 3,000+ tokens before the model even starts reasoning. caldav-blade-mcp takes a different approach:

  • Compact output — pipe-delimited, one line per event, null fields omitted. A day's events in ~200 tokens.
  • Batch operations — cal_events_batch fetches N calendars in one tool call. One call instead of eleven for a family digest.
  • Purpose-built views — cal_today, cal_week, cal_freebusy give you exactly what you need with zero configuration.
  • Write-gated — read by default, writes require explicit opt-in. cal_delete has an additional confirm=true safety gate.

Quick start

# Install
uv pip install -e .

# Configure (single provider)
export CALDAV_URL="https://caldav.fastmail.com/dav/calendars/user/you@fastmail.com"
export CALDAV_USERNAME="you@fastmail.com"
export CALDAV_PASSWORD="app-specific-password"

# Run
caldav-blade-mcp

13 tools, 3 categories

Read (9 tools)

Tool Purpose Token cost
cal_info Health check — providers, connection, write gate ~50
cal_calendars List all calendars (name, UID, provider) ~20/cal
cal_events Events from one calendar in date range ~30/event
cal_events_batch Events from N calendars in one call ~30/event
cal_event Full detail by UID (attendees, recurrence) ~100
cal_search Search by text, attendee, location ~30/event
cal_today Today's events across all calendars ~30/event
cal_week This week's events across all calendars ~30/event
cal_freebusy Busy periods only — cheapest availability check ~15/period

Write (4 tools, gated)

Tool Purpose
cal_create Create event with all fields (description, location, recurrence, attendees, alarm)
cal_update Partial update — only changed fields, auto-increments SEQUENCE
cal_delete Delete by UID — requires confirm=true
cal_move Move event between calendars

Output format

── Work ──
08:30-09:30 | Standup | uid=abc123
14:00-15:00 | Design review @ Level 3 | loc=Level 3 | uid=def456

── Personal ──
All day | School holidays | uid=ghi789
18:30-19:30 | Swim squad | uid=jkl012

Multi-provider support

Run against multiple CalDAV servers simultaneously — useful when calendars span Fastmail, iCloud, Google, or self-hosted (Radicale, Baïkal, Nextcloud).

export CALDAV_PROVIDERS="fastmail,icloud"
export CALDAV_FASTMAIL_URL="https://caldav.fastmail.com/dav/calendars/user/..."
export CALDAV_FASTMAIL_USERNAME="you@fastmail.com"
export CALDAV_FASTMAIL_PASSWORD="fm-app-password"
export CALDAV_ICLOUD_URL="https://caldav.icloud.com/"
export CALDAV_ICLOUD_USERNAME="you@icloud.com"
export CALDAV_ICLOUD_PASSWORD="app-specific-password"

Single-provider mode (the CALDAV_URL / CALDAV_USERNAME / CALDAV_PASSWORD env vars) remains fully supported for simple setups.

Security model

Layer Mechanism
Write gate CALDAV_WRITE_ENABLED=true required for any mutation
Delete safety cal_delete additionally requires confirm=true
Credential scrubbing Passwords and server URLs stripped from all error output
Bearer auth Optional CALDAV_MCP_API_TOKEN for HTTP transport
No caching Credentials read from env at startup, never persisted

Claude Code integration

Add to your MCP config (e.g. claude.nix or settings.json):

{
  "mcpServers": {
    "calendar-piers": {
      "type": "stdio",
      "command": "uv",
      "args": ["--directory", "~/src/caldav-blade-mcp", "run", "caldav-blade-mcp"],
      "env": {
        "CALDAV_URL": "...",
        "CALDAV_USERNAME": "...",
        "CALDAV_PASSWORD": "...",
        "CALDAV_WRITE_ENABLED": "false"
      }
    }
  }
}

A bundled SKILL.md teaches Claude the optimal tool-calling patterns — batch over individual, freebusy over full event scans, convenience views for common queries.

Development

make install-dev    # Install with dev + test dependencies
make test           # Unit tests (mocked caldav, no server needed)
make check          # Lint + format + type-check
make run            # Start MCP server (stdio)

Architecture

src/caldav_blade_mcp/
├── server.py       — FastMCP 2.0 server, 13 @mcp.tool decorators
├── client.py       — CalDAVClient with multi-provider, typed exceptions
├── formatters.py   — Token-efficient output (pipe-delimited, null omission)
├── models.py       — Provider config, write-gate, constants
└── auth.py         — Bearer token middleware for HTTP transport

Built with FastMCP 2.0, caldav, and python-dateutil.

License

MIT

Metadata

Release files for caldav-blade-mcp 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for caldav-blade-mcp 0.4.0
File Size Uploaded
caldav_blade_mcp-0.4.0.tar.gz 142.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for caldav-blade-mcp 0.4.0
File Interpreter ABI Platform
caldav_blade_mcp-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 165.2 kB

Release files / caldav_blade_mcp-0.4.0.tar.gz

Download URL caldav_blade_mcp-0.4.0.tar.gz
Size 142.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4055b35730f79b0be7710881fd01962bd32e22c8fd7ab14f3bc90c0a8f225212
BLAKE2b-256 checksum
How to use checksums
c925c22b2852f0efe05bc80d94cede9f12dc4a0a438018209019d8b434f757a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.

Transparency log

Release files / caldav_blade_mcp-0.4.0-py3-none-any.whl

Download URL caldav_blade_mcp-0.4.0-py3-none-any.whl
Size 22.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2694e3c7dc7ff54964b63f0e979e4e65c43b43640d15485af313980604d0eecc
BLAKE2b-256 checksum
How to use checksums
d93d7f2d6324960445c808dc3ee6d81948ff76d6a35dbfd40521fd81588be8d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page