calendar-mcp-server
Provides CalDAV integration with iCloud, allowing calendar management (list calendars, query events, create/update/delete events with dry-run safety) using app-specific passwords.
Provides CalDAV integration with Nextcloud, enabling calendar reading and writing (list calendars, query events, create/update/delete events with dry-run safety).
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@calendar-mcp-serverlist my calendars"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
calendar-mcp-server (calmcp)
By Erik Bitzek e.bitzek@mpi-susmat.de — licensed under PolyForm Noncommercial 1.0.0
A thin, privacy-respecting CalDAV toolkit that lets an LLM read and manage your calendars — safely. The intelligence lives in the LLM and a small set of skill prompts; the tool itself is a compact set of well-guarded primitives with dry-run writes, role gating, and an audit log.
Works with any CalDAV server (Kerio Connect, Apple iCloud, Nextcloud, Radicale, Fastmail, …). Exposes everything over the Model Context Protocol (MCP) so it plugs straight into Claude Desktop, Claude Code, and Cowork.
Status. Read commands (
list_calendars,discover,query_events,find_events,get_free_busy,export_ics) and write commands (create_event,update_event,move_event,delete_event— dry-run by default) are implemented, plus the MCP adapter and LLM skills. Google (via its own API) is deferred; see DESIGN.md.
Why this design
No secrets in the repo. Passwords never live in the code, in
calendars.yaml, or in environment variables — they're stored in your OS keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service).Writes are safe by default. Every write is a
--confirm-gated dry-run that prints abefore/afterdiff first. Writing to a calendar you don't own needs a second--confirm-foreigngate. Every real write is appended to an audit log.Least privilege. A small YAML registry maps friendly calendar ids to accounts and a safety
role(owner/writable/read-only).LLM-friendly. Ships with skill prompts (
skills/) so an assistant can turn free-text dates into events, do bulk edits, and check overlaps.
Related MCP server: dav-mcp
Quick start
# 1. Install
git clone https://github.com/biterik/calendar-mcp-server.git
cd calendar-mcp-server
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[mcp]" # add ,dev for tests/lint: ".[mcp,dev]"
# 2. Create your registry (copy the example; it is git-ignored)
cp calendars.example.yaml calendars.yaml
$EDITOR calendars.yaml
# 3. Store each account's password in your OS keyring (never in the repo)
keyring set calmcp/kerio_personal your-username # prompts, hidden input
# 4. Find your real calendars and paste the ones you want into calendars.yaml
calmcp discover
# 5. Check everything is reachable
calmcp list_calendarsWindows / Linux. Use
pythoninstead ofpython3on Windows, and activate the venv with.venv\Scripts\Activate.ps1(PowerShell) or.venv\Scripts\activate.bat(cmd). On Linux/macOS usesource .venv/bin/activateas shown. Everything else is identical across platforms —calmcpworks the same on all three.
Configuration
Where the registry lives
calmcp looks for your calendars.yaml in this order and uses the first it finds:
$CALMCP_REGISTRY(an explicit path)./calendars.yaml(the current directory)~/.calendars.yaml(per-user; works on every platform)the platform-native config directory:
Linux:
~/.config/calmcp/calendars.yaml(or$XDG_CONFIG_HOME/calmcp/…)macOS:
~/Library/Application Support/calmcp/calendars.yamlWindows:
%APPDATA%\calmcp\calendars.yaml
To run calmcp from anywhere, put your file in that config directory (or use
~/.calendars.yaml). You can always override with --registry path/to/calendars.yaml or CALMCP_REGISTRY=....
calendars.yaml is git-ignored, so it never ends up in the repo and a
git pull will never overwrite it. Only calendars.example.yaml is tracked.
The registry file
It maps calendar ids → accounts → roles. No passwords — those go in the keyring.
accounts:
kerio_personal:
type: caldav
url: "https://caldav.example.de/caldav/users/example.de/jdoe"
username: jdoe
keyring_service: "calmcp/kerio_personal"
verify_ssl: true
icloud:
type: caldav
url: "https://caldav.icloud.com"
username: "your-apple-id@icloud.com"
keyring_service: "calmcp/icloud" # Apple APP-SPECIFIC password
calendars:
- id: me_personal # you own this one
account: kerio_personal
role: owner
- id: family # shared to you, read-only
account: icloud
name: "Family"
role: read-only
defaults:
write_calendar: me_personal
timezone: Europe/BerlinCredentials (OS keyring)
Passwords live in your operating system's credential store — never in the repo: macOS Keychain, Windows Credential Manager, Linux Secret Service (GNOME Keyring / KWallet, via libsecret). Set one with:
keyring set <keyring_service> <username> # e.g. keyring set calmcp/icloud you@icloud.com
# If the `keyring` command isn't on PATH (common on Windows):
python -m keyring set <keyring_service> <username>Headless Linux note. The Secret Service needs a running desktop / D-Bus
session. On a server — or if you see "No recommended backend" — install an
alternative backend (pip install keyrings.alt) or run inside an unlocked
keyring session. Because the MCP server is launched without a terminal, the
password must already be in the keyring before you start your Claude client
(there's nowhere to prompt).
iCloud
iCloud is just another CalDAV account. Use https://caldav.icloud.com and an
app-specific password (generate one at
appleid.apple.com → Sign-In & Security):
keyring set calmcp/icloud your-apple-id@icloud.com # paste the app-specific passwordFinding calendars with discover
Instead of hunting for CalDAV URLs by hand, ask the server:
calmcp discover # all configured accounts
calmcp discover --account icloud # just one account
calmcp discover --owner cm-office # also probe a calendar shared TO youIt prints the real name and url of every calendar it can see. Copy the URL
of the one you want into calendars.yaml as a new entry. discover is
read-only and never changes anything.
Command-line usage
# Read:
calmcp list_calendars
calmcp query_events --from 2026-06-01 --to 2026-06-30
calmcp query_events --from 2026-06-01 --to 2026-06-30 --calendars me_personal --json
calmcp find_events --from 2026-06-01 --to 2026-12-31 --q "DFG"
calmcp get_free_busy --from 2026-06-14 --to 2026-06-21
calmcp export_ics --from 2026-06-01 --to 2026-06-30 --out june.icsWriting events (safe by default)
Write commands print a dry-run diff and do nothing until you add --confirm:
# Preview only — writes nothing:
calmcp create_event --calendar me_personal --summary "Dentist" \
--start "2026-07-01 09:00" --end "2026-07-01 09:30"
# Actually create it:
calmcp create_event --calendar me_personal --summary "Dentist" \
--start "2026-07-01 09:00" --end "2026-07-01 09:30" --confirm
calmcp update_event --calendar me_personal --uid <uid> --set location="Room 2" --confirm
calmcp move_event --calendar me_personal --uid <uid> \
--start "2026-07-01 10:00" --end "2026-07-01 10:30" --confirm
calmcp delete_event --calendar me_personal --uid <uid> --confirmWriting to a calendar whose role isn't owner adds a warning and requires a
second --confirm-foreign gate. Recurring writes take --scope this|all|thisAndFuture.
Every real write is appended to an audit log — ~/.local/state/calmcp/audit.jsonl
on Linux/macOS, %LOCALAPPDATA%\calmcp\audit.jsonl on Windows (override with
CALMCP_STATE_DIR).
Connect to Claude (MCP)
calmcp exposes these tools over MCP (stdio):
Tool | What it does |
| List configured calendars, roles, and reachability |
| List calendars present on the server (to add to the registry) |
| List events in a date range (optionally expand recurrences) |
| Full-text search across calendars in a range |
| Free/busy blocks for a range |
| Export a range to iCalendar ( |
| Create an event (dry-run unless confirmed) |
| Change fields on an event |
| Reschedule an event |
| Delete an event |
The MCP server finds its registry the same way the CLI does (see
Where the registry lives). Because your client
launches the server from an arbitrary working directory, set CALMCP_REGISTRY
to an absolute path (or keep your file at ~/.config/calmcp/calendars.yaml).
Claude Desktop
Edit the config file — macOS:
~/Library/Application Support/Claude/claude_desktop_config.json; Windows:
%APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"calmcp": {
"command": "/path/to/calendar-mcp-server/.venv/bin/calmcp-mcp",
"env": {
"CALMCP_REGISTRY": "/path/to/calendar-mcp-server/calendars.yaml"
}
}
}
}Fully quit and reopen Claude Desktop; the calmcp tools appear in a new chat.
On Windows, the launcher is calmcp-mcp.exe under Scripts, and JSON
requires escaped backslashes:
{
"mcpServers": {
"calmcp": {
"command": "C:\\Users\\you\\calendar-mcp-server\\.venv\\Scripts\\calmcp-mcp.exe",
"env": {
"CALMCP_REGISTRY": "C:\\Users\\you\\calendar-mcp-server\\calendars.yaml"
}
}
}
}(Tip: put your registry at the platform config path above and you can drop the
CALMCP_REGISTRY env entirely.)
Claude Code
claude mcp add calmcp \
--env CALMCP_REGISTRY=/path/to/calendar-mcp-server/calendars.yaml \
-- /path/to/calendar-mcp-server/.venv/bin/calmcp-mcpSkills
The prompts in skills/ (dates-to-events, bulk-edit,
overlap-check) teach an assistant common calendar workflows on top of these
tools.
Updating
Because your calendars.yaml and keyring passwords live outside the repo,
updating is just:
git pull
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[mcp]" # in case dependencies changedYour registry and credentials are untouched. If you moved your registry to
~/.config/calmcp/calendars.yaml, you can even delete and re-clone the repo
without losing your setup.
Develop
pip install -e ".[mcp,dev]"
ruff check .
mypy calmcp
pytestTests run against a local Radicale CalDAV fixture — no real credentials, and no network calls to any real provider.
License
Copyright © 2026 Erik Bitzek e.bitzek@mpi-susmat.de.
Released under the PolyForm Noncommercial License 1.0.0 — free to use, modify, and share for any noncommercial purpose (personal projects, research, education, and other noncommercial organizations). Commercial use requires a separate license from the author.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/biterik/calendar-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server