Fix CardDAV URL construction for contacts
All checks were successful
Build And Test / publish (push) Successful in 48s

- Add _build_url helper to properly construct URLs from paths
- Fix test.sh to pass addressbook_id when listing contacts
- Prevents path duplication when addressbook_id is a full path

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-30 17:39:53 -08:00
parent c77dbda13c
commit 710666ee0a
2 changed files with 23 additions and 11 deletions

View File

@@ -1,4 +1,5 @@
from typing import Optional from typing import Optional
from urllib.parse import urlparse
import uuid import uuid
import httpx import httpx
@@ -51,6 +52,15 @@ class ContactsService:
) )
return self._client return self._client
def _build_url(self, path: str) -> str:
"""Build full URL from a path, handling both relative and absolute paths."""
if path.startswith("http://") or path.startswith("https://"):
return path
# Extract base URL (scheme + host) from carddav_url
parsed = urlparse(self.settings.carddav_url)
base = f"{parsed.scheme}://{parsed.netloc}"
return f"{base}{path}"
def list_addressbooks(self) -> list[AddressBook]: def list_addressbooks(self) -> list[AddressBook]:
client = self._get_client() client = self._get_client()
@@ -112,8 +122,7 @@ class ContactsService:
client = self._get_client() client = self._get_client()
# Build URL # Build URL
base_url = self.settings.carddav_url.rstrip("/") addressbook_url = self._build_url(addressbook_id)
addressbook_url = f"{base_url}{addressbook_id}" if addressbook_id.startswith("/") else addressbook_id
response = client.request( response = client.request(
"REPORT", "REPORT",
@@ -183,8 +192,7 @@ class ContactsService:
client = self._get_client() client = self._get_client()
# Build URL # Build URL
base_url = self.settings.carddav_url.rstrip("/") contact_url = self._build_url(contact_id)
contact_url = f"{base_url}{contact_id}" if contact_id.startswith("/") else contact_id
response = client.get(contact_url) response = client.get(contact_url)
@@ -275,8 +283,7 @@ class ContactsService:
adr.type_param = addr_data.get("type", "home").upper() adr.type_param = addr_data.get("type", "home").upper()
# Build URL and save # Build URL and save
base_url = self.settings.carddav_url.rstrip("/") addressbook_url = self._build_url(addressbook_id)
addressbook_url = f"{base_url}{addressbook_id}" if addressbook_id.startswith("/") else addressbook_id
contact_url = f"{addressbook_url.rstrip('/')}/{uid}.vcf" contact_url = f"{addressbook_url.rstrip('/')}/{uid}.vcf"
response = client.put( response = client.put(
@@ -343,8 +350,7 @@ class ContactsService:
client = self._get_client() client = self._get_client()
# Build URL # Build URL
base_url = self.settings.carddav_url.rstrip("/") contact_url = self._build_url(contact_id)
contact_url = f"{base_url}{contact_id}" if contact_id.startswith("/") else contact_id
response = client.delete(contact_url) response = client.delete(contact_url)

10
test.sh
View File

@@ -74,10 +74,16 @@ echo -e "\n[6/7] Listing address books..."
ADDRESSBOOKS=$(mcp_request 5 "tools/call" '{"name":"list_addressbooks","arguments":{}}') ADDRESSBOOKS=$(mcp_request 5 "tools/call" '{"name":"list_addressbooks","arguments":{}}')
echo "$ADDRESSBOOKS" echo "$ADDRESSBOOKS"
# List contacts # List contacts (using first addressbook from previous response)
echo -e "\n[7/7] Listing contacts..." echo -e "\n[7/7] Listing contacts..."
CONTACTS=$(mcp_request 6 "tools/call" '{"name":"list_contacts","arguments":{"limit":10}}') # Extract first addressbook ID from previous response
ADDRESSBOOK_ID=$(echo "$ADDRESSBOOKS" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
if [ -n "$ADDRESSBOOK_ID" ]; then
CONTACTS=$(mcp_request 6 "tools/call" "{\"name\":\"list_contacts\",\"arguments\":{\"addressbook_id\":\"$ADDRESSBOOK_ID\",\"limit\":10}}")
echo "$CONTACTS" echo "$CONTACTS"
else
echo "No addressbook found to list contacts from"
fi
echo -e "\n================================" echo -e "\n================================"
echo "All tests completed!" echo "All tests completed!"