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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ wheels/
# Virtual environments
.venv
.vscode
.DS_Store
.DS_Store
uv.lock
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MIT License

Copyright (c) 2025 Omar D.
Copyright (c) 2025 Malte Sussdorff / cognovis GmbH

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
57 changes: 52 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,49 @@ Claude: "✨ πŸ“… Created: Lunch with Sarah Tomorrow, 12:00 PM"

## ✨ Features

### πŸ“ Calendar Groups ✨ NEW!

Organize calendars from different sources (iCloud, Google, Office365) into logical collections for streamlined management!

```text
"Create a Work group with my Office365 and Google work calendars"
↓
πŸ“‚ Created: Work Group
πŸ“… Office365 Calendar
πŸ“… Google Work Calendar

"What meetings do I have in my Work calendars this week?"
↓
πŸ“Š Shows events from all calendars in your Work group
```

#### Calendar Groups Features

- **Cross-Account Support**: Group calendars from different sources (iCloud, Google, Exchange, etc.)
- **Persistent Storage**: Groups persist between app launches with local JSON storage
- **Natural Language Queries**: "Show me events from Family calendars next month"
- **Complete CRUD Operations**: Create, update, delete, and list calendar groups
- **Flexible Management**: Add/remove individual calendars from existing groups

#### Calendar Groups Examples

```text
πŸ“‚ Group Management:
"Create group 'Fitness' with my Gym and Sports calendars"
"Add my Project calendar to the Work group"
"Remove Personal calendar from the Work group"

πŸ“… Group-Based Scheduling:
"What's my schedule in Family calendars this weekend?"
"Show me all Work events for next week"
"List events from my Fitness group today"

πŸ”§ Group Operations:
"List all my calendar groups"
"Show me what calendars are in my Work group"
"Delete the Old Projects group"
```

### πŸ“… Event Creation

Transform natural language into calendar events instantly!
Expand Down Expand Up @@ -95,9 +138,10 @@ After: ✨ Meeting rescheduled to 3:00 PM

### πŸ“Š Calendar Management

- View all available calendars
- Smart calendar suggestions
- Seamless Google Calendar integration when configured with iCloud
- **Enhanced Calendar Listing**: View calendars organized by account with highlighted default calendar
- **Calendar Groups**: Organize calendars into logical collections across all sources
- **Smart Calendar Suggestions**: Intelligent recommendations based on context
- **Seamless Multi-Account Support**: Works with iCloud, Google, Office365, Exchange, and more

> πŸ’‘ **Pro Tip**: Since you can create events in custom calendars, if you have your Google Calendar synced with your iCloud Calendar, you can use this MCP server to create events in your Google Calendar too! Just specify the Google calendar when creating/updating events.

Expand Down Expand Up @@ -150,12 +194,15 @@ Whilst this MCP server can be used with any MCP compatible client, the instructi

> ⚠️ **Critical**: Claude must be launched from the terminal to properly request calendar permissions. Launching directly from Finder will not trigger the permissions prompt.

Run the following command in your terminal.

**Option A: Terminal Launch (Quick)**
```bash
/Applications/Claude.app/Contents/MacOS/Claude
```

**Option B: Alfred Workflow (Recommended)**

For a more convenient launch experience that supports multiple Claude instances, see our [Alfred Setup Guide](docs/alfred-setup.md).

> ⚠️ **Warning**: Alternatively, you can [manually grant calendar access](docs/install.md#method-2-manually-grant-calendar-access), but this involves modifying system files and should only be done if you understand the risks involved.

4. **Start Using!**
Expand Down
90 changes: 90 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Release Notes

## Version 0.2.0 - Calendar Groups & Enhanced Management

*Released: January 22, 2025*

### πŸŽ‰ Major New Features

#### πŸ“ Calendar Groups
Transform how you organize and manage calendars across multiple accounts! Calendar Groups allow you to create logical collections of calendars from different sources (iCloud, Google, Office365, Exchange, etc.) for streamlined scheduling and event management.

**Key Features:**
- **Cross-Account Support**: Group calendars from any source together
- **Persistent Storage**: Groups persist between app launches with local JSON storage
- **Natural Language Integration**: Use groups in everyday calendar queries
- **Complete CRUD Operations**: Full create, read, update, delete support for groups

**Example Usage:**
```
"Create a Work group with my Office365 and Google work calendars"
"What meetings do I have in my Work calendars this week?"
"Add my Project calendar to the Work group"
"Show me all Family events for next month"
```

#### πŸ“Š Enhanced Calendar Management
- **Account-Organized Listing**: View calendars grouped by account (iCloud, Google, etc.)
- **Default Calendar Highlighting**: Easily identify your default calendar
- **Multi-Source Integration**: Improved support for calendars from different providers

### πŸ› οΈ New MCP Tools

The following new tools have been added to support calendar groups:

- `create_calendar_group(name, calendar_names, description)` - Create new custom groups
- `update_calendar_group(group_name, calendar_names, description)` - Modify group membership
- `delete_calendar_group(group_name)` - Remove custom groups
- `list_calendar_groups()` - List all custom groups
- `list_calendars_in_group(group_name)` - Get calendars within a specific group
- `list_events_by_group(start_date, end_date, group_name)` - Get events from all calendars in a group
- `add_calendar_to_group(group_name, calendar_name)` - Add individual calendars to groups
- `remove_calendar_from_group(group_name, calendar_name)` - Remove calendars from groups

### πŸ”§ Technical Improvements

- **Modular Architecture**: Calendar groups implemented with clean, testable package structure
- **Robust Storage Layer**: Atomic file operations with corruption recovery
- **Enhanced Error Handling**: Better validation and graceful handling of missing calendars
- **Performance Optimizations**: Efficient group-based event filtering
- **NSTaggedDate Compatibility**: Resolved compatibility issues for improved reliability

### πŸ—οΈ Implementation Highlights

Calendar Groups are built on a solid foundation:

- **Storage Layer**: JSON-based persistence with atomic writes and backup support
- **Data Models**: Pydantic-based validation with schema versioning
- **Group Manager**: Business logic for CRUD operations with validation
- **Calendar Integration**: Bridge between groups and existing calendar system
- **MCP Tools**: Natural language interface for all group operations

### πŸ“¦ Dependencies

No new external dependencies added - calendar groups use only existing libraries (Pydantic, standard library JSON operations).

### πŸ”„ Backward Compatibility

All existing functionality remains unchanged. Calendar groups are an additive feature that doesn't affect existing workflows.

### πŸ§ͺ Testing

Comprehensive test coverage added:
- Unit tests for each component (storage, models, manager, integration, tools)
- Integration tests with real calendar data
- Edge case handling (missing calendars, corrupted files, validation errors)
- MCP protocol testing with FastMCP framework

---

## Version 0.1.0 - Initial Release

*Previous release*

### Features
- Natural language calendar event creation
- Smart schedule management and availability checking
- Intelligent event updates and modifications
- Multi-calendar support (iCloud, Google, Office365)
- macOS Calendar app integration
- MCP protocol compatibility
111 changes: 111 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Calendar Groups Architecture

## Overview
Calendar Groups provide cross-account calendar organization with persistent local storage. The implementation uses a clean separation of concerns across 5 main components.

## Code Structure

### `group_models.py` - Data Models
**Purpose:** Pydantic models for data validation and serialization

**Key Classes:**
- `CalendarGroup` - Individual group with name, calendar IDs, description, timestamps
- `GroupsSchema` - Complete storage file structure with versioning

**Responsibilities:**
- Field validation and constraints
- JSON serialization/deserialization
- Schema versioning for migrations

---

### `storage.py` - Persistence Layer
**Purpose:** Atomic JSON file operations with error recovery

**Key Features:**
- Atomic writes (temp file + rename pattern)
- Automatic backups before modifications
- Schema migration support
- Corruption recovery from backups

**Storage Location:** `~/Library/Application Support/mcp-ical/calendar_groups.json`

---

### `group_manager.py` - Business Logic
**Purpose:** Core CRUD operations and group management

**Key Operations:**
- Group creation, updating, deletion
- Calendar addition/removal from groups
- Group validation and statistics
- Schema caching for performance

**Notable:** Handles all business rules and data consistency

---

### `calendar_integration.py` - Calendar Bridge
**Purpose:** Connect groups with existing calendar system

**Key Functions:**
- Event retrieval across multiple calendars in a group
- Calendar name ↔ ID resolution and validation
- Group validation against actual calendar availability
- Cleanup utilities for invalid calendar references

**Integration:** Works with existing `CalendarManager` from `ical.py`

---

### `group_tools.py` - MCP API Layer
**Purpose:** External interface via MCP protocol

**Provides 12 MCP Tools:**
- Group CRUD operations
- Calendar membership management
- Group-based event queries
- User-friendly calendar name interfaces

**Notable:** Translates between user-friendly names and internal calendar IDs

## Data Flow

```
User Query β†’ MCP Tools β†’ Calendar Integration β†’ Group Manager β†’ Storage
↓
Calendar System (EventKit)
```

## Key Design Decisions

### Why This Architecture?
- **Separation of Concerns:** Each component has a single responsibility
- **Testability:** Each layer can be tested independently
- **Maintainability:** Changes to one layer don't affect others
- **Performance:** Caching at manager level, atomic operations at storage level

### Storage Strategy
- **Local JSON:** No cloud dependencies, fast access
- **Calendar IDs:** Persistent across name changes
- **Atomic Operations:** Prevents corruption during writes
- **Schema Versioning:** Enables future migrations

### Error Handling
- **Graceful Degradation:** Invalid calendars are flagged but don't break groups
- **Recovery Mechanisms:** Automatic backup restoration
- **User Feedback:** Clear error messages through MCP tools

## Extension Points

### Adding New Features
- **New MCP Tools:** Add to `group_tools.py`
- **New Group Properties:** Extend `CalendarGroup` model
- **New Storage Formats:** Implement in `storage.py` with migration
- **New Calendar Sources:** Extend `calendar_integration.py`

### Performance Considerations
- Schema caching in `group_manager.py`
- Lazy loading of calendar validation
- Efficient JSON serialization
- Minimal EventKit calls through existing `CalendarManager`
Loading