Introduction¶
In DSH agent scenarios, models often need to query “what events are scheduled for today” or “is there any availability tomorrow morning,” or convert a todo item into a calendar event. If they have to manually export calendar text, take screenshots, or write custom sync scripts every time, it becomes difficult for the model to participate directly in scheduling.
dsh-calendar is a DSH community plugin that reads and writes calendar events via CalDAV, supporting Google, iCloud, Nextcloud, and any custom CalDAV server. The DSH ecosystem emphasizes “everything is a plugin”; here we introduce a community plugin, not an official app store built-in capability.
Plugin Overview¶
dsh-calendar addresses a clear problem: encapsulating calendar event capabilities into model tools that DSH can invoke.
It provides five tools oriented towards the model:
calendar_list: List events within a time rangecalendar_create: Create new eventscalendar_update: Update events byuidcalendar_delete: Delete events byuidcalendar_search: Search events by keywords
Several key facts are as follows:
- GitHub Repository:
https://github.com/STARDUSTLC666/dsh-calendar - License:
MIT - Runtime Requirements: Node
>=22 - Authentication Method: Basic Auth using app-specific passwords
- Does not support Google / iCloud OAuth login flow
- No settings page UI; configuration is handled via the
cordis.patch.ymlin the profile - The stable event identifier
uiduses the CalDAVhref
Installation and Enablement¶
First, install the plugin in the target profile:
dsh plugin --profile web add dsh-calendar
After installation, restart dsh.
The default configuration usually does not contain any credentials. At this point, the plugin can load normally, but tools will return Chinese guidance errors when invoked, prompting you to complete the configuration. The configuration location is the cordis.patch.yml of the current profile, where you override the calendar line’s config by id.
A minimal example:
- id: calendar
config:
provider: custom
caldavUrl: https://dav.example.com/calendars/me/work/
username: me
password: your app-specific password
If you do not want to write the password into the YAML, you can use the environment variable DSH_CALENDAR_PASSWORD.
The uninstall command is as follows:
dsh plugin --profile web remove dsh-calendar
After uninstalling, restart the Web service. If a thorough cleanup is needed, you can manually delete the corresponding plugin line from the cordis.patch.yml in your profile.
Configuration Fields¶
All configuration resides within the calendar line in cordis.patch.yml. Common fields are as follows:
provider:google,icloud,nextcloud,customcaldavUrl: The full calendar collection URL. Required forcustomandicloud;google/nextcloudcan also be manually filled to override presetsusername: CalDAV account. For Google / iCloud, usually the account emailpassword: Password. For Google / iCloud, please use an app-specific passwordproxyUrl: Local proxy address. May be needed when accessing Google / iCloud CalDAV endpoints in ChinacalendarId: Google specific, calendar ID, usually your emailhost: Nextcloud specific, e.g.,https://cloud.example.comuser: Nextcloud specific, CalDAV usercalendar: Nextcloud specific, calendar name
Typical Usage¶
Google Calendar¶
An example for Google is as follows:
- id: calendar
config:
provider: google
username: you@gmail.com
calendarId: you@gmail.com
# You can also use DSH_CALENDAR_PASSWORD
password: your app-specific password
Google’s CalDAV collection URL is constructed by the plugin:
https://apidata.googleusercontent.com/caldav/v2/<calendarId>/events
Google requires the use of an app-specific password; the Google login password cannot be used.
iCloud Calendar¶
An example for iCloud is as follows:
- id: calendar
config:
provider: icloud
username: you@icloud.com
caldavUrl: https://caldav.icloud.com/123456789/calendars/<calendarID>/
# You can also use DSH_CALENDAR_PASSWORD
password: your app-specific password
iCloud requires manually filling in the full calendar collection URL, including the user ID and calendar ID. The plugin does not perform automatic principal discovery and does not support multi-calendar selection.
iCloud also requires the use of an app-specific password; the Apple ID login password cannot be used.
Nextcloud Calendar¶
An example for Nextcloud is as follows:
- id: calendar
config:
provider: nextcloud
username: alice
host: https://cloud.example.com
user: alice
calendar: personal
# You can also use DSH_CALENDAR_PASSWORD
password: your app-specific password
The plugin will construct a URL similar to:
https://cloud.example.com/remote.php/dav/calendars/alice/personal/
Custom CalDAV¶
An example for custom CalDAV is as follows:
- id: calendar
config:
provider: custom
caldavUrl: https://dav.example.com/calendars/me/work/
username: me
# You can also use DSH_CALENDAR_PASSWORD
password: your app-specific password
This method is suitable for self-hosted Radicale, Nextcloud, or other servers providing standard CalDAV.
Tool Behavior¶
calendar_list¶
calendar_list is used to list events within a specific time range.
Supported parameters:
start/end: ISO 8601 timeexpand: Whether to expand recurring events, defaulttruemaxOccurrences: Upper limit for expanding recurring events, default30, range1-200
By default, calendar_list will expand recurring events. The expanded instances will carry:
isOccurrence: trueseriesStart
Non-recurring events will remain:
isOccurrence: false
If expand=false is set, recurring events will be returned as original single entries, carrying rrule.
The results are stably sorted by start time.
calendar_create¶
calendar_create is used to create new events.
Required fields:
summarystartend
Optional fields:
descriptionlocationallDayrrule
The plugin will validate real calendar dates and require end >= start. For example, dates that do not exist (like 2025-02-30) will be rejected.
calendar_update¶
calendar_update updates events by uid.
Updatable fields include:
summarystartenddescriptionlocationallDayrrule
Fields not provided retain their original values. Recurrence rules will not be lost when updating other fields.
calendar_delete¶
calendar_delete deletes events by uid.
calendar_search¶
calendar_search is used to search for events by keywords.
It performs client-side filtering on the title, description, location, and UID, case-insensitive.
Supported parameters:
- keyword
limit: Default50, range1-200
The results are sorted by start time.
Note: calendar_search returns the original series and does not expand recurring events.
Recurring Event Limits¶
calendar_update and calendar_delete operate on the entire recurring series via uid.
This means they are suitable for modifying or deleting an entire recurring schedule, but do not support modifying or deleting a single occurrence. In other words, RECURRENCE-ID instance-level modification or deletion is not supported.
If you need to “cancel just Wednesday,” this plugin currently cannot do that directly.
Timezone and Time Format¶
Input and output use ISO 8601 uniformly.
- Timed events are output in UTC, for example:
2025-01-15T01:00:00Z
- All-day events are output in date format:
2025-01-15
Input can include timezone offsets, for example:
2025-01-15T09:00:00+08:00
The plugin converts them to UTC for storage internally.
Events with named timezones (using TZID) will be converted to UTC. Complex timezone rules such as all-day boundaries and Daylight Saving Time are not processed in granular detail.
Proxy and Network Limits¶
Direct access to Google and iCloud CalDAV endpoints is not possible in China. You can use the proxyUrl configuration to set up a local proxy.
Example:
- id: calendar
config:
provider: google
username: you@gmail.com
calendarId: you@gmail.com
password: your app-specific password
proxyUrl: http://127.0.0.1:7890
Here, proxyUrl should be filled with the actual HTTP port exposed by your local proxy client. For CalDAV services that can be accessed directly in China (e.g., self-hosted Nextcloud or other private CalDAV services), proxy configuration is usually not required.
The overall tool timeout is 60 seconds. The plugin does not propagate AbortSignal through individual network requests.
Use Cases¶
dsh-calendar is quite suitable for scenarios such as:
- You use DSH as an agent or assistant and want the model to be able to query the calendar directly
- You need the model to create, update, delete, or search schedules
- You already have Google, iCloud, Nextcloud, or other CalDAV services
- You can maintain plugin configuration via
cordis.patch.yml - You accept that the current version does not have a Web settings page and configuration is written directly in YAML
Precautions¶
It is recommended to pay attention to the following points before use:
- The plugin runs with the permissions of the current
dshprocess; it is recommended to check the source code and license before installing. - Only Basic Auth is supported; Google / iCloud OAuth is not supported.
- Google / iCloud must use app-specific passwords; login passwords cannot be used.
calendar_updateandcalendar_deletetarget the entire recurring series and do not support single-instance operations.calendar_searchdoes not expand recurring events.- iCloud requires manually filling in the full calendar collection URL.
- There is no settings page UI; all configuration goes through
cordis.patch.yml. - If the call returns 401 / 403, prioritize checking if you mistakenly used the login password.
Conclusion¶
The value of dsh-calendar lies in wrapping CalDAV calendar capabilities into five stable model tools, enabling DSH agents to directly perform actions such as querying, creating, updating, deleting, and searching schedules.
GitHub Repository:
https://github.com/STARDUSTLC666/dsh-calendar