Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/apple_eventkit_mcp/calendar_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def calendar_list_events(
start_date: str,
end_date: str,
calendar_name: Optional[str] = None,
exclude_calendars: Optional[list[str]] = None,
limit: int = 50
) -> dict:
"""List calendar events within a date range.
Expand All @@ -83,6 +84,8 @@ def calendar_list_events(
start_date: Start date in ISO 8601 format (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS)
end_date: End date in ISO 8601 format
calendar_name: Filter to specific calendar (optional)
exclude_calendars: Calendar titles to skip (optional, case-insensitive
exact match). Ignored when ``calendar_name`` is set.
limit: Maximum events to return (default: 50)
"""
try:
Expand All @@ -93,6 +96,7 @@ def calendar_list_events(
start=start,
end=end,
calendar_name=calendar_name,
exclude_calendars=exclude_calendars,
limit=limit
)

Expand Down Expand Up @@ -160,6 +164,7 @@ def calendar_search_events(
start_date: Optional[str] = None,
end_date: Optional[str] = None,
tags: Optional[list[str]] = None,
exclude_calendars: Optional[list[str]] = None,
limit: int = 50
) -> dict:
"""Search events by text in title, location, or notes.
Expand All @@ -169,6 +174,8 @@ def calendar_search_events(
start_date: Search range start (optional, defaults to 30 days ago)
end_date: Search range end (optional, defaults to 90 days from now)
tags: Filter by tags (optional)
exclude_calendars: Calendar titles to skip (optional, case-insensitive
exact match).
limit: Maximum events to return (default: 50)
"""
try:
Expand All @@ -184,6 +191,7 @@ def calendar_search_events(
start=start,
end=end,
tags=tags,
exclude_calendars=exclude_calendars,
limit=limit
)

Expand Down
23 changes: 20 additions & 3 deletions src/apple_eventkit_mcp/eventkit_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,15 @@ def get_events(
start: datetime,
end: datetime,
calendar_name: Optional[str] = None,
exclude_calendars: Optional[list[str]] = None,
limit: int = 50
) -> list[dict]:
"""Fetch events in date range."""
"""Fetch events in date range.

If ``exclude_calendars`` is provided, calendars whose title matches
any entry (case-insensitive exact match) are dropped before fetching.
Ignored when ``calendar_name`` is set (single-include wins).
"""
require_calendar_permission()
with self._lock:
start_ns = self._datetime_to_nsdate(start)
Expand All @@ -81,6 +87,9 @@ def get_events(
self._store.calendarsForEntityType_(EventKit.EKEntityTypeEvent)
or []
)
if exclude_calendars:
excluded_lower = {n.lower() for n in exclude_calendars}
calendars = [c for c in calendars if c.title().lower() not in excluded_lower]

if not calendars:
return []
Expand Down Expand Up @@ -246,9 +255,15 @@ def search_events(
start: Optional[datetime] = None,
end: Optional[datetime] = None,
tags: Optional[list[str]] = None,
exclude_calendars: Optional[list[str]] = None,
limit: int = 50
) -> list[dict]:
"""Search events by text in title, location, or notes."""
"""Search events by text in title, location, or notes.

``exclude_calendars`` follows the same semantics as in
:meth:`get_events`: calendars whose title matches any entry
(case-insensitive exact match) are dropped before fetching.
"""
require_calendar_permission()

# Default to searching past 30 days to future 90 days
Expand All @@ -257,7 +272,9 @@ def search_events(
if end is None:
end = datetime.now() + timedelta(days=90)

events = self.get_events(start, end, limit=1000) # Get more for filtering
events = self.get_events(
start, end, exclude_calendars=exclude_calendars, limit=1000
) # Get more for filtering

query_lower = query.lower()
results = []
Expand Down