@laylzj777/my-apple-apple-eventkit 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/CHANGELOG.md +575 -0
  2. package/LICENSE +21 -0
  3. package/README.md +304 -0
  4. package/README.zh-CN.md +270 -0
  5. package/bin/event +0 -0
  6. package/bin/event-disclaim +0 -0
  7. package/dist/bin/apple-calendar.d.ts +6 -0
  8. package/dist/bin/apple-calendar.js +8 -0
  9. package/dist/bin/apple-calendar.js.map +1 -0
  10. package/dist/bin/apple-reminders.d.ts +7 -0
  11. package/dist/bin/apple-reminders.js +9 -0
  12. package/dist/bin/apple-reminders.js.map +1 -0
  13. package/dist/bootstrap.d.ts +11 -0
  14. package/dist/bootstrap.js +44 -0
  15. package/dist/bootstrap.js.map +1 -0
  16. package/dist/index.d.ts +10 -0
  17. package/dist/index.js +12 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/server/handlers.d.ts +12 -0
  20. package/dist/server/handlers.js +58 -0
  21. package/dist/server/handlers.js.map +1 -0
  22. package/dist/server/mode.d.ts +19 -0
  23. package/dist/server/mode.js +47 -0
  24. package/dist/server/mode.js.map +1 -0
  25. package/dist/server/promptAbstractions.d.ts +61 -0
  26. package/dist/server/promptAbstractions.js +140 -0
  27. package/dist/server/promptAbstractions.js.map +1 -0
  28. package/dist/server/prompts.d.ts +13 -0
  29. package/dist/server/prompts.js +461 -0
  30. package/dist/server/prompts.js.map +1 -0
  31. package/dist/server/server.d.ts +61 -0
  32. package/dist/server/server.js +112 -0
  33. package/dist/server/server.js.map +1 -0
  34. package/dist/tools/definitions.d.ts +9 -0
  35. package/dist/tools/definitions.js +272 -0
  36. package/dist/tools/definitions.js.map +1 -0
  37. package/dist/tools/handlers/calendarHandlers.d.ts +11 -0
  38. package/dist/tools/handlers/calendarHandlers.js +151 -0
  39. package/dist/tools/handlers/calendarHandlers.js.map +1 -0
  40. package/dist/tools/handlers/formatters.d.ts +24 -0
  41. package/dist/tools/handlers/formatters.js +105 -0
  42. package/dist/tools/handlers/formatters.js.map +1 -0
  43. package/dist/tools/handlers/index.d.ts +8 -0
  44. package/dist/tools/handlers/index.js +9 -0
  45. package/dist/tools/handlers/index.js.map +1 -0
  46. package/dist/tools/handlers/listHandlers.d.ts +10 -0
  47. package/dist/tools/handlers/listHandlers.js +47 -0
  48. package/dist/tools/handlers/listHandlers.js.map +1 -0
  49. package/dist/tools/handlers/reminderHandlers.d.ts +10 -0
  50. package/dist/tools/handlers/reminderHandlers.js +219 -0
  51. package/dist/tools/handlers/reminderHandlers.js.map +1 -0
  52. package/dist/tools/handlers/shared.d.ts +28 -0
  53. package/dist/tools/handlers/shared.js +57 -0
  54. package/dist/tools/handlers/shared.js.map +1 -0
  55. package/dist/tools/handlers/subtaskHandlers.d.ts +12 -0
  56. package/dist/tools/handlers/subtaskHandlers.js +113 -0
  57. package/dist/tools/handlers/subtaskHandlers.js.map +1 -0
  58. package/dist/tools/index.d.ts +10 -0
  59. package/dist/tools/index.js +74 -0
  60. package/dist/tools/index.js.map +1 -0
  61. package/dist/types/index.d.ts +263 -0
  62. package/dist/types/index.js +42 -0
  63. package/dist/types/index.js.map +1 -0
  64. package/dist/types/prompts.d.ts +88 -0
  65. package/dist/types/prompts.js +6 -0
  66. package/dist/types/prompts.js.map +1 -0
  67. package/dist/types/repository.d.ts +197 -0
  68. package/dist/types/repository.js +14 -0
  69. package/dist/types/repository.js.map +1 -0
  70. package/dist/utils/binaryValidator.d.ts +52 -0
  71. package/dist/utils/binaryValidator.js +185 -0
  72. package/dist/utils/binaryValidator.js.map +1 -0
  73. package/dist/utils/calendarRepository.d.ts +49 -0
  74. package/dist/utils/calendarRepository.js +226 -0
  75. package/dist/utils/calendarRepository.js.map +1 -0
  76. package/dist/utils/constants.d.ts +79 -0
  77. package/dist/utils/constants.js +80 -0
  78. package/dist/utils/constants.js.map +1 -0
  79. package/dist/utils/dateFiltering.d.ts +41 -0
  80. package/dist/utils/dateFiltering.js +129 -0
  81. package/dist/utils/dateFiltering.js.map +1 -0
  82. package/dist/utils/dateUtils.d.ts +27 -0
  83. package/dist/utils/dateUtils.js +71 -0
  84. package/dist/utils/dateUtils.js.map +1 -0
  85. package/dist/utils/errorHandling.d.ts +27 -0
  86. package/dist/utils/errorHandling.js +88 -0
  87. package/dist/utils/errorHandling.js.map +1 -0
  88. package/dist/utils/eventCli.d.ts +40 -0
  89. package/dist/utils/eventCli.js +294 -0
  90. package/dist/utils/eventCli.js.map +1 -0
  91. package/dist/utils/helpers.d.ts +35 -0
  92. package/dist/utils/helpers.js +61 -0
  93. package/dist/utils/helpers.js.map +1 -0
  94. package/dist/utils/looseDateParser.d.ts +19 -0
  95. package/dist/utils/looseDateParser.js +149 -0
  96. package/dist/utils/looseDateParser.js.map +1 -0
  97. package/dist/utils/projectUtils.d.ts +13 -0
  98. package/dist/utils/projectUtils.js +92 -0
  99. package/dist/utils/projectUtils.js.map +1 -0
  100. package/dist/utils/reminderDateParser.d.ts +8 -0
  101. package/dist/utils/reminderDateParser.js +89 -0
  102. package/dist/utils/reminderDateParser.js.map +1 -0
  103. package/dist/utils/reminderRepository.d.ts +33 -0
  104. package/dist/utils/reminderRepository.js +262 -0
  105. package/dist/utils/reminderRepository.js.map +1 -0
  106. package/dist/utils/subtaskUtils.d.ts +103 -0
  107. package/dist/utils/subtaskUtils.js +253 -0
  108. package/dist/utils/subtaskUtils.js.map +1 -0
  109. package/dist/utils/tagUtils.d.ts +58 -0
  110. package/dist/utils/tagUtils.js +177 -0
  111. package/dist/utils/tagUtils.js.map +1 -0
  112. package/dist/utils/timeHelpers.d.ts +40 -0
  113. package/dist/utils/timeHelpers.js +136 -0
  114. package/dist/utils/timeHelpers.js.map +1 -0
  115. package/dist/validation/schemas.d.ts +385 -0
  116. package/dist/validation/schemas.js +579 -0
  117. package/dist/validation/schemas.js.map +1 -0
  118. package/package.json +96 -0
  119. package/scripts/build-event.mjs +513 -0
  120. package/scripts/disclaim.c +69 -0
  121. package/scripts/event-Info.plist +29 -0
  122. package/scripts/event.entitlements +10 -0
  123. package/scripts/postinstall.mjs +91 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * tools/definitions.ts
3
+ * MCP tool definitions for the Apple Reminders / Calendar server.
4
+ *
5
+ * The schema is the cross-action property union for each tool; the per-action
6
+ * validator (src/validation/schemas.ts) narrows the accepted fields.
7
+ */
8
+ import type { Tool } from '@modelcontextprotocol/sdk/types.js';
9
+ export declare const TOOLS: Tool[];
@@ -0,0 +1,272 @@
1
+ /**
2
+ * tools/definitions.ts
3
+ * MCP tool definitions for the Apple Reminders / Calendar server.
4
+ *
5
+ * The schema is the cross-action property union for each tool; the per-action
6
+ * validator (src/validation/schemas.ts) narrows the accepted fields.
7
+ */
8
+ import { CALENDAR_ACTIONS, DUE_WITHIN_OPTIONS, LIST_ACTIONS, REMINDER_ACTIONS, } from '../types/index.js';
9
+ export const TOOLS = [
10
+ {
11
+ name: 'reminders_tasks',
12
+ description: 'Manages reminder tasks. Supports reading, creating, updating, and deleting reminders. Alarms, recurrence rules, and location-based triggers are read-only via this tool; configure them in Reminders.app.',
13
+ inputSchema: {
14
+ type: 'object',
15
+ properties: {
16
+ action: {
17
+ type: 'string',
18
+ enum: REMINDER_ACTIONS,
19
+ description: 'The operation to perform.',
20
+ },
21
+ // ID-based operations
22
+ id: {
23
+ type: 'string',
24
+ description: 'The unique identifier of the reminder (REQUIRED for update, delete; optional for read to get single reminder).',
25
+ },
26
+ // Creation/Update properties
27
+ title: {
28
+ type: 'string',
29
+ description: 'The title of the reminder (REQUIRED for create, optional for update).',
30
+ },
31
+ startDate: {
32
+ type: 'string',
33
+ description: "Start date. UPDATE-ONLY: the underlying CLI cannot set a start date at create time. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time without timezone). Also supports 'YYYY-MM-DD' and ISO 8601 with timezone.",
34
+ },
35
+ dueDate: {
36
+ type: 'string',
37
+ description: "Due date. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time without timezone, e.g., '2025-11-04 18:00:00'). Also supports: 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ss', or ISO 8601 with timezone (e.g., '2025-10-30T04:00:00Z'). When no timezone is specified, the time is interpreted as local time.",
38
+ },
39
+ note: {
40
+ type: 'string',
41
+ description: 'Additional notes for the reminder.',
42
+ },
43
+ url: {
44
+ type: 'string',
45
+ description: 'A URL to associate with the reminder.',
46
+ format: 'uri',
47
+ },
48
+ completed: {
49
+ type: 'boolean',
50
+ description: 'Mark the reminder as completed/uncompleted (update only).',
51
+ },
52
+ priority: {
53
+ type: 'integer',
54
+ enum: [0, 1, 5, 9],
55
+ description: 'Priority level: 0=none, 1=high, 5=medium, 9=low (for create/update).',
56
+ },
57
+ targetList: {
58
+ type: 'string',
59
+ description: 'The name of the list for create or update operations.',
60
+ },
61
+ // Read filters
62
+ filterList: {
63
+ type: 'string',
64
+ description: 'Filter reminders by a specific list name.',
65
+ },
66
+ showCompleted: {
67
+ type: 'boolean',
68
+ description: 'Include completed reminders in the results.',
69
+ default: false,
70
+ },
71
+ search: {
72
+ type: 'string',
73
+ description: 'A search term to filter reminders by title or notes (applied in TS after fetch).',
74
+ },
75
+ dueWithin: {
76
+ type: 'string',
77
+ enum: DUE_WITHIN_OPTIONS,
78
+ description: 'Filter reminders by a due date range (applied in TS after fetch).',
79
+ },
80
+ filterPriority: {
81
+ type: 'string',
82
+ enum: ['high', 'medium', 'low', 'none'],
83
+ description: 'Filter reminders by priority level.',
84
+ },
85
+ filterRecurring: {
86
+ type: 'boolean',
87
+ description: 'Filter to only show recurring reminders when true.',
88
+ },
89
+ filterLocationBased: {
90
+ type: 'boolean',
91
+ description: 'Filter to only show location-based reminders when true.',
92
+ },
93
+ // Tag filtering
94
+ filterTags: {
95
+ type: 'array',
96
+ items: { type: 'string' },
97
+ description: 'Filter reminders by tags (must have ALL specified tags). Example: ["work", "urgent"]',
98
+ },
99
+ // Tag properties for create/update
100
+ tags: {
101
+ type: 'array',
102
+ items: { type: 'string' },
103
+ description: 'Tags to set on the reminder (for create). Replaces any existing tags. Example: ["work", "urgent"]',
104
+ },
105
+ addTags: {
106
+ type: 'array',
107
+ items: { type: 'string' },
108
+ description: 'Tags to add to the reminder (for update). Merges with existing tags. Example: ["followup"]',
109
+ },
110
+ removeTags: {
111
+ type: 'array',
112
+ items: { type: 'string' },
113
+ description: 'Tags to remove from the reminder (for update). Example: ["urgent"]',
114
+ },
115
+ // Subtask properties for create
116
+ subtasks: {
117
+ type: 'array',
118
+ items: { type: 'string' },
119
+ description: 'Initial subtasks to create with the reminder (for create action). Provide an array of subtask titles. Example: ["Buy milk", "Get eggs", "Pick up bread"]',
120
+ },
121
+ },
122
+ required: ['action'],
123
+ },
124
+ },
125
+ {
126
+ name: 'reminders_lists',
127
+ description: 'Manages reminder lists. Supports reading, creating, updating, and deleting reminder lists.',
128
+ inputSchema: {
129
+ type: 'object',
130
+ properties: {
131
+ action: {
132
+ type: 'string',
133
+ enum: LIST_ACTIONS,
134
+ description: 'The operation to perform on a list.',
135
+ },
136
+ name: {
137
+ type: 'string',
138
+ description: 'The current name of the list (for update, delete) or the name of the new list (for create).',
139
+ },
140
+ newName: {
141
+ type: 'string',
142
+ description: 'The new name for the list (for update).',
143
+ },
144
+ },
145
+ required: ['action'],
146
+ },
147
+ },
148
+ {
149
+ name: 'calendar_events',
150
+ description: 'Manages calendar events (time blocks). Supports reading, creating, updating, and deleting events. URL, structured-location, all-day toggle, availability, alarms, and recurrence rules are read-only via this tool; configure them in Calendar.app. All-day events are inferred from the date format ("YYYY-MM-DD" without a time component).',
151
+ inputSchema: {
152
+ type: 'object',
153
+ properties: {
154
+ action: {
155
+ type: 'string',
156
+ enum: CALENDAR_ACTIONS,
157
+ description: 'The operation to perform.',
158
+ },
159
+ // ID-based operations
160
+ id: {
161
+ type: 'string',
162
+ description: 'The unique identifier of the event (REQUIRED for update, delete; optional for read to get single event).',
163
+ },
164
+ // Creation/Update properties
165
+ title: {
166
+ type: 'string',
167
+ description: 'The title of the event (REQUIRED for create, optional for update).',
168
+ },
169
+ startDate: {
170
+ type: 'string',
171
+ description: "Start date and time. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time, e.g., '2025-11-04 09:00:00'). Use 'YYYY-MM-DD' (no time) for all-day events. Also supports 'YYYY-MM-DDTHH:mm:ss' or ISO 8601 with timezone. For action='read': if omitted and endDate is omitted, defaults to today; if only endDate is provided, startDate defaults to endDate - 14 days.",
172
+ },
173
+ endDate: {
174
+ type: 'string',
175
+ description: "End date and time. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time). Use 'YYYY-MM-DD' (no time) for all-day events. Also supports 'YYYY-MM-DDTHH:mm:ss' or ISO 8601 with timezone. For action='read': if omitted and startDate is omitted, defaults to today + 14 days; if only startDate is provided, endDate defaults to startDate + 14 days.",
176
+ },
177
+ note: {
178
+ type: 'string',
179
+ description: 'Additional notes for the event.',
180
+ },
181
+ location: {
182
+ type: 'string',
183
+ description: 'Location text for the event.',
184
+ },
185
+ availability: {
186
+ type: 'string',
187
+ enum: ['not-supported', 'busy', 'free', 'tentative', 'unavailable'],
188
+ description: 'READ-ONLY filter: narrow read results by event availability. Cannot be set via create/update; configure in Calendar.app.',
189
+ },
190
+ span: {
191
+ type: 'string',
192
+ enum: ['this-event', 'future-events'],
193
+ description: 'Scope for changes to recurring events: this-event or future-events.',
194
+ },
195
+ targetCalendar: {
196
+ type: 'string',
197
+ description: 'The name of the calendar for the create action. Events cannot be moved across calendars via update — delete and recreate instead.',
198
+ },
199
+ // Read filters
200
+ filterCalendar: {
201
+ type: 'string',
202
+ description: 'Filter events by a specific calendar name.',
203
+ },
204
+ search: {
205
+ type: 'string',
206
+ description: 'A search term to filter events by title, notes, or location (applied in TS after fetch).',
207
+ },
208
+ },
209
+ required: ['action'],
210
+ },
211
+ },
212
+ {
213
+ name: 'calendar_calendars',
214
+ description: 'Reads calendar collections. Use to inspect available calendars before creating or updating events. Optional date range filters return only calendars with events in that range.',
215
+ inputSchema: {
216
+ type: 'object',
217
+ properties: {
218
+ action: {
219
+ type: 'string',
220
+ enum: ['read'],
221
+ description: 'The operation to perform on calendars.',
222
+ },
223
+ startDate: {
224
+ type: 'string',
225
+ description: "Optional range start for scoped calendar discovery. Format: 'YYYY-MM-DD', 'YYYY-MM-DD HH:mm:ss', or ISO 8601. If only one of startDate/endDate is supplied, the other is filled in as a 14-day window from the bound that was given.",
226
+ },
227
+ endDate: {
228
+ type: 'string',
229
+ description: 'Optional range end for scoped calendar discovery. When used with startDate, only calendars with at least one event in the range are returned, each annotated with the in-range event count (recurring events count as one per instance). endDate must be on or after startDate.',
230
+ },
231
+ },
232
+ required: ['action'],
233
+ },
234
+ },
235
+ {
236
+ name: 'reminders_subtasks',
237
+ description: 'Manages subtasks/checklists within reminders. Subtasks are stored in the notes field and visible in the native Reminders app. Use this to create checklist items for a reminder.',
238
+ inputSchema: {
239
+ type: 'object',
240
+ properties: {
241
+ action: {
242
+ type: 'string',
243
+ enum: ['read', 'create', 'update', 'delete', 'toggle', 'reorder'],
244
+ description: 'The operation to perform: read (list subtasks), create (add new), update (modify), delete (remove), toggle (flip completion), reorder (change order).',
245
+ },
246
+ reminderId: {
247
+ type: 'string',
248
+ description: 'The unique identifier of the parent reminder (REQUIRED for all operations).',
249
+ },
250
+ subtaskId: {
251
+ type: 'string',
252
+ description: 'The unique identifier of the subtask (REQUIRED for update, delete, toggle).',
253
+ },
254
+ title: {
255
+ type: 'string',
256
+ description: 'The title of the subtask (REQUIRED for create, optional for update).',
257
+ },
258
+ completed: {
259
+ type: 'boolean',
260
+ description: 'The completion status of the subtask (for update).',
261
+ },
262
+ order: {
263
+ type: 'array',
264
+ items: { type: 'string' },
265
+ description: 'Array of subtask IDs in desired order (REQUIRED for reorder). Must include all subtask IDs.',
266
+ },
267
+ },
268
+ required: ['action', 'reminderId'],
269
+ },
270
+ },
271
+ ];
272
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * handlers/calendarHandlers.ts
3
+ * Handlers for calendar event operations
4
+ */
5
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
6
+ import type { CalendarsToolArgs, CalendarToolArgs } from '../../types/index.js';
7
+ export declare const handleCreateCalendarEvent: (args: CalendarToolArgs) => Promise<CallToolResult>;
8
+ export declare const handleUpdateCalendarEvent: (args: CalendarToolArgs) => Promise<CallToolResult>;
9
+ export declare const handleDeleteCalendarEvent: (args: CalendarToolArgs) => Promise<CallToolResult>;
10
+ export declare const handleReadCalendarEvents: (args: CalendarToolArgs) => Promise<CallToolResult>;
11
+ export declare const handleReadCalendars: (args?: CalendarsToolArgs) => Promise<CallToolResult>;
@@ -0,0 +1,151 @@
1
+ /**
2
+ * handlers/calendarHandlers.ts
3
+ * Handlers for calendar event operations
4
+ */
5
+ import { calendarRepository } from '../../utils/calendarRepository.js';
6
+ import { handleAsyncOperation } from '../../utils/errorHandling.js';
7
+ import { formatMultilineNotes } from '../../utils/helpers.js';
8
+ import { CreateCalendarEventSchema, DeleteCalendarEventSchema, ReadCalendarEventsSchema, ReadCalendarsSchema, UpdateCalendarEventSchema, } from '../../validation/schemas.js';
9
+ import { formatAlarm, formatRecurrenceRules } from './formatters.js';
10
+ import { extractAndValidateArgs, formatDeleteMessage, formatListMarkdown, formatSuccessMessage, UNTRUSTED_DATA_NOTICE, } from './shared.js';
11
+ /**
12
+ * Formats a calendar event as a markdown list item. Renders alarms /
13
+ * recurrence rules through the same helpers as the reminder formatter so the
14
+ * two outputs stay structurally consistent (instead of degenerating to bare
15
+ * counts like `Alarms: 2`).
16
+ */
17
+ const formatEventMarkdown = (event) => {
18
+ const lines = [];
19
+ lines.push(`- ${event.title}`);
20
+ if (event.calendar)
21
+ lines.push(` - Calendar: ${event.calendar}`);
22
+ if (event.id)
23
+ lines.push(` - ID: ${event.id}`);
24
+ if (event.startDate)
25
+ lines.push(` - Start: ${event.startDate}`);
26
+ if (event.endDate)
27
+ lines.push(` - End: ${event.endDate}`);
28
+ if (event.isAllDay !== undefined)
29
+ lines.push(` - All Day: ${event.isAllDay}`);
30
+ if (event.location)
31
+ lines.push(` - Location: ${event.location}`);
32
+ if (event.structuredLocation)
33
+ lines.push(` - Structured Location: ${event.structuredLocation.title}`);
34
+ if (event.availability)
35
+ lines.push(` - Availability: ${event.availability}`);
36
+ if (event.alarms && event.alarms.length > 0) {
37
+ lines.push(` - Alarms: ${event.alarms.map(formatAlarm).join('; ')}`);
38
+ }
39
+ if (event.recurrenceRules && event.recurrenceRules.length > 0) {
40
+ lines.push(` - Repeats: ${formatRecurrenceRules(event.recurrenceRules)}`);
41
+ }
42
+ if (event.organizer)
43
+ lines.push(` - Organizer: ${event.organizer.name ?? event.organizer.url}`);
44
+ if (event.attendees && event.attendees.length > 0) {
45
+ const attendeeList = event.attendees.map((a) => a.name ?? a.url).join(', ');
46
+ lines.push(` - Attendees (${event.attendees.length}): ${attendeeList}`);
47
+ }
48
+ if (event.status)
49
+ lines.push(` - Status: ${event.status}`);
50
+ if (event.isDetached !== undefined)
51
+ lines.push(` - Detached: ${event.isDetached}`);
52
+ if (event.occurrenceDate)
53
+ lines.push(` - Occurrence Date: ${event.occurrenceDate}`);
54
+ if (event.externalId)
55
+ lines.push(` - External ID: ${event.externalId}`);
56
+ if (event.creationDate)
57
+ lines.push(` - Created: ${event.creationDate}`);
58
+ if (event.lastModifiedDate)
59
+ lines.push(` - Modified: ${event.lastModifiedDate}`);
60
+ if (event.notes)
61
+ lines.push(` - Notes: ${formatMultilineNotes(event.notes)}`);
62
+ if (event.url)
63
+ lines.push(` - URL: ${event.url}`);
64
+ return lines;
65
+ };
66
+ export const handleCreateCalendarEvent = async (args) => {
67
+ return handleAsyncOperation(async () => {
68
+ const validatedArgs = extractAndValidateArgs(args, CreateCalendarEventSchema);
69
+ const event = await calendarRepository.createEvent({
70
+ title: validatedArgs.title,
71
+ startDate: validatedArgs.startDate,
72
+ endDate: validatedArgs.endDate,
73
+ calendar: validatedArgs.targetCalendar,
74
+ notes: validatedArgs.note,
75
+ location: validatedArgs.location,
76
+ });
77
+ return formatSuccessMessage('created', 'event', event.title, event.id);
78
+ }, 'create calendar event');
79
+ };
80
+ export const handleUpdateCalendarEvent = async (args) => {
81
+ return handleAsyncOperation(async () => {
82
+ const validatedArgs = extractAndValidateArgs(args, UpdateCalendarEventSchema);
83
+ const event = await calendarRepository.updateEvent({
84
+ id: validatedArgs.id,
85
+ title: validatedArgs.title,
86
+ startDate: validatedArgs.startDate,
87
+ endDate: validatedArgs.endDate,
88
+ notes: validatedArgs.note,
89
+ location: validatedArgs.location,
90
+ });
91
+ return formatSuccessMessage('updated', 'event', event.title, event.id);
92
+ }, 'update calendar event');
93
+ };
94
+ export const handleDeleteCalendarEvent = async (args) => {
95
+ return handleAsyncOperation(async () => {
96
+ const validatedArgs = extractAndValidateArgs(args, DeleteCalendarEventSchema);
97
+ await calendarRepository.deleteEvent(validatedArgs.id, validatedArgs.span);
98
+ return formatDeleteMessage('event', validatedArgs.id, {
99
+ useQuotes: true,
100
+ useIdPrefix: true,
101
+ usePeriod: true,
102
+ useColon: false,
103
+ });
104
+ }, 'delete calendar event');
105
+ };
106
+ export const handleReadCalendarEvents = async (args) => {
107
+ return handleAsyncOperation(async () => {
108
+ const validatedArgs = extractAndValidateArgs(args, ReadCalendarEventsSchema);
109
+ if (validatedArgs.id) {
110
+ const event = await calendarRepository.findEventById(validatedArgs.id);
111
+ return [
112
+ '### Calendar Event',
113
+ '',
114
+ UNTRUSTED_DATA_NOTICE,
115
+ '',
116
+ ...formatEventMarkdown(event),
117
+ ].join('\n');
118
+ }
119
+ const events = await calendarRepository.findEvents({
120
+ startDate: validatedArgs.startDate,
121
+ endDate: validatedArgs.endDate,
122
+ calendarName: validatedArgs.filterCalendar,
123
+ search: validatedArgs.search,
124
+ availability: validatedArgs.availability,
125
+ });
126
+ return formatListMarkdown('Calendar Events', events, formatEventMarkdown, 'No calendar events found.');
127
+ }, 'read calendar events');
128
+ };
129
+ export const handleReadCalendars = async (args) => {
130
+ return handleAsyncOperation(async () => {
131
+ const validatedArgs = extractAndValidateArgs(args, ReadCalendarsSchema);
132
+ const calendars = await calendarRepository.findCalendars({
133
+ startDate: validatedArgs.startDate,
134
+ endDate: validatedArgs.endDate,
135
+ });
136
+ return formatListMarkdown('Calendars', calendars, (calendar) => {
137
+ // The vendored `event` CLI doesn't expose EventKit calendar
138
+ // identifiers, so calendars synthesized from the read window have
139
+ // `id === title`. Skip the trailing `(ID: …)` then since it just
140
+ // duplicates the title.
141
+ const idSuffix = calendar.id && calendar.id !== calendar.title
142
+ ? ` (ID: ${calendar.id})`
143
+ : '';
144
+ const countSuffix = calendar.eventCount !== undefined
145
+ ? ` - ${calendar.eventCount} event${calendar.eventCount === 1 ? '' : 's'}`
146
+ : '';
147
+ return [`- ${calendar.title}${idSuffix}${countSuffix}`];
148
+ }, 'No calendars found.');
149
+ }, 'read calendars');
150
+ };
151
+ //# sourceMappingURL=calendarHandlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendarHandlers.js","sourceRoot":"","sources":["../../../src/tools/handlers/calendarHandlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * handlers/formatters.ts
3
+ * Shared display formatters for reminder/event sub-structures (alarms,
4
+ * recurrence rules, location triggers). Calendar events and reminders both
5
+ * persist these as the same EventKit primitives, so rendering them through
6
+ * a single set of helpers keeps the two tool outputs consistent.
7
+ */
8
+ import type { Alarm, LocationTrigger, RecurrenceRule } from '../../types/index.js';
9
+ /**
10
+ * Formats a single recurrence rule into a short human-readable phrase
11
+ * (e.g. "every 2 weeks on Mon, Wed").
12
+ */
13
+ export declare const formatRecurrence: (recurrence: RecurrenceRule) => string;
14
+ export declare const formatRecurrenceRules: (rules: RecurrenceRule[]) => string;
15
+ /**
16
+ * Formats a location trigger as a short human-readable phrase
17
+ * (e.g. `Arriving at "Home" (100m radius)`).
18
+ */
19
+ export declare const formatLocationTrigger: (location: LocationTrigger) => string;
20
+ /**
21
+ * Formats a single alarm — relative offset, absolute date, or location
22
+ * trigger — into a single line.
23
+ */
24
+ export declare const formatAlarm: (alarm: Alarm) => string;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * handlers/formatters.ts
3
+ * Shared display formatters for reminder/event sub-structures (alarms,
4
+ * recurrence rules, location triggers). Calendar events and reminders both
5
+ * persist these as the same EventKit primitives, so rendering them through
6
+ * a single set of helpers keeps the two tool outputs consistent.
7
+ */
8
+ /**
9
+ * Formats a single recurrence rule into a short human-readable phrase
10
+ * (e.g. "every 2 weeks on Mon, Wed").
11
+ */
12
+ export const formatRecurrence = (recurrence) => {
13
+ const parts = [];
14
+ const interval = recurrence.interval > 1 ? `every ${recurrence.interval} ` : '';
15
+ switch (recurrence.frequency) {
16
+ case 'minutely':
17
+ parts.push(`${interval}minute${recurrence.interval > 1 ? 's' : ''}`);
18
+ break;
19
+ case 'hourly':
20
+ parts.push(`${interval}hour${recurrence.interval > 1 ? 's' : ''}`);
21
+ break;
22
+ case 'daily':
23
+ parts.push(`${interval}day${recurrence.interval > 1 ? 's' : ''}`);
24
+ break;
25
+ case 'weekly':
26
+ parts.push(`${interval}week${recurrence.interval > 1 ? 's' : ''}`);
27
+ if (recurrence.daysOfWeek?.length) {
28
+ const dayNames = ['', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
29
+ const days = recurrence.daysOfWeek.map((d) => dayNames[d]).join(', ');
30
+ parts.push(`on ${days}`);
31
+ }
32
+ break;
33
+ case 'monthly':
34
+ parts.push(`${interval}month${recurrence.interval > 1 ? 's' : ''}`);
35
+ if (recurrence.daysOfMonth?.length) {
36
+ parts.push(`on day${recurrence.daysOfMonth.length > 1 ? 's' : ''} ${recurrence.daysOfMonth.join(', ')}`);
37
+ }
38
+ break;
39
+ case 'yearly':
40
+ parts.push(`${interval}year${recurrence.interval > 1 ? 's' : ''}`);
41
+ if (recurrence.monthsOfYear?.length) {
42
+ const monthNames = [
43
+ '',
44
+ 'Jan',
45
+ 'Feb',
46
+ 'Mar',
47
+ 'Apr',
48
+ 'May',
49
+ 'Jun',
50
+ 'Jul',
51
+ 'Aug',
52
+ 'Sep',
53
+ 'Oct',
54
+ 'Nov',
55
+ 'Dec',
56
+ ];
57
+ const months = recurrence.monthsOfYear
58
+ .map((m) => monthNames[m])
59
+ .join(', ');
60
+ parts.push(`in ${months}`);
61
+ }
62
+ break;
63
+ default: {
64
+ const exhaustiveCheck = recurrence.frequency;
65
+ throw new Error(`Unknown recurrence frequency: ${exhaustiveCheck}`);
66
+ }
67
+ }
68
+ if (recurrence.endDate) {
69
+ parts.push(`until ${recurrence.endDate}`);
70
+ }
71
+ else if (recurrence.occurrenceCount) {
72
+ parts.push(`(${recurrence.occurrenceCount} times)`);
73
+ }
74
+ return parts.join(' ');
75
+ };
76
+ export const formatRecurrenceRules = (rules) => {
77
+ const [first, ...rest] = rules;
78
+ if (first && rest.length === 0)
79
+ return formatRecurrence(first);
80
+ return rules.map((rule) => formatRecurrence(rule)).join('; ');
81
+ };
82
+ /**
83
+ * Formats a location trigger as a short human-readable phrase
84
+ * (e.g. `Arriving at "Home" (100m radius)`).
85
+ */
86
+ export const formatLocationTrigger = (location) => {
87
+ const proximityText = location.proximity === 'enter' ? 'Arriving at' : 'Leaving';
88
+ const radiusText = location.radius ? ` (${location.radius}m radius)` : '';
89
+ return `${proximityText} "${location.title}"${radiusText}`;
90
+ };
91
+ /**
92
+ * Formats a single alarm — relative offset, absolute date, or location
93
+ * trigger — into a single line.
94
+ */
95
+ export const formatAlarm = (alarm) => {
96
+ const typeStr = alarm.alarmType ? ` (${alarm.alarmType})` : '';
97
+ if (alarm.absoluteDate)
98
+ return `at ${alarm.absoluteDate}${typeStr}`;
99
+ if (alarm.relativeOffset !== undefined)
100
+ return `${alarm.relativeOffset}s from due/start${typeStr}`;
101
+ if (alarm.locationTrigger)
102
+ return `on ${formatLocationTrigger(alarm.locationTrigger)}${typeStr}`;
103
+ return 'unknown';
104
+ };
105
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../../src/tools/handlers/formatters.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,UAA0B,EAAU,EAAE;IACrE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GACZ,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjE,QAAQ,UAAU,CAAC,SAAS,EAAE,CAAC;QAC7B,KAAK,UAAU;YACb,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,SAAS,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrE,MAAM;QACR,KAAK,QAAQ;YACX,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,OAAO,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnE,MAAM;QACR,KAAK,OAAO;YACV,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,MAAM,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClE,MAAM;QACR,KAAK,QAAQ;YACX,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,OAAO,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnE,IAAI,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;gBACvE,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;YAC3B,CAAC;YACD,MAAM;QACR,KAAK,SAAS;YACZ,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,QAAQ,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpE,IAAI,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;gBACnC,KAAK,CAAC,IAAI,CACR,SAAS,UAAU,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAC;YACJ,CAAC;YACD,MAAM;QACR,KAAK,QAAQ;YACX,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,OAAO,UAAU,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnE,IAAI,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;gBACpC,MAAM,UAAU,GAAG;oBACjB,EAAE;oBACF,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;oBACL,KAAK;iBACN,CAAC;gBACF,MAAM,MAAM,GAAG,UAAU,CAAC,YAAY;qBACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;qBACzB,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;YAC7B,CAAC;YACD,MAAM;QACR,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,eAAe,GAAU,UAAU,CAAC,SAAS,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,iCAAiC,eAAe,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,UAAU,CAAC,eAAe,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,eAAe,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAuB,EAAU,EAAE;IACvE,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;IAC/B,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC/D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAAyB,EAAU,EAAE;IACzE,MAAM,aAAa,GACjB,QAAQ,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,OAAO,GAAG,aAAa,KAAK,QAAQ,CAAC,KAAK,IAAI,UAAU,EAAE,CAAC;AAC7D,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAY,EAAU,EAAE;IAClD,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,IAAI,KAAK,CAAC,YAAY;QAAE,OAAO,MAAM,KAAK,CAAC,YAAY,GAAG,OAAO,EAAE,CAAC;IACpE,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS;QACpC,OAAO,GAAG,KAAK,CAAC,cAAc,mBAAmB,OAAO,EAAE,CAAC;IAC7D,IAAI,KAAK,CAAC,eAAe;QACvB,OAAO,MAAM,qBAAqB,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,OAAO,EAAE,CAAC;IACxE,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * handlers/index.ts
3
+ * Unified exports for all tool handlers
4
+ */
5
+ export { handleCreateCalendarEvent, handleDeleteCalendarEvent, handleReadCalendarEvents, handleReadCalendars, handleUpdateCalendarEvent, } from './calendarHandlers.js';
6
+ export { handleCreateReminderList, handleDeleteReminderList, handleReadReminderLists, handleUpdateReminderList, } from './listHandlers.js';
7
+ export { handleCreateReminder, handleDeleteReminder, handleReadReminders, handleUpdateReminder, } from './reminderHandlers.js';
8
+ export { handleCreateSubtask, handleDeleteSubtask, handleReadSubtasks, handleReorderSubtasks, handleToggleSubtask, handleUpdateSubtask, } from './subtaskHandlers.js';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * handlers/index.ts
3
+ * Unified exports for all tool handlers
4
+ */
5
+ export { handleCreateCalendarEvent, handleDeleteCalendarEvent, handleReadCalendarEvents, handleReadCalendars, handleUpdateCalendarEvent, } from './calendarHandlers.js';
6
+ export { handleCreateReminderList, handleDeleteReminderList, handleReadReminderLists, handleUpdateReminderList, } from './listHandlers.js';
7
+ export { handleCreateReminder, handleDeleteReminder, handleReadReminders, handleUpdateReminder, } from './reminderHandlers.js';
8
+ export { handleCreateSubtask, handleDeleteSubtask, handleReadSubtasks, handleReorderSubtasks, handleToggleSubtask, handleUpdateSubtask, } from './subtaskHandlers.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/handlers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * handlers/listHandlers.ts
3
+ * Handlers for reminder list operations
4
+ */
5
+ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
6
+ import type { ListsToolArgs } from '../../types/index.js';
7
+ export declare const handleReadReminderLists: () => Promise<CallToolResult>;
8
+ export declare const handleCreateReminderList: (args: ListsToolArgs) => Promise<CallToolResult>;
9
+ export declare const handleUpdateReminderList: (args: ListsToolArgs) => Promise<CallToolResult>;
10
+ export declare const handleDeleteReminderList: (args: ListsToolArgs) => Promise<CallToolResult>;