CalDAV Task Sync
pendingby speze88
Bidirectionally synchronize markdown tasks tagged with #caldav to/from a CalDAV server.
Obsidian CalDAV Task Sync
An Obsidian plugin that bidirectionally synchronizes markdown tasks to/from a CalDAV server (e.g. mailcow/SOGo).
Features
- Tag tasks with a configured calendar tag such as
#caldav,#work, or#private - Map multiple CalDAV calendars to different tags
- Syncs on file save — no background polling
- Bidirectional: push completions to the server, pull remote title/status changes back
- UIDs stored in invisible HTML comments so your notes stay readable
- Works with any CalDAV server that supports VTODO (mailcow, SOGo, Nextcloud, Baikal, etc.)
Task Format
Before sync (you write this):
- [ ] Buy groceries #private
After sync (UID written back automatically):
- [ ] Buy groceries #private <!-- caldav-uid:550e8400-e29b-41d4-a716-446655440000 -->
The UID comment is invisible in Obsidian's reading/preview mode.
Installation
Manual
- Download or build
main.jsandmanifest.json - Create the plugin folder in your vault:
<vault>/.obsidian/plugins/obsidian-caldav-sync/ - Copy
main.jsandmanifest.jsoninto that folder - Enable the plugin in Obsidian → Settings → Community plugins
Build from source
git clone https://github.com/your-username/obsidian-caldav-sync
cd obsidian-caldav-sync
npm install
npm run build
Then copy main.js and manifest.json to your vault's plugin folder as above.
Configuration
Go to Settings → CalDAV Task Sync and add one or more calendar mappings:
| Field | Description | Example |
|---|---|---|
| Calendar name | Optional label shown in settings | Private |
| Server URL | Full CalDAV calendar URL with trailing slash | https://mail.example.com/SOGo/dav/user@example.com/Calendar/personal/ |
| Username | Username for this calendar (usually your full email for mailcow) | user@example.com |
| Password | Password for this calendar | |
| Tag | Tag that routes a task into this calendar | #private |
Use Add calendar to create additional mappings. Each calendar stores its own URL and credentials, so different servers or accounts can be used side by side.
Example mappings:
| Tag | Calendar |
|---|---|
#private | Personal CalDAV calendar |
#work | Work CalDAV calendar |
Example task routing:
- [ ] Pay rent #private
- [ ] Prepare Q2 review #work
Each task is synced to the calendar whose configured tag appears on the same task line.
Finding your CalDAV URL (mailcow / SOGo)
Your calendar URL typically follows this pattern:
https://<mail-server>/SOGo/dav/<email>/Calendar/<calendar-name>/
You can verify it with curl:
curl -u user@example.com:password \
https://mail.example.com/SOGo/dav/user@example.com/Calendar/personal/ \
-X PROPFIND -H "Depth: 0"
A 207 Multi-Status response confirms the URL and credentials are correct.
Sync Behavior
Sync is triggered every time you save a markdown file.
Conflict resolution
| Scenario | Result |
|---|---|
Local [x], remote incomplete | Local wins — pushes STATUS:COMPLETED |
Local [ ], remote completed | Remote wins — marks task [x] in your note |
| Local title differs from remote SUMMARY | Remote wins — updates the title in your note |
| Remote VTODO not found (404) | Warning logged, local task unchanged |
| ETag conflict (412) | Re-fetches ETag and retries the PUT once |
Re-entrancy
When the plugin writes UIDs or pulled changes back to a file, it uses an internal guard to prevent that write from triggering another sync loop.
Dependencies
Limitations
- No periodic background sync — changes only sync on file save
- Remote-only tasks (created outside Obsidian) are not pulled into notes automatically
- No support for recurring tasks, due dates, or priorities (v1)
- Sync tag must appear on the same line as the task checkbox
License
MIT
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.