fix: address PR #574 third review round
- Guard board.labels against None in deck_get_labels and resource - Add TODO comments for calendar_display_name in single-calendar paths - Document _raw_contact_to_model scope limitation (maps only what the client returns; expanding requires changes to vCard parsing) - Log debug warning when event has no start_datetime - Verified Table model is safe with extra fields (Pydantic v2 ignores) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -29,10 +29,14 @@ def _event_dict_to_summary(event: dict) -> CalendarEventSummary:
|
||||
else:
|
||||
categories = raw_categories
|
||||
|
||||
start = event.get("start_datetime", "")
|
||||
if not start:
|
||||
logger.debug("Event %s has no start_datetime", event.get("uid", "unknown"))
|
||||
|
||||
return CalendarEventSummary(
|
||||
uid=event.get("uid", ""),
|
||||
summary=event.get("title", ""),
|
||||
start=event.get("start_datetime", ""),
|
||||
start=start,
|
||||
end=event.get("end_datetime"),
|
||||
all_day=event.get("all_day", False),
|
||||
location=event.get("location") or None,
|
||||
@@ -240,7 +244,10 @@ def configure_calendar_tools(mcp: FastMCP):
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
# Enrich events with calendar context for per-event mapping
|
||||
# Enrich events with calendar context for per-event mapping.
|
||||
# Note: calendar_display_name is not available here without an
|
||||
# extra list_calendars() call; the response-level calendar_name
|
||||
# already identifies the calendar for single-calendar queries.
|
||||
for event in events:
|
||||
event["calendar_name"] = calendar_name
|
||||
|
||||
@@ -463,6 +470,7 @@ def configure_calendar_tools(mcp: FastMCP):
|
||||
end_datetime=end_datetime,
|
||||
limit=limit,
|
||||
)
|
||||
# calendar_display_name not available without extra API call
|
||||
for event in events:
|
||||
event["calendar_name"] = calendar_name
|
||||
else:
|
||||
|
||||
@@ -19,7 +19,13 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _raw_contact_to_model(raw: dict) -> Contact:
|
||||
"""Convert a raw contact dict from the contacts client to a Contact model."""
|
||||
"""Convert a raw contact dict from the contacts client to a Contact model.
|
||||
|
||||
Only maps fields the client's list_contacts() currently returns:
|
||||
fullname, nickname, birthday, and email. Additional Contact model fields
|
||||
(phones, addresses, organization, etc.) require expanding the client's
|
||||
vCard parsing in ContactsClient.list_contacts().
|
||||
"""
|
||||
contact_info = raw.get("contact", {})
|
||||
|
||||
# Convert email field (str, list, or None) to list[ContactField]
|
||||
|
||||
@@ -107,7 +107,7 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
)
|
||||
client = await get_client(ctx)
|
||||
board = await client.deck.get_board(board_id)
|
||||
return [label.model_dump() for label in board.labels]
|
||||
return [label.model_dump() for label in (board.labels or [])]
|
||||
|
||||
@mcp.resource("nc://Deck/boards/{board_id}/labels/{label_id}")
|
||||
async def deck_label_resource(board_id: int, label_id: int):
|
||||
@@ -209,7 +209,8 @@ def configure_deck_tools(mcp: FastMCP):
|
||||
"""Get all labels in a Nextcloud Deck board"""
|
||||
client = await get_client(ctx)
|
||||
board = await client.deck.get_board(board_id)
|
||||
return ListLabelsResponse(labels=board.labels, total=len(board.labels))
|
||||
labels = board.labels or []
|
||||
return ListLabelsResponse(labels=labels, total=len(labels))
|
||||
|
||||
@mcp.tool(
|
||||
title="Get Deck Label",
|
||||
|
||||
Reference in New Issue
Block a user