Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ gradle-app.setting
# gradle/wrapper/gradle-wrapper.properties

*.iml

# Spring AI weather demo build artifacts
**/model-context-protocol/**/target/

# Claude Code workspace files
.claude/
131 changes: 96 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,125 @@ iCal4j Command is a collection of operations for common iCalendar and vCard
use cases. This includes direct manipulation of data objects, integration with
persistence stores, and systems interoperability.

## Calendar Commands
### Example Use Cases

| Use Case | Description |
|--------------|-------------------------------------------------|
| Workspaces | Create workspaces for distinct knowledge graphs |
| Collections | Group related activities, notes and contacts |
| Events | Schedule and manage events and tasks |
| Actions | Track actions and to-dos |
| Issues | Manage issues and bug reports |
| Notes | Maintain notes and annotations |
| Observances | Reminders for important dates |
| Reports | Report on past activities and events |
| Availability | Share free/busy information |
| Entities | Maintain contact and organization information |

## Command Line Interface (CLI)

The CLI provides access to iCal4j Command operations via a terminal
interface. It supports a variety of commands for manipulating iCalendar and
vCard data, as well as managing workspaces and collections.

### Calendar Commands

The following commands directly manipulate iCalendar objects:

* Validator - check validity of iCalendar data
* Filter - select a subset of iCalendar components using filter expressions
* Free Busy - generate free/busy information for specified iCalendar data
* Replace UIDs - regenerate UIDs for all iCalendar components
* Serialize - output iCalendar data in various formats (e.g. XML, JSON)
* Deserialize - read iCalendar data from various formats (e.g. XML, JSON)

## vCard Commands
### vCard Commands

* ...


## Template Commands
### Strategy Commands

* Event - generate/modify iCalendar data using shorthand template input
Strategy commands use the `generate` verb (command group `generate`, alias `new`):

## Store Commands
* Generate Event - generate/overlay iCalendar data using strategy patterns

* Create Collection - create a new collection for a calendar store
* ...
### Store Commands

* Add Workspace - add a new workspace for storing iCalendar/vCard collections
* List Workspaces - list available workspaces
* Remove Workspace - remove an existing workspace
* Get Workspace - retrieve details of a specific workspace

## Collection Commands
### Collection Commands

* ...

## Channel Commands
### Channel Commands

* ...


## Model Context Protocol (MCP)

iCal4j Command supports the Model Context Protocol (MCP) for managing
iCalendar and vCard data in a structured manner. MCP defines a set of
operations for creating, retrieving, updating, and deleting data objects within
a defined context.

### MCP Operations

MCP operations follow the canonical vocabulary (see `docs/command-protocols.md`): a **verb**
applied to an **entity type** within a **locus**. The supported verbs are:

* `add` / `remove` — add or remove an item within a locus (e.g. add a workspace, remove a
collection)
* `list` — enumerate items of a type within a locus (e.g. list events in a collection)
* `get` — retrieve a single item or its metadata
* `update` — modify an existing item
* `import` / `export` — move calendar/card serializations into or out of a collection

These apply across the loci `workspace` and `collection`, and the entity types `entity`
(contact), `event`, `action`, `issue`, `note`, `observance`, `report`, `availability` and
`resource`. (`create`/`delete` are standardised on `add`/`remove`.)

## Agentic User Agent

iCal4j Command includes an Agentic User Agent that provides intelligent
automation capabilities for managing iCalendar and vCard data. The User Agent
can perform tasks such as scheduling events, sending notifications, and
managing contacts based on predefined rules and user preferences.

### Prompts

Some example prompts for the User Agent:

* "Create a new event for a team meeting next Monday at 10 AM."
* "Add a contact for John Doe with email"
* "Generate a free/busy report for the next two weeks."
* "List all upcoming events in my calendar."
* "Update the location of the event 'Project Kickoff' to 'Conference Room B'."
* "Delete the contact for Jane Smith."
* "Send a notification to all attendees of the event 'Weekly Sync'."
* "Create a new workspace for project management."
* "List all workspaces available in my account."
* "Add a new collection for storing project-related notes."

### Interactions

The User Agent can interact with users through various channels, including
email, messaging apps, and voice assistants. It can also integrate with other
systems and services to enhance its capabilities.

When prompted the agent may ask clarifying questions to ensure it understands the user's intent before taking action.

For example:

**User:** "Create birthday reminders for my family members."
**Agent:** "Could you please provide the names and birth dates of your family members?"



## System Properties

The following table describes System properties applicable to the iCal4j User Agent.
Expand All @@ -51,29 +138,3 @@ The following table describes System properties applicable to the iCal4j User Ag
| org.ical4j.command.organizer | The default URI used as the value for the iCalendar `ORGANIZER` property | A URI (e.g. `mailto:johnd@example.com`) | - |
| org.ical4j.command.uidgenerator | The `UidGenerator` implementation used to create `UID` properties | A fully qualified class name | `net.fortuna.ical4j.util.RandomUidGenerator` |


## Command Line Usage

### Publish a collection of events

ical4j publish -F ./Australian32Holidays.ics

Result:

```
BEGIN:VCALENDAR
PRODID:iCal4j User Agent
VERSION:2.0
METHOD:PUBLISH
BEGIN:VEVENT
UID:D416469E-C414-11D6-BA97-003065F198AC
DTSTAMP:20020906T094459Z
SUMMARY:Australia Day
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=1
DTSTART;VALUE=DATE:20020126
DTEND;VALUE=DATE:20020127
ORGANIZER:johnd@example.com
SEQUENCE:0
END:VEVENT
...
```
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ configure(subprojects) {
// spock
testImplementation platform(libs.spock.bom), libs.spock.core

testRuntimeOnly libs.junit.platform
}

group = 'org.ical4j'
Expand Down
118 changes: 118 additions & 0 deletions docs/command-protocols.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# iCal4j Command Protocols

This document describes the various command protocols and tools provided by the iCal4j Command library for managing iCalendar and vCard data.

## Canonical Vocabulary

All command surfaces (CLI, MCP, agent) name operations from a single controlled vocabulary
defined in the `ical4j-command-core` module. Each operation is identified by a **verb**, an
**entity type**, and a **locus** (container). Surfaces share these names but dispatch
independently.

- **Verbs** (`org.ical4j.command.core.Verb`): `list` (many), `get` (one), `generate`
(synthesise from a strategy/template), `add` (place into a locus), `update`, `remove`
(take out of a locus), `copy`, `move`, `filter`, `validate`, `import`, `export`, `send`,
`receive`. There is no `create`/`delete` — these are standardised on `add`/`remove`.
- **Entity types** (`EntityType`): `event`, `action`, `issue`, `note`, `observance`,
`availability`, `report`, `entity` (contact), `resource`. All live directly within a
collection.
- **Loci** (`Locus`): `workspace` ⊃ `collection` (two levels; entities live directly in a
collection).
- **Serialization families** (`SerializationFamily`): `calendar` (iCalendar), `card`
(vCard). These are NOT loci or entity types; data crosses a collection boundary via
`import`/`export`.
- **iTIP methods** (`SendMethod`): `publish`, `request`, `reply` are specialised forms of
`send`, not independent verbs.

## Calendar Commands

### Validator
- Purpose: Validates iCalendar data for conformance to specifications
- Location: `org.ical4j.command.calendar.Validator`
- Usage: Validates iCalendar objects for RFC compliance and structural integrity

### Filter
- Purpose: Filters iCalendar components based on expressions
- Location: `org.ical4j.command.calendar.FilterCalendar`
- Usage: Selects subsets of iCalendar components using filter criteria

### Free/Busy
- Purpose: Generates availability information
- Location: `org.ical4j.command.calendar.FreeBusy`
- Usage: Creates free/busy time reports from calendar data

### Replace UIDs
- Purpose: Regenerates unique identifiers
- Location: `org.ical4j.command.calendar.ReplaceUids`
- Usage: Updates UIDs across all calendar components

## Collection Management

### Calendar Collections
- Import Calendar (`import-calendar`): Imports calendar data into a collection
- Export Calendar (`export-calendar`): Exports calendar data from a collection
- Remove Calendar (`remove-calendar`): Removes calendar data from a collection
- List: Enumerates calendar entities in a collection

### Card Collections
- Import Card (`import-card`): Imports vCard data into a collection
- Export Card (`export-card`): Exports vCard data from a collection
- Remove Card (`remove-card`): Removes vCard data from a collection
- List: Enumerates vCard entities in a collection

## Channel Operations

### Calendar Channels
- Send Calendar: Transmits calendar data to specified endpoints. The iTIP methods
`publish`, `request` and `reply` are specialised forms of `send`.
- Receive Calendar: Accepts incoming calendar data

### vCard Channels
- Send vCard: Transmits vCard data to specified endpoints
- Receive vCard: Accepts incoming vCard data

## Store Operations

### Collection Management
- Add Collection: Adds a collection to a workspace
- Remove Collection: Removes a collection from a workspace
- Get Collection: Retrieves collection metadata
- List Collections: Enumerates available collections
- Update Collection: Modifies collection properties

## Strategy (Generation) Operations

### Event Templates
- Purpose: Generates calendar data using simplified templates (the `generate` verb)
- Location: `org.ical4j.command.strategy.CreateEvent` (command name `generate event`)
- Usage: Synthesises calendar entries from template definitions

## Configuration

### System Properties
The following properties can be configured:

- `org.ical4j.command.prodid`: Customizes the PRODID property
- `org.ical4j.command.organizer`: Sets default organizer URI
- `org.ical4j.command.uidgenerator`: Specifies UID generation implementation

## Common Patterns

### Input/Output Handling
- Input handling through `InputHandler` interface
- Output processing via `DefaultOutputHandlers`
- Support for various data formats and sources

### Command Groups
- Calendar Command Group: Calendar-specific operations
- Card Command Group: vCard-specific operations
- Channel Command Group: Communication operations
- Collection Command Group: Data collection management
- Store Command Group: Storage operations
- Template Command Group: Template-based generation

Each command follows a consistent protocol pattern:
1. Input validation
2. Operation execution
3. Result handling
4. Error management
11 changes: 6 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[versions]
ical4j = "4.2.1"
ical4j-vcard = "2.0.1"
ical4j-extensions = "2.0.1-develop-SNAPSHOT"
ical4j-connector = "2.0.0-beta2-SNAPSHOT"
ical4j = "4.2.3"
ical4j-vcard = "2.1.0"
ical4j-extensions = "2.0.0"
ical4j-connector = "2.0.0-beta1"
ical4j-integration = "0.3.1"
ical4j-serializer = "0.4.0-develop-SNAPSHOT"
ical4j-serializer = "0.4.1"
groovy = "3.0.25"
log4j = "2.25.2"
spock = "2.4-M7-groovy-3.0"
Expand Down Expand Up @@ -42,3 +42,4 @@ spock-bom = { module = "org.spockframework:spock-bom", version.ref = "spock"}
spock-core = { module = "org.spockframework:spock-core", version.ref = "spock"}

junit-jupiter = { group = "org.junit.jupiter", name="junit-jupiter", version.ref = "junitVintage"}
junit-platform = { module = "org.junit.platform:junit-platform-launcher" }
5 changes: 5 additions & 0 deletions ical4j-command-agent/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies {
api project(':ical4j-command-core')

implementation libs.langchain4j, libs.langchain4j.openai
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
package org.ical4j.command.config;
package org.ical4j.command.agent;

import net.fortuna.ical4j.model.Calendar;
import net.fortuna.ical4j.vcard.VCard;
import org.ical4j.command.util.Filesystem;
import org.ical4j.connector.CalendarCollection;
import org.ical4j.connector.CardCollection;
import org.ical4j.connector.ObjectCollection;
import org.ical4j.connector.ObjectStore;
import org.ical4j.connector.local.LocalCalendarStore;
import org.ical4j.connector.local.LocalCardStore;

import java.io.File;

/*
* Copyright (c) 2025, Ben Fortuna
Expand Down Expand Up @@ -43,13 +33,11 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public class StoreConfiguration {
public interface CalendarUserAgent {

Calendar publish(String prompt) throws Exception;

public ObjectStore<? extends CalendarCollection> getCalendarStore() {
return new LocalCalendarStore(new File(Filesystem.getDataDirectory(), "iCal4j/calendars"));
}
Calendar request(String prompt) throws Exception;

public ObjectStore<? extends CardCollection> getCardStore() {
return new LocalCardStore(new File(Filesystem.getDataDirectory(), "iCal4j/vcards"));
}
Calendar reply(String prompt) throws Exception;
}
Loading
Loading