Skip to main content
Glama
sorglos-it

synology-calendar-mcp

by sorglos-it

synology-calendar-mcp

Claude Desktop Protocol Node License: MIT Donate

Lets Claude use the Calendar app of your Synology NAS — or any other CalDAV server: list calendars, read the events of a date range, create, change and delete appointments and todos, straight from a conversation. A Claude Desktop extension in a single .mcpb file: install, fill in three fields (NAS-Adresse, Benutzername, Passwort), done — the other three have defaults.

Folder

Purpose

Language

Start

Build

apps/server

MCP server: Claude's calendar and todo tools over CalDAV, built around caldav-mcp

JavaScript, Node.js ≥ 18

install the .mcpb in Claude Desktop

python tools/build.py → dist/synology-calendar-<version>.mcpb (install the dependencies first, see Development)

Start in 3 steps

You need Claude Desktop 0.10.0 or newer (Windows, macOS, Linux), a reachable Synology NAS with the Calendar app installed and CalDAV enabled, and the DSM user account that owns the calendars. Nothing else to install — Node ships with Claude Desktop, and all dependencies are inside the .mcpb.

  1. Get the extension synology-calendar-<version>.mcpb from Releases, or build it yourself (see Development).

  2. Install it in Claude Desktop: Settings → Extensions → Advanced settings → Install extension…, pick the file. Dragging it onto the extensions window works too.

  3. Fill in the fields (see Configuration) and switch the extension on. Then ask Claude something like "which calendars do I have?".

Related MCP server: CalDAV MCP Server

Update

Install the new .mcpb the same way; it replaces the old one. Once, for bundles built after 22 Sep 2026: the author name changed, so Claude Desktop sees a new extension. Uninstall the old Synology Calendar extension first (Settings → Extensions), then install the new one and fill in the fields again. From 1.1.5, Zertifikat prüfen is on. A NAS still on its self-signed certificate needs a valid one (DSM → Control Panel → Security → Certificate, e.g. Let's Encrypt), or the switch goes off — on your own network only.

Configuration

Field

Meaning

NAS-Adresse

Host name or IP only, e.g. nas.example.com. No https://, no path. A non-standard port goes here as nas.example.com:8443.

HTTPS verwenden

On → https, default port 5001. Off → http, default port 5000, and the password crosses the network unencrypted. These are the DSM defaults.

Benutzername

DSM login name of the user who owns the calendars

Passwort

DSM password; stored in the OS keychain, never in the package

Zertifikat prüfen

On by default: the extension only talks to a NAS whose certificate is valid for the name entered above, so nobody in between can pose as the NAS and read the password. Needs a real certificate on the NAS (e.g. Let's Encrypt). Switch off only for a NAS on its self-signed certificate, and only on your own network.

Zeitlimit pro Anfrage

Seconds allowed per request, default 45. Leave it alone unless the NAS is slow enough to run into it.

The labels are German because the extension manifest is; the fields behave exactly as described above.

Setup asks for a host name and a protocol switch, never a URL. The extension assembles the endpoint itself, which removes the single most common way to get CalDAV configuration wrong. Input is forgiving: a pasted https://, a trailing path or an explicit :port are handled instead of rejected. A self-signed certificate needs one switch, no manual NODE_TLS_REJECT_UNAUTHORIZED fiddling.

Tools

Tool

Purpose

list-calendars

All calendars with name and URL

list-events

Events in a date range, a recurring one per date it falls on

create-event

New event, optionally all-day or recurring

update-event

Change an existing event; everything not passed stays as it is

delete-event

Remove an event

list-todos

Open todos by default; completed or all on request

create-todo

New todo

update-todo

Change a todo

complete-todo

Mark a todo done

delete-todo

Remove a todo

Security and caveats

  • Runs locally. The server talks to your NAS directly; nothing is sent to a third party. Claude Desktop stores the password in the OS keychain — there are no credentials in the package.

  • Certificate checking protects the password. It is on by default since 1.1.5. Switched off, it disables TLS verification for the whole Node process, and anyone between your computer and the NAS can pose as the NAS and read the DSM password — acceptable on your own LAN with a self-signed NAS, wrong anywhere else. Certificates trusted by the operating system count too (Node.js 22.19 / 24.5 or newer). A rejected certificate is reported with the reason and both ways out.

  • Calendar URLs stay on the NAS. Every request carries the DSM password, so a calendar URL on another host is refused before anything is sent — otherwise one prompt injection in an event text would be enough to leak it. A calendar URL with ? or #, and event or todo uids with /, \, ?, # or %, are refused as well: they could address the whole calendar or objects in other calendars.

  • A change edits the object, it does not rebuild it. Since 1.1.5 an update is written into the iCalendar object the NAS has, so attendees, alarms, time zones, the cancelled and moved dates of a series and a task's repetition rule survive a rename. Before that, every change rebuilt the object from a handful of fields and quietly lost the rest. Whole-day dates stay dates, which is why they no longer slide to the day before.

  • A change counts as done only when the NAS confirms it. A write is never repeated at an address the answer points to, and an answer that is a web page — DSM after the session ended — is reported as such instead of passing for success or for an empty calendar.

  • Shared calendars can be read-only. Synology hands out team calendars without write privileges in some configurations; writes then fail with HTTP 403.

  • The connection is opened on first use, not at startup. A wrong password or an unreachable NAS therefore surfaces as an error on the tool that needed it, and the next call tries again. Up to and including 1.1.2 the server connected before it spoke MCP, so a NAS that stayed quiet for a minute cost the whole handshake and Claude Desktop reported "Verbindung zum Erweiterungs-Server nicht möglich" — an extension that looked broken while only the NAS was slow.

  • Calendar URLs are absolutized before every request. list-calendars returns bare paths — ts-caldav strips its calendar URLs to the pathname — and axios resolves a relative URL against the base URL rather than the origin, so /caldav.php/user/home/ became https://nas:5001/caldav/caldav.php/user/home/. Reads died on it: getComponents() sends its REPORT without absolutizing and reports every failure as "Failed to retrieve vevents from the CalDAV server", which is what 1.1.3 and earlier did for list-events and list-todos while writes still went through. The wrapper in apps/server/vendor/caldav-mcp/dist/index.js now resolves the URL for every client call, so passing a full https://nas:5001/caldav.php/... URL by hand is no longer needed.

  • DSM is slow to authenticate. The first authenticated request of a session regularly takes five seconds or more, later ones come from its session cache in milliseconds. ts-caldav hardcodes a 5000 ms timeout that caldav-mcp never overrides, so the wrapper raises it to 45 s before the server starts. The Zeitlimit pro Anfrage field changes that; it reaches the wrapper as CALDAV_TIMEOUT, in seconds, and a blank or unparsable value falls back to 45 rather than stopping the server. A NAS that needs several seconds per request on every call is worth looking at on the DSM side — a directory-service lookup running into its own timeout produces exactly that pattern.

Development

apps/server/manifest.json       name, settings and start command of the extension (mcpb format)
apps/server/index.js            entry point: turns the settings into caldav-mcp's environment, then starts it
apps/server/package.json        marks index.js as an ES module
apps/server/assets/icon.png     icon shown in Claude Desktop
apps/server/VERSION             version, the same as in manifest.json and package.json
apps/server/vendor/caldav-mcp/  caldav-mcp 0.10.0 with our changes — origin and changes in THIRD-PARTY.md
apps/server/tests/              checks against fake servers; never contact a real NAS and never ship in the bundle
tools/build.py                  packs apps/server, README.md, LICENSE and THIRD-PARTY.md into dist/synology-calendar-<version>.mcpb
cd apps/server/tests
node test_ical.mjs           # reading and writing iCalendar objects
python test_mcp.py           # the tools over real MCP against a fake NAS: where requests go
python test_written_ics.py   # the same, looking at what is written into them
uv run --with "mcp>=2.0,<3" --with httpx --with cryptography python test_tls.py   # certificate checking

Every check prints one line and the run ends with all passed. Pass an unpacked .mcpb folder as the first argument to run the two Python suites against a built bundle instead of the sources.

npm install --prefix apps/server/vendor/caldav-mcp --omit=dev --ignore-scripts
python tools/build.py

The first line fetches the libraries caldav-mcp needs into apps/server/vendor/caldav-mcp/node_modules/; they are not kept in this repository. The second one (Python 3.8 or newer, nothing else) packs everything into the .mcpb and stops when a library is missing or when VERSION, manifest.json and package.json name different versions — raise all three for a new version. How to move to a newer caldav-mcp is described in THIRD-PARTY.md.

How it works:

  1. Claude Desktop starts index.js with the configured fields as environment variables.

  2. The wrapper builds CALDAV_BASE_URL from host name and protocol switch and appends the CalDAV path /caldav/. ts-caldav can find that path by itself on most servers, but not on DSM: its well-known probe uses GET where DSM only answers OPTIONS, and its fallback candidates carry no trailing slash where DSM insists on one. Discovery would fall back to the bare origin, DSM serves the web UI there, and no principal is ever found.

  3. With certificate checking off, NODE_TLS_REJECT_UNAUTHORIZED=0 is set before anything connects. ts-caldav's discovery probes run only when the base URL answers with an error, so an unreachable NAS costs one request timeout, not eight.

  4. The bundled caldav-mcp server takes over, exposes the ten tools over stdio and answers the MCP handshake immediately. The NAS is contacted on the first tool call, not at startup.

To run the server without Claude Desktop, set the variables and start it from the project folder:

node apps/server/index.js

Variable

Meaning

CALDAV_HOST

Host name, :port optional

CALDAV_HTTPS

true (default) → https + port 5001, false → http + port 5000

CALDAV_USERNAME

DSM login name

CALDAV_PASSWORD

DSM password

CALDAV_VERIFY_SSL

true (default) checks the certificate; false only for a self-signed NAS on your own network

CALDAV_TIMEOUT

Seconds per request, default 45. Blank or unparsable falls back to the default.

CALDAV_BASE_URL

Legacy: a complete endpoint URL, wins over CALDAV_HOST — useful for a server that lives behind a path

See also synology-contacts-mcp — the same idea for contacts over CardDAV — and github-mcp for repositories on github.com. Changes: CHANGELOG.md.

Credits

Built around caldav-mcp by Dominik Grusemann (MIT), bundled with the changes described in THIRD-PARTY.md.

License

This project is licensed under the MIT License — © 2026 Sorglos Thomas Weirich. Third-party code: THIRD-PARTY.md.

Donate via PayPal

If this extension saved you time, you can support further development:

Donate with PayPal

➡️ Donate via PayPal

Related MCP Connectors

Related MCP Servers