Skip to content

Fix Nextcloud UUID principals for DAV + robust OCS sharing (paths + internal UUID users)#638

Open
Khazhinov wants to merge 10 commits into
cbcoutinho:masterfrom
Khazhinov:principal-discovery
Open

Fix Nextcloud UUID principals for DAV + robust OCS sharing (paths + internal UUID users)#638
Khazhinov wants to merge 10 commits into
cbcoutinho:masterfrom
Khazhinov:principal-discovery

Conversation

@Khazhinov

@Khazhinov Khazhinov commented Mar 20, 2026

Copy link
Copy Markdown

Summary

Nextcloud frequently uses a UUID-based DAV principal for current-user-principal. The MCP server client previously built CalDAV/CardDAV “home” paths from NEXTCLOUD_USERNAME, which could lead to empty calendars/events and broken addressbook
resolution.
This MR includes:
Correct principal discovery for CalDAV/CardDAV (UUID principals)
• current-user-principal → discover cal:calendar-home-set / card:addressbook-home-set
• cache discovered home-set URLs and fall back to username-based paths only if discovery fails
Fix & performance hardening for CardDAV contacts
• nc_contacts_list_contacts now supports:
• query (server-side CardDAV filtering via card:text-match on vCard FN)
• limit (best-effort server-side limit to avoid huge responses/timeouts)
• query is best-effort extended with RU→LAT transliteration (e.g. search “Агарков” matches vCards storing “Agarkov”)
• vCard parsing is resilient to invalid BDAY: a single broken contact no longer prevents loading the whole addressbook
Fix WebDAV file browsing/search on UUID-principal Nextcloud
• WebDAV “files home” base path now uses the discovered UUID principal (not NEXTCLOUD_USERNAME), so:
• nc_webdav_list_directory no longer fails with 404
• nc_webdav_find_by_name no longer fails with 404
Fix OCS sharing/public link generation on this Nextcloud
• Normalize inputs for /ocs/v2.php/apps/files_sharing/api/v1/shares:
• decode WebDAV href/%xx segments into decoded file/folder path before calling OCS
• support href-like paths by stripping /remote.php/dav/files//... prefix
• For share_type=0 (internal user share):
• resolve shareWith to internal UUID user id via /ocs/v2.php/cloud/users?search=...
• if “sharing with yourself” is forbidden (403), automatically fall back to share_type=3 (public link) for the same path

Files / Components

• nextcloud_mcp_server/client/calendar.py
• nextcloud_mcp_server/client/contacts.py
• nextcloud_mcp_server/server/contacts.py
• nextcloud_mcp_server/client/webdav.py
• nextcloud_mcp_server/client/sharing.py

Changes in MCP tools

• nc_contacts_list_contacts(addressbook, query?, limit?)
• query optional, server-side filtering by vCard FN
• limit optional (defaults to 50)
• Sharing behavior (tool signature unchanged) now works reliably for:
• internal user shares (share_type=0) with correct UUID shareWith
• public links (share_type=3) even when paths originate from WebDAV (encoded/href-like)

Test plan

  1. Start nextcloud-mcp-server.
  2. Verify calendars load:

• call nc_calendar_list_calendars → result is non-empty.
3. Verify addressbooks load:

• call nc_contacts_list_addressbooks → includes the relevant addressbook (e.g. “Учётные записи”).
4. Verify contacts search:

• call nc_contacts_list_contacts with query="Агарков" and small limit (e.g. 5).
5. Verify contacts “no query” is capped:

• call nc_contacts_list_contacts with only addressbook → returns up to default limit (50).
6. Verify WebDAV file browsing/search:

• call nc_webdav_list_directory(path="") → no 404; returns entries.
• call nc_webdav_find_by_name(pattern="%%") → returns matching files.
7. Verify sharing / public links:

• get a file path via nc_webdav_list_directory
• call nc_share_create with:
• share_type=0, share_with=, read permissions for a docx path
• expected: no HTTP 404; returns usable url (internally falls back to share_type=3 when needed)

Notes

• Backwards compatibility: existing callers that pass only addressbook still work; the server caps results by default to prevent timeouts on large addressbooks.
• Explicit types:
• share_type=0 internal user share
• share_type=3 public link

vkhazhinov added 3 commits March 20, 2026 14:48
Use DAV current-user-principal + cal:calendar-home-set and card:addressbook-home-set to avoid empty calendars/contacts when Nextcloud uses UUID principals. No functional interface changes.
Some Nextcloud contacts contain invalid BDAY values that break pythonvCard4 parsing. Catch per-contact parsing errors and retry after removing all BDAY lines so a single bad contact doesn't prevent loading the whole addressbook.
Add server-side CardDAV filtering (card:text-match on vCard FN) with optional RU->LAT transliteration, plus best-effort limit to avoid timeouts when addressbooks contain many contacts. Keep per-contact vCard parsing resilient to invalid BDAY so one bad contact doesn't break the whole addressbook.
@Khazhinov Khazhinov changed the title Fix CalDAV/CardDAV home-set discovery for UUID principals Fix CalDAV/CardDAV home-set discovery + scalable contacts lookup for UUID principals Mar 20, 2026
The current WebDAV client builds paths from `NEXTCLOUD_USERNAME`.
On this Nextcloud instance the files WebDAV home lives under UUID
principals, so `PROPFIND`/`SEARCH` hit `/files/<username>/` and return 404.

Fix:
- Discover `current-user-principal` from `PROPFIND /remote.php/dav/`.
- Use the discovered principal id to build WebDAV base paths: `/remote.php/dav/files/<uuid>/`.
- Update WebDAV SEARCH scope and tag/report prefix stripping to use the same UUID principal.

Notes:
- Also fixes a small syntax error in the contacts tool signature that could
  prevent the MCP server from starting after rebuilds.

Made-with: Cursor
@Khazhinov Khazhinov changed the title Fix CalDAV/CardDAV home-set discovery + scalable contacts lookup for UUID principals Fix CalDAV/CardDAV home-set discovery + WebDAV file browsing/search + scalable contacts lookup for UUID principals Mar 20, 2026
@Khazhinov Khazhinov changed the title Fix CalDAV/CardDAV home-set discovery + WebDAV file browsing/search + scalable contacts lookup for UUID principals Fix Nextcloud UUID principals for DAV + robust OCS sharing (paths + internal UUID users) Mar 20, 2026
@cbcoutinho

Copy link
Copy Markdown
Owner

Hi @Khazhinov thanks for your contribution! I've recently replaced my fork of the caldav library with the original library now that it supports async in v3.x - can you please reexamine if this PR is required, and if so, fix the merge conflicts? It would be great if you could add some unit/integration tests that reproduce the error and show that your addition fixes the issue.

Thanks 🙏

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


vkhazhinov seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants