@mcp-monorepo/ics 1.2.0 → 1.3.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 (71) hide show
  1. package/dist/ics-parser/errors.d.ts +16 -0
  2. package/dist/ics-parser/errors.d.ts.map +1 -0
  3. package/dist/ics-parser/errors.js +31 -0
  4. package/dist/ics-parser/errors.js.map +1 -0
  5. package/dist/ics-parser/event-expander.d.ts +71 -0
  6. package/dist/ics-parser/event-expander.d.ts.map +1 -0
  7. package/dist/ics-parser/event-expander.js +328 -0
  8. package/dist/ics-parser/event-expander.js.map +1 -0
  9. package/dist/ics-parser/index.d.ts +67 -0
  10. package/dist/ics-parser/index.d.ts.map +1 -0
  11. package/dist/ics-parser/index.js +91 -0
  12. package/dist/ics-parser/index.js.map +1 -0
  13. package/dist/ics-parser/parser.d.ts +26 -0
  14. package/dist/ics-parser/parser.d.ts.map +1 -0
  15. package/dist/ics-parser/parser.js +99 -0
  16. package/dist/ics-parser/parser.js.map +1 -0
  17. package/dist/ics-parser/property-parsers.d.ts +66 -0
  18. package/dist/ics-parser/property-parsers.d.ts.map +1 -0
  19. package/dist/ics-parser/property-parsers.js +226 -0
  20. package/dist/ics-parser/property-parsers.js.map +1 -0
  21. package/dist/ics-parser/rrule-expander.d.ts +10 -0
  22. package/dist/ics-parser/rrule-expander.d.ts.map +1 -0
  23. package/dist/ics-parser/rrule-expander.js +305 -0
  24. package/dist/ics-parser/rrule-expander.js.map +1 -0
  25. package/dist/ics-parser/timezone-processor.d.ts +40 -0
  26. package/dist/ics-parser/timezone-processor.d.ts.map +1 -0
  27. package/dist/ics-parser/timezone-processor.js +219 -0
  28. package/dist/ics-parser/timezone-processor.js.map +1 -0
  29. package/dist/ics-parser/types.d.ts +119 -0
  30. package/dist/ics-parser/types.d.ts.map +1 -0
  31. package/dist/ics-parser/types.js +2 -0
  32. package/dist/ics-parser/types.js.map +1 -0
  33. package/dist/ics-parser/utils.d.ts +16 -0
  34. package/dist/ics-parser/utils.d.ts.map +1 -0
  35. package/dist/ics-parser/utils.js +19 -0
  36. package/dist/ics-parser/utils.js.map +1 -0
  37. package/dist/index.js +5 -3
  38. package/dist/index.js.map +1 -1
  39. package/dist/lib/config.d.ts +10 -0
  40. package/dist/lib/config.d.ts.map +1 -0
  41. package/dist/lib/config.js +39 -0
  42. package/dist/lib/config.js.map +1 -0
  43. package/dist/lib/event-store-2.d.ts +11 -0
  44. package/dist/lib/event-store-2.d.ts.map +1 -0
  45. package/dist/lib/event-store-2.js +90 -0
  46. package/dist/lib/event-store-2.js.map +1 -0
  47. package/dist/lib/format-date.d.ts +7 -1
  48. package/dist/lib/format-date.d.ts.map +1 -1
  49. package/dist/lib/format-date.js +9 -4
  50. package/dist/lib/format-date.js.map +1 -1
  51. package/dist/lib/types.d.ts +0 -42
  52. package/dist/lib/types.d.ts.map +1 -1
  53. package/dist/tools/fetch-events.d.ts.map +1 -1
  54. package/dist/tools/fetch-events.js +31 -26
  55. package/dist/tools/fetch-events.js.map +1 -1
  56. package/dist/tools/search-events.d.ts.map +1 -1
  57. package/dist/tools/search-events.js +50 -17
  58. package/dist/tools/search-events.js.map +1 -1
  59. package/package.json +10 -6
  60. package/dist/lib/event-store.d.ts +0 -20
  61. package/dist/lib/event-store.d.ts.map +0 -1
  62. package/dist/lib/event-store.js +0 -107
  63. package/dist/lib/event-store.js.map +0 -1
  64. package/dist/lib/filter-events.d.ts +0 -3
  65. package/dist/lib/filter-events.d.ts.map +0 -1
  66. package/dist/lib/filter-events.js +0 -10
  67. package/dist/lib/filter-events.js.map +0 -1
  68. package/dist/lib/recurrrence.d.ts +0 -3
  69. package/dist/lib/recurrrence.d.ts.map +0 -1
  70. package/dist/lib/recurrrence.js +0 -70
  71. package/dist/lib/recurrrence.js.map +0 -1
@@ -0,0 +1,119 @@
1
+ import { type DateTime } from 'luxon';
2
+ export interface IcsProperty {
3
+ key: string;
4
+ value: string;
5
+ params: Record<string, string>;
6
+ }
7
+ export interface VComponent {
8
+ type: string;
9
+ properties: IcsProperty[];
10
+ subComponents: VComponent[];
11
+ }
12
+ export interface ParsedIcs {
13
+ events: VComponent[];
14
+ timezones: VComponent[];
15
+ }
16
+ export type Freq = 'YEARLY' | 'MONTHLY' | 'WEEKLY' | 'DAILY' | 'HOURLY' | 'MINUTELY' | 'SECONDLY';
17
+ export type Weekday = 'SU' | 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA';
18
+ export interface WeekdayRule {
19
+ weekday: Weekday;
20
+ n?: number;
21
+ }
22
+ export interface RecurrenceRule {
23
+ freq: Freq;
24
+ interval?: number;
25
+ count?: number;
26
+ until?: DateTime;
27
+ wkst?: Weekday;
28
+ byday?: WeekdayRule[];
29
+ bymonth?: number[];
30
+ bymonthday?: number[];
31
+ byyearday?: number[];
32
+ byweekno?: number[];
33
+ byhour?: number[];
34
+ byminute?: number[];
35
+ bysecond?: number[];
36
+ bysetpos?: number[];
37
+ }
38
+ export interface RRuleOptions {
39
+ dtstart: DateTime;
40
+ rule: RecurrenceRule;
41
+ rangeStart?: DateTime;
42
+ rangeEnd: DateTime;
43
+ }
44
+ export interface TimeZoneObservance {
45
+ dtstart: string;
46
+ offsetTo: number;
47
+ offsetFrom: number;
48
+ rrule?: string;
49
+ rdates: IcsProperty[];
50
+ }
51
+ export interface TimeZoneTransition {
52
+ transitionTime: DateTime;
53
+ offsetTo: number;
54
+ }
55
+ export interface TimeZoneData {
56
+ observances: TimeZoneObservance[];
57
+ url?: string;
58
+ }
59
+ export type TimeZoneResolver = (localTime: DateTime, tzid: string) => number;
60
+ /**
61
+ * Represents a calendar address for properties like ORGANIZER or ATTENDEE.
62
+ */
63
+ export interface CalAddress {
64
+ email: string;
65
+ commonName?: string;
66
+ partstat?: string;
67
+ role?: string;
68
+ }
69
+ /**
70
+ * Represents a geographic position.
71
+ */
72
+ export interface Geo {
73
+ lat: number;
74
+ lon: number;
75
+ }
76
+ /**
77
+ * Represents a fully expanded, concrete event occurrence.
78
+ * All date-time fields are in UTC ISO 8601 format.
79
+ */
80
+ export interface ExpandedEvent {
81
+ uid: string;
82
+ summary: string;
83
+ /** ISO 8601 format with Z */
84
+ start: string;
85
+ /** ISO 8601 format with Z */
86
+ end?: string;
87
+ allDay: boolean;
88
+ description?: string;
89
+ location?: string;
90
+ status?: 'TENTATIVE' | 'CONFIRMED' | 'CANCELLED';
91
+ class?: 'PUBLIC' | 'PRIVATE' | 'CONFIDENTIAL';
92
+ created?: string;
93
+ lastModified?: string;
94
+ sequence?: number;
95
+ organizer?: CalAddress;
96
+ attendees?: CalAddress[];
97
+ categories?: string[];
98
+ priority?: number;
99
+ transp?: 'OPAQUE' | 'TRANSPARENT';
100
+ url?: string;
101
+ geo?: Geo;
102
+ /**
103
+ * The recurrence ID for this specific instance, if it's an override.
104
+ */
105
+ recurrenceId?: string;
106
+ /**
107
+ * Holds any non-standard (X-) or IANA-registered properties.
108
+ */
109
+ customProperties?: Record<string, IcsProperty>;
110
+ }
111
+ /**
112
+ * Represents a parsed but not expanded event, including its recurrence rules.
113
+ */
114
+ export interface UnexpandedEvent extends ExpandedEvent {
115
+ rrule?: RecurrenceRule;
116
+ rdates?: string[];
117
+ exdates?: string[];
118
+ }
119
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ics-parser/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAErC,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,aAAa,EAAE,UAAU,EAAE,CAAA;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,SAAS,EAAE,UAAU,EAAE,CAAA;CACxB;AAED,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAA;AACjG,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAEpE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,CAAC,CAAC,EAAE,MAAM,CAAA;CACX;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,QAAQ,CAAA;IACjB,IAAI,EAAE,cAAc,CAAA;IACpB,UAAU,CAAC,EAAE,QAAQ,CAAA;IACrB,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,WAAW,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,QAAQ,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,kBAAkB,EAAE,CAAA;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;AAE5E;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAA;IAChD,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,cAAc,CAAA;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,SAAS,CAAC,EAAE,UAAU,EAAE,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAA;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,GAAG,CAAA;IACT;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/ics-parser/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ import { type IcsProperty, type VComponent } from './types.js';
2
+ /**
3
+ * Finds the first property with a given key from a component's properties.
4
+ * @param component - The VComponent to search.
5
+ * @param key - The property key (e.g., 'DTSTART').
6
+ * @returns The IcsProperty or undefined if not found.
7
+ */
8
+ export declare function findProperty(component: VComponent, key: string): IcsProperty | undefined;
9
+ /**
10
+ * Finds all properties with a given key from a component's properties.
11
+ * @param component - The VComponent to search.
12
+ * @param key - The property key (e.g., 'EXDATE').
13
+ * @returns An array of matching IcsProperty objects.
14
+ */
15
+ export declare function findProperties(component: VComponent, key: string): IcsProperty[];
16
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/ics-parser/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAE9D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAEhF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Finds the first property with a given key from a component's properties.
3
+ * @param component - The VComponent to search.
4
+ * @param key - The property key (e.g., 'DTSTART').
5
+ * @returns The IcsProperty or undefined if not found.
6
+ */
7
+ export function findProperty(component, key) {
8
+ return component.properties.find((p) => p.key === key);
9
+ }
10
+ /**
11
+ * Finds all properties with a given key from a component's properties.
12
+ * @param component - The VComponent to search.
13
+ * @param key - The property key (e.g., 'EXDATE').
14
+ * @returns An array of matching IcsProperty objects.
15
+ */
16
+ export function findProperties(component, key) {
17
+ return component.properties.filter((p) => p.key === key);
18
+ }
19
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/ics-parser/utils.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,SAAqB,EAAE,GAAW;IAC7D,OAAO,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,SAAqB,EAAE,GAAW;IAC/D,OAAO,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;AAC1D,CAAC"}
package/dist/index.js CHANGED
@@ -1,20 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { createMcpServer } from '@mcp-monorepo/shared';
3
3
  import { logger } from '@mcp-monorepo/shared';
4
- import { getRawEvents } from './lib/event-store.js';
4
+ import { getPreparedIcs } from './lib/event-store-2.js';
5
5
  import { registerFetchEventsTool } from './tools/fetch-events.js';
6
6
  import { registerGetCurrentDatetimeTool } from './tools/get-current-datetime.js';
7
7
  import { registerSearchEventsTool } from './tools/search-events.js';
8
+ process.env.CALENDAR_Arbeit =
9
+ 'https://outlook.office365.com/owa/calendar/6726b109005640a4982f52968f443e51@netlight.com/840711b63b9c446a89efbac67588c7a812184317992758283667/S-1-8-1012071154-1048752624-2164084980-293329427/reachcalendar.ics';
8
10
  createMcpServer({
9
11
  name: 'ics',
10
12
  importMetaPath: import.meta.filename,
11
13
  title: 'ICS Calendar MCP Server',
12
14
  tools: [registerGetCurrentDatetimeTool, registerFetchEventsTool, registerSearchEventsTool],
13
15
  }).then(() => logger.error);
14
- getRawEvents()
16
+ getPreparedIcs()
15
17
  .refresh()
16
18
  .then(() => logger.error);
17
- setTimeout(() => getRawEvents()
19
+ setTimeout(() => getPreparedIcs()
18
20
  .refresh()
19
21
  .then(() => logger.error), 1000 * 60 * 60);
20
22
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAA;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,eAAe,CAAC;IACd,IAAI,EAAE,KAAK;IACX,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ;IACpC,KAAK,EAAE,yBAAyB;IAChC,KAAK,EAAE,CAAC,8BAA8B,EAAE,uBAAuB,EAAE,wBAAwB,CAAC;CAC3F,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAE3B,YAAY,EAAE;KACX,OAAO,EAAE;KACT,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC3B,UAAU,CACR,GAAG,EAAE,CACH,YAAY,EAAE;KACX,OAAO,EAAE;KACT,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC7B,IAAI,GAAG,EAAE,GAAG,EAAE,CACf,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAA;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,OAAO,CAAC,GAAG,CAAC,eAAe;IACzB,kNAAkN,CAAA;AAEpN,eAAe,CAAC;IACd,IAAI,EAAE,KAAK;IACX,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ;IACpC,KAAK,EAAE,yBAAyB;IAChC,KAAK,EAAE,CAAC,8BAA8B,EAAE,uBAAuB,EAAE,wBAAwB,CAAC;CAC3F,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAE3B,cAAc,EAAE;KACb,OAAO,EAAE;KACT,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC3B,UAAU,CACR,GAAG,EAAE,CACH,cAAc,EAAE;KACb,OAAO,EAAE;KACT,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC7B,IAAI,GAAG,EAAE,GAAG,EAAE,CACf,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { type CalendarSource } from './types.js';
2
+ /**
3
+ * Gets calendar sources from environment variables.
4
+ * Variables should be prefixed with `CALENDAR_`.
5
+ *
6
+ * @returns An array of calendar sources.
7
+ * @throws If no valid calendar sources are found or a URL is invalid.
8
+ */
9
+ export declare const getIcsUrls: () => CalendarSource[];
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAA;AAahD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAO,cAAc,EAsB3C,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { logger } from '@mcp-monorepo/shared';
2
+ /**
3
+ * Throws an error and logs a message when no ICS URLs are configured.
4
+ */
5
+ function throwForNoIcsUrls() {
6
+ const errorMessage = 'No calendar sources configured. Please set environment variables starting with "CALENDAR_".\n' +
7
+ 'For example: CALENDAR_PRIVATE="https://your-calendar-url/basic.ics"';
8
+ logger.error(errorMessage);
9
+ throw new Error(errorMessage);
10
+ }
11
+ /**
12
+ * Gets calendar sources from environment variables.
13
+ * Variables should be prefixed with `CALENDAR_`.
14
+ *
15
+ * @returns An array of calendar sources.
16
+ * @throws If no valid calendar sources are found or a URL is invalid.
17
+ */
18
+ export const getIcsUrls = () => {
19
+ const envVars = process.env;
20
+ const calendarSources = [];
21
+ Object.keys(envVars).forEach((key) => {
22
+ const ENV_PREFIX = 'CALENDAR_';
23
+ if (key.startsWith(ENV_PREFIX)) {
24
+ const url = envVars[key];
25
+ if (url && (url.startsWith('http://') || url.startsWith('https://'))) {
26
+ const name = key.substring(ENV_PREFIX.length);
27
+ calendarSources.push({ name, url });
28
+ }
29
+ else {
30
+ throw new Error(`Invalid URL for environment variable ${key}: ${url}`);
31
+ }
32
+ }
33
+ });
34
+ if (calendarSources.length === 0) {
35
+ throwForNoIcsUrls();
36
+ }
37
+ return calendarSources;
38
+ };
39
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAI7C;;GAEG;AACH,SAAS,iBAAiB;IACxB,MAAM,YAAY,GAChB,+FAA+F;QAC/F,qEAAqE,CAAA;IACvE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC1B,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAA;AAC/B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,GAAqB,EAAE;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAA;IAC3B,MAAM,eAAe,GAAqB,EAAE,CAAA;IAE5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACnC,MAAM,UAAU,GAAG,WAAW,CAAA;QAC9B,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;YACxB,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBACrE,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;gBAC7C,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;YACrC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,KAAK,GAAG,EAAE,CAAC,CAAA;YACxE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,iBAAiB,EAAE,CAAA;IACrB,CAAC;IAED,OAAO,eAAe,CAAA;AACxB,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { RefreshablePromise } from '@mcp-monorepo/shared';
2
+ import { type PreparedIcs } from '../ics-parser/index.js';
3
+ /**
4
+ * Gets the singleton instance of the RefreshablePromise for prepared ICS data.
5
+ * The instance is created on the first call.
6
+ */
7
+ export declare function getPreparedIcs(): RefreshablePromise<{
8
+ prepared: PreparedIcs;
9
+ errors: string[];
10
+ }>;
11
+ //# sourceMappingURL=event-store-2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-store-2.d.ts","sourceRoot":"","sources":["../../src/lib/event-store-2.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAGlF,OAAO,EAAmC,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAsF1F;;;GAGG;AACH,wBAAgB,cAAc;cAN2B,WAAW;YAAU,MAAM,EAAE;GAWrF"}
@@ -0,0 +1,90 @@
1
+ import { mkdir, readFile, writeFile } from 'fs/promises';
2
+ import { dirname, join } from 'path';
3
+ import { findProjectRoot, logger, RefreshablePromise } from '@mcp-monorepo/shared';
4
+ import { getIcsUrls } from './config.js';
5
+ import { deserialize, prepare, serialize } from '../ics-parser/index.js';
6
+ /**
7
+ * The core refresh function. It fetches ICS files, prepares them using the parser,
8
+ * and caches the prepared, serializable data. On failure, it falls back to the cache.
9
+ */
10
+ async function refreshPreparedData() {
11
+ logger.info('Refreshing and preparing calendar data...');
12
+ const sources = getIcsUrls();
13
+ const allErrors = [];
14
+ const projectRoot = await findProjectRoot(import.meta.dirname);
15
+ const processPromises = sources.map(async (source) => {
16
+ // Cache prepared data in its own directory
17
+ const dataFile = join(projectRoot, 'data', 'ics-prepared', source.url.replace(/[^a-zA-Z0-9]/g, '_') + '.json');
18
+ try {
19
+ logger.info(`[${source.name}] Attempting to fetch fresh data...`);
20
+ const response = await fetch(source.url);
21
+ if (!response.ok) {
22
+ throw new Error(`Fetch failed with status ${response.status} ${response.statusText}`);
23
+ }
24
+ const icsText = await response.text();
25
+ const preparedData = prepare(icsText);
26
+ // Inject the source name into each event component for later identification.
27
+ // This uses a custom 'X-' property, which the parser is designed to handle.
28
+ preparedData.events.forEach((eventComponent) => {
29
+ eventComponent.properties.push({
30
+ key: 'X-MCP-SOURCE',
31
+ value: source.name,
32
+ params: {},
33
+ });
34
+ });
35
+ logger.info(`[${source.name}] Successfully fetched and prepared data.`);
36
+ // Asynchronously cache the new prepared data
37
+ try {
38
+ await mkdir(dirname(dataFile), { recursive: true });
39
+ const jsonToCache = serialize(preparedData);
40
+ await writeFile(dataFile, jsonToCache);
41
+ logger.info(`[${source.name}] Successfully cached prepared data.`);
42
+ }
43
+ catch (cacheError) {
44
+ logger.warn(`[${source.name}] Failed to write prepared data to cache: ${cacheError}`);
45
+ }
46
+ return preparedData;
47
+ }
48
+ catch (fetchError) {
49
+ const errorMessage = `[${source.name}] Fetch failed: ${fetchError instanceof Error ? fetchError.message : String(fetchError)}.`;
50
+ logger.warn(`${errorMessage} Attempting to use cache.`);
51
+ try {
52
+ const cachedJson = await readFile(dataFile, 'utf-8');
53
+ const preparedData = deserialize(cachedJson);
54
+ logger.info(`[${source.name}] Successfully loaded prepared data from cache.`);
55
+ return preparedData;
56
+ }
57
+ catch (cacheError) {
58
+ const finalErrorMsg = `[${source.name}] Fetch failed and cache is unavailable or corrupt.`;
59
+ logger.error(finalErrorMsg, cacheError);
60
+ allErrors.push(finalErrorMsg);
61
+ return undefined; // Indicate failure for this source
62
+ }
63
+ }
64
+ });
65
+ // Wait for all sources to be processed (either fetched or from cache)
66
+ const allPreparedOrNull = await Promise.all(processPromises);
67
+ const allPrepared = allPreparedOrNull.filter((p) => p !== undefined);
68
+ // Combine all prepared data into a single object for the consumer
69
+ const combinedPrepared = { events: [], tzData: new Map() };
70
+ for (const preparedData of allPrepared) {
71
+ combinedPrepared.events.push(...preparedData.events);
72
+ for (const [tzid, data] of preparedData.tzData.entries()) {
73
+ combinedPrepared.tzData.set(tzid, data);
74
+ }
75
+ }
76
+ logger.info(`Finished refreshing. Total VEVENTs prepared: ${combinedPrepared.events.length}, Total errors: ${allErrors.length}`);
77
+ return { prepared: combinedPrepared, errors: allErrors };
78
+ }
79
+ let preparedDataInstance;
80
+ /**
81
+ * Gets the singleton instance of the RefreshablePromise for prepared ICS data.
82
+ * The instance is created on the first call.
83
+ */
84
+ export function getPreparedIcs() {
85
+ if (!preparedDataInstance) {
86
+ preparedDataInstance = new RefreshablePromise(refreshPreparedData);
87
+ }
88
+ return preparedDataInstance;
89
+ }
90
+ //# sourceMappingURL=event-store-2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-store-2.js","sourceRoot":"","sources":["../../src/lib/event-store-2.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,8 @@
1
- export declare function formatDate(date: Date, allDay?: boolean, timeZone?: string): string;
1
+ /**
2
+ * Formats a Date object into a string.
3
+ * @param date The date to format.
4
+ * @param allDay If true, only the date part is returned (YYYY-MM-DD).
5
+ * @returns A formatted date string.
6
+ */
7
+ export declare function formatDate(date: Date, allDay: boolean): string;
2
8
  //# sourceMappingURL=format-date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-date.d.ts","sourceRoot":"","sources":["../../src/lib/format-date.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,UAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAmBhF"}
1
+ {"version":3,"file":"format-date.d.ts","sourceRoot":"","sources":["../../src/lib/format-date.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAmB9D"}
@@ -1,11 +1,17 @@
1
- export function formatDate(date, allDay = false, timeZone) {
1
+ /**
2
+ * Formats a Date object into a string.
3
+ * @param date The date to format.
4
+ * @param allDay If true, only the date part is returned (YYYY-MM-DD).
5
+ * @returns A formatted date string.
6
+ */
7
+ export function formatDate(date, allDay) {
2
8
  if (allDay) {
3
- return new Date(date).toLocaleDateString('en-US', {
9
+ // For all-day events, return in YYYY-MM-DD format
10
+ return date.toLocaleString('en-US', {
4
11
  weekday: 'long',
5
12
  year: 'numeric',
6
13
  month: 'long',
7
14
  day: 'numeric',
8
- timeZone,
9
15
  });
10
16
  }
11
17
  return date.toLocaleString('en-US', {
@@ -15,7 +21,6 @@ export function formatDate(date, allDay = false, timeZone) {
15
21
  day: 'numeric',
16
22
  hour: '2-digit',
17
23
  minute: '2-digit',
18
- timeZone,
19
24
  });
20
25
  }
21
26
  //# sourceMappingURL=format-date.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-date.js","sourceRoot":"","sources":["../../src/lib/format-date.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,IAAU,EAAE,MAAM,GAAG,KAAK,EAAE,QAAiB;IACtE,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE;YAChD,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,SAAS;YACd,QAAQ;SACT,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;QAClC,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;QACjB,QAAQ;KACT,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"format-date.js","sourceRoot":"","sources":["../../src/lib/format-date.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU,EAAE,MAAe;IACpD,IAAI,MAAM,EAAE,CAAC;QACX,kDAAkD;QAClD,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;YAClC,OAAO,EAAE,MAAM;YACf,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,SAAS;SACf,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;QAClC,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,SAAS;KAClB,CAAC,CAAA;AACJ,CAAC"}
@@ -1,45 +1,3 @@
1
- import { type VEventStatus } from 'node-ical';
2
- export interface CalendarEvent {
3
- uid: string;
4
- summary: string;
5
- dtstart: Date;
6
- dtend?: Date;
7
- allDay: boolean;
8
- location?: string;
9
- description?: string;
10
- source: string;
11
- isRecurring?: boolean;
12
- }
13
- export interface RRuleLike {
14
- between: (start: Date, end: Date) => Date[];
15
- origOptions?: {
16
- tzid?: string;
17
- dtstart: Date;
18
- [key: string]: unknown;
19
- };
20
- }
21
- export interface RawIcalEvent {
22
- uid: string;
23
- summary: string;
24
- description?: string;
25
- location?: string;
26
- dtstart: Date;
27
- dtend?: Date;
28
- allDay: boolean;
29
- source: string;
30
- rrule?: RRuleLike;
31
- rruleOptions?: {
32
- tzid?: string;
33
- dtstart: Date;
34
- };
35
- exdate?: {
36
- [key: string]: Date;
37
- };
38
- recurrences?: {
39
- [key: string]: RawIcalEvent;
40
- };
41
- status?: VEventStatus;
42
- }
43
1
  export interface CalendarSource {
44
2
  name: string;
45
3
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AAE7C,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,EAAE,CAAA;IAC3C,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,IAAI,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CACvE;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,YAAY,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,IAAI,CAAA;KAAE,CAAA;IAC/C,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;IAChC,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,CAAA;IAC7C,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;CACZ"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;CACZ"}
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-events.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-events.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,eAAO,MAAM,uBAAuB,GAAI,QAAQ,SAAS,SA8DrD,CAAA"}
1
+ {"version":3,"file":"fetch-events.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-events.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,eAAO,MAAM,uBAAuB,GAAI,QAAQ,SAAS,SAyErD,CAAA"}
@@ -1,13 +1,12 @@
1
1
  import { registerTool } from '@mcp-monorepo/shared';
2
2
  import { z } from 'zod';
3
- import { getRawEvents } from '../lib/event-store.js';
4
- import { filterEvents } from '../lib/filter-events.js';
3
+ import { getEventsBetween } from '../ics-parser/index.js';
4
+ import { getPreparedIcs } from '../lib/event-store-2.js';
5
5
  import { formatDate } from '../lib/format-date.js';
6
- import { resolveRecurrence } from '../lib/recurrrence.js';
7
6
  export const registerFetchEventsTool = (server) => registerTool(server, {
8
7
  name: 'fetch-events',
9
8
  title: 'Fetch Calendar Events',
10
- description: 'Fetches events from multiple ICS calendar URLs for a specified time period.',
9
+ description: 'Fetches events from multiple ICS calendar URLs for a specified time period. cc',
11
10
  inputSchema: {
12
11
  offset: z.number().default(0).describe('Offset to start returning events from (default: 0)'),
13
12
  limit: z.number().default(50).describe('Maximum number of events to return (default: 50)'),
@@ -29,33 +28,39 @@ export const registerFetchEventsTool = (server) => registerTool(server, {
29
28
  },
30
29
  isReadOnly: true,
31
30
  async fetcher({ endDate, limit, offset, startDate }) {
32
- const start = new Date(startDate + 'T00:00:00');
33
- const end = new Date(endDate + 'T23:59:59');
34
- if (start > end)
31
+ if (new Date(startDate) > new Date(endDate)) {
35
32
  throw new Error('Error: Start date must be before end date');
36
- const events = await getRawEvents();
37
- const expandedEvents = resolveRecurrence(events.events, start, end);
38
- const filteredEvents = filterEvents(expandedEvents, start, end);
33
+ }
34
+ // Get the prepared (and cached) data from the new store
35
+ const { prepared, errors } = await getPreparedIcs();
36
+ // The new parser requires UTC ISO strings for the range
37
+ const startIso = new Date(`${startDate}T00:00:00.000Z`).toISOString();
38
+ const endIso = new Date(`${endDate}T23:59:59.999Z`).toISOString();
39
+ // Let the new parser do all the heavy lifting of expanding and filtering
40
+ const expandedEvents = getEventsBetween(prepared, startIso, endIso);
39
41
  return {
40
- events: filteredEvents.slice(offset, offset + limit),
41
- errors: events.errors,
42
- total: filteredEvents.length,
42
+ events: expandedEvents.slice(offset, offset + limit),
43
+ errors,
44
+ total: expandedEvents.length,
43
45
  };
44
46
  },
45
47
  formatter({ events, errors, total }) {
46
- const formattedEvents = events.map((event) => ({
47
- summary: event.summary,
48
- start: formatDate(event.dtstart, event.allDay),
49
- ...(event.dtend ? { end: formatDate(event.dtend, event.allDay) } : {}),
50
- description: event.description
51
- ? event.description.length > 400
52
- ? event.description.substring(0, 400) + '...'
53
- : event.description
54
- : undefined,
55
- location: event.location,
56
- uid: event.uid,
57
- source: event.source,
58
- }));
48
+ const formattedEvents = events.map((event) => {
49
+ const source = event.customProperties?.['X-MCP-SOURCE']?.value ?? 'Unknown';
50
+ return {
51
+ summary: event.summary,
52
+ start: formatDate(new Date(event.start), event.allDay),
53
+ ...(event.end ? { end: formatDate(new Date(event.end), event.allDay) } : {}),
54
+ description: event.description
55
+ ? event.description.length > 400
56
+ ? event.description.substring(0, 400) + '...'
57
+ : event.description
58
+ : undefined,
59
+ location: event.location,
60
+ uid: event.uid,
61
+ source: source,
62
+ };
63
+ });
59
64
  return {
60
65
  events: formattedEvents,
61
66
  errors,
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-events.js","sourceRoot":"","sources":["../../src/tools/fetch-events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-events.js","sourceRoot":"","sources":["../../src/tools/fetch-events.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"search-events.d.ts","sourceRoot":"","sources":["../../src/tools/search-events.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,eAAO,MAAM,wBAAwB,GAAI,QAAQ,SAAS,SAkFtD,CAAA"}
1
+ {"version":3,"file":"search-events.d.ts","sourceRoot":"","sources":["../../src/tools/search-events.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAExE,eAAO,MAAM,wBAAwB,GAAI,QAAQ,SAAS,SAqHtD,CAAA"}