@protocoltooling/fullcalendar 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -14,7 +14,7 @@ npm install @protocoltooling/fullcalendar
14
14
 
15
15
  ```bash
16
16
  npm pack
17
- npm install /path/to/protocoltooling-fullcalendar-0.1.0.tgz
17
+ npm install /path/to/protocoltooling-fullcalendar-0.2.0.tgz
18
18
  ```
19
19
 
20
20
  ### Peer Dependencies
package/dist/index.d.ts CHANGED
@@ -1,7 +1,29 @@
1
1
  import { RefObject } from 'react';
2
2
 
3
+ /**
4
+ * JSON-safe primitive values for WebMCP tool boundaries.
5
+ */
6
+ type JsonPrimitive = string | number | boolean | null;
7
+ /**
8
+ * Recursive JSON-safe value. Intentionally excludes Date, Map, Set, BigInt,
9
+ * functions, undefined, and class instances that are not plain JSON.
10
+ */
11
+ type JsonValue = JsonPrimitive | JsonValue[] | {
12
+ [key: string]: JsonValue;
13
+ };
14
+ /**
15
+ * JSON-safe object used for host-selected, agent-visible event metadata.
16
+ */
17
+ type JsonObject = {
18
+ [key: string]: JsonValue;
19
+ };
3
20
  /**
4
21
  * Normalized calendar event model.
22
+ *
23
+ * `metadata` is an optional, host-selected, JSON-safe projection for agents.
24
+ * It is read-only at the WebMCP write boundary: create/update inputs never
25
+ * accept metadata. Omission means nothing agent-visible beyond core fields.
26
+ * Protocol Tooling does not automatically expose FullCalendar `extendedProps`.
5
27
  */
6
28
  interface CalendarEvent {
7
29
  id: string;
@@ -9,9 +31,11 @@ interface CalendarEvent {
9
31
  start: string;
10
32
  end: string | null;
11
33
  allDay: boolean;
34
+ metadata?: JsonObject;
12
35
  }
13
36
  /**
14
37
  * Input payload for creating a new calendar event.
38
+ * Metadata is intentionally absent — writes remain core fields only.
15
39
  */
16
40
  interface CreateCalendarEventInput {
17
41
  title: string;
@@ -21,6 +45,7 @@ interface CreateCalendarEventInput {
21
45
  }
22
46
  /**
23
47
  * Input payload for updating an existing calendar event.
48
+ * Metadata is intentionally absent — writes remain core fields only.
24
49
  */
25
50
  interface UpdateCalendarEventInput {
26
51
  title?: string;
@@ -89,4 +114,4 @@ interface FullCalendarWebMCPOptions {
89
114
  */
90
115
  declare function useFullCalendarWebMCP(options: FullCalendarWebMCPOptions): void;
91
116
 
92
- export { type CalendarEvent, type CalendarEventQuery, type CalendarEventRepository, type CreateCalendarEventInput, type FullCalendarHandle, type FullCalendarWebMCPOptions, type UpdateCalendarEventInput, useFullCalendarWebMCP };
117
+ export { type CalendarEvent, type CalendarEventQuery, type CalendarEventRepository, type CreateCalendarEventInput, type FullCalendarHandle, type FullCalendarWebMCPOptions, type JsonObject, type JsonPrimitive, type JsonValue, type UpdateCalendarEventInput, useFullCalendarWebMCP };
package/dist/index.js CHANGED
@@ -36,6 +36,9 @@ function readAnnotations() {
36
36
  function writeAnnotations() {
37
37
  return { readOnlyHint: false, untrustedContentHint: true };
38
38
  }
39
+ function executionSignal(executeOptions) {
40
+ return executeOptions?.signal;
41
+ }
39
42
  function createCalendarTools(readOptions) {
40
43
  return [
41
44
  {
@@ -61,7 +64,7 @@ function createCalendarTools(readOptions) {
61
64
  {
62
65
  name: "calendar_list_events",
63
66
  title: "List calendar events",
64
- description: "List persisted calendar events, optionally filtered by an inclusive start, exclusive end, or case-insensitive title text. Use an end boundary one day after the requested day.",
67
+ description: "List persisted calendar events, optionally filtered by an inclusive start, exclusive end, or case-insensitive title text. Use an end boundary one day after the requested day. Events may include optional host-selected metadata (JSON object) for agent context; Protocol Tooling does not automatically expose FullCalendar extendedProps.",
65
68
  inputSchema: {
66
69
  type: "object",
67
70
  properties: {
@@ -83,15 +86,19 @@ function createCalendarTools(readOptions) {
83
86
  additionalProperties: false
84
87
  },
85
88
  annotations: readAnnotations(),
86
- async execute(query, { signal }) {
87
- const events = await readOptions().events.list(query, { signal });
89
+ async execute(query, executeOptions) {
90
+ const signal = executionSignal(executeOptions);
91
+ const events = await readOptions().events.list(
92
+ query,
93
+ { signal }
94
+ );
88
95
  return { events };
89
96
  }
90
97
  },
91
98
  {
92
99
  name: "calendar_get_event",
93
100
  title: "Get calendar event",
94
- description: "Get one persisted calendar event by its stable event ID.",
101
+ description: "Get one persisted calendar event by its stable event ID. The event may include optional host-selected metadata (JSON object) for agent context; metadata is read-only and is never inferred from FullCalendar extendedProps.",
95
102
  inputSchema: {
96
103
  type: "object",
97
104
  properties: {
@@ -101,8 +108,9 @@ function createCalendarTools(readOptions) {
101
108
  additionalProperties: false
102
109
  },
103
110
  annotations: readAnnotations(),
104
- async execute(input, { signal }) {
111
+ async execute(input, executeOptions) {
105
112
  const { id } = input;
113
+ const signal = executionSignal(executeOptions);
106
114
  const event = await readOptions().events.get(id, { signal });
107
115
  return { event };
108
116
  }
@@ -110,7 +118,7 @@ function createCalendarTools(readOptions) {
110
118
  {
111
119
  name: "calendar_create_event",
112
120
  title: "Create calendar event",
113
- description: "Create and persist a generic calendar event. Times must be ISO 8601 values with explicit offsets. Returns the host-assigned stable event ID.",
121
+ description: "Create and persist a generic calendar event. Times must be ISO 8601 values with explicit offsets. Returns the host-assigned stable event ID. Metadata cannot be supplied on create; only title, start, end, and allDay are accepted.",
114
122
  inputSchema: {
115
123
  type: "object",
116
124
  properties: eventProperties,
@@ -118,8 +126,9 @@ function createCalendarTools(readOptions) {
118
126
  additionalProperties: false
119
127
  },
120
128
  annotations: writeAnnotations(),
121
- async execute(rawInput, { signal }) {
129
+ async execute(rawInput, executeOptions) {
122
130
  const input = rawInput;
131
+ const signal = executionSignal(executeOptions);
123
132
  const options = readOptions();
124
133
  const event = await options.events.create(input, { signal });
125
134
  await options.onEventsChanged();
@@ -129,7 +138,7 @@ function createCalendarTools(readOptions) {
129
138
  {
130
139
  name: "calendar_update_event",
131
140
  title: "Update calendar event",
132
- description: "Update selected fields on one persisted calendar event using its stable event ID. Omitted fields remain unchanged.",
141
+ description: "Update selected fields on one persisted calendar event using its stable event ID. Omitted fields remain unchanged. Metadata cannot be supplied on update; only title, start, end, and allDay may be changed. Host-owned metadata is preserved by the repository.",
133
142
  inputSchema: {
134
143
  type: "object",
135
144
  properties: {
@@ -141,8 +150,9 @@ function createCalendarTools(readOptions) {
141
150
  additionalProperties: false
142
151
  },
143
152
  annotations: writeAnnotations(),
144
- async execute(rawInput, { signal }) {
153
+ async execute(rawInput, executeOptions) {
145
154
  const { id, ...input } = rawInput;
155
+ const signal = executionSignal(executeOptions);
146
156
  const options = readOptions();
147
157
  const event = await options.events.update(id, input, { signal });
148
158
  await options.onEventsChanged();
@@ -162,8 +172,9 @@ function createCalendarTools(readOptions) {
162
172
  additionalProperties: false
163
173
  },
164
174
  annotations: writeAnnotations(),
165
- async execute(input, { signal }) {
175
+ async execute(input, executeOptions) {
166
176
  const { id } = input;
177
+ const signal = executionSignal(executeOptions);
167
178
  const options = readOptions();
168
179
  await options.events.delete(id, { signal });
169
180
  await options.onEventsChanged();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tool-definitions.ts","../src/register-tools.ts","../src/use-fullcalendar-webmcp.ts"],"names":[],"mappings":";;;;;AAUA,IAAM,WAAA,GAAc;AAAA,EAClB,IAAA,EAAM,QAAA;AAAA,EACN,YAAY,EAAC;AAAA,EACb,oBAAA,EAAsB;AACxB,CAAA;AAEA,IAAM,eAAA,GAAkB;AAAA,EACtB,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,SAAA,EAAW,CAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACf;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,WAAA;AAAA,IACR,WAAA,EAAa;AAAA,GACf;AAAA,EACA,GAAA,EAAK;AAAA,IACH,IAAA,EAAM,CAAC,QAAA,EAAU,MAAM,CAAA;AAAA,IACvB,MAAA,EAAQ,WAAA;AAAA,IACR,WAAA,EAAa;AAAA,GACf;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa;AAAA;AAEjB,CAAA;AAEA,SAAS,eAAA,GAA0C;AACjD,EAAA,OAAO,EAAE,YAAA,EAAc,IAAA,EAAM,oBAAA,EAAsB,IAAA,EAAK;AAC1D;AAEA,SAAS,gBAAA,GAA2C;AAClD,EAAA,OAAO,EAAE,YAAA,EAAc,KAAA,EAAO,oBAAA,EAAsB,IAAA,EAAK;AAC3D;AAEO,SAAS,oBACd,WAAA,EAC2B;AAC3B,EAAA,OAAO;AAAA,IACL;AAAA,MACE,IAAA,EAAM,sBAAA;AAAA,MACN,KAAA,EAAO,sBAAA;AAAA,MACP,WAAA,EACE,0LAAA;AAAA,MACF,WAAA,EAAa,WAAA;AAAA,MACb,aAAa,eAAA,EAAgB;AAAA,MAC7B,MAAM,OAAA,GAAU;AACd,QAAA,MAAM,GAAA,GAAM,WAAA,EAAY,CAAE,WAAA,CAAY,SAAS,MAAA,EAAO;AACtD,QAAA,OAAO;AAAA,UACL,GAAA,EAAA,iBAAK,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,UAC5B,eAAA,EAAiB,IAAA,CAAK,cAAA,EAAe,CAAE,iBAAgB,CAAE,QAAA;AAAA,UACzD,oBAAA,EAAsB,GAAA,EAAK,SAAA,CAAU,UAAU,CAAA,IAAK,OAAA;AAAA,UACpD,IAAA,EAAM,GAAA,EAAK,IAAA,CAAK,IAAA,IAAQ,IAAA;AAAA,UACxB,cAAc,GAAA,GACV;AAAA,YACE,KAAA,EAAO,GAAA,CAAI,IAAA,CAAK,WAAA,CAAY,WAAA,EAAY;AAAA,YACxC,GAAA,EAAK,GAAA,CAAI,IAAA,CAAK,SAAA,CAAU,WAAA;AAAY,WACtC,GACA;AAAA,SACN;AAAA,MACF;AAAA,KACF;AAAA,IACA;AAAA,MACE,IAAA,EAAM,sBAAA;AAAA,MACN,KAAA,EAAO,sBAAA;AAAA,MACP,WAAA,EACE,gLAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,KAAA,EAAO;AAAA,YACL,IAAA,EAAM,QAAA;AAAA,YACN,MAAA,EAAQ,WAAA;AAAA,YACR,WAAA,EAAa;AAAA,WACf;AAAA,UACA,GAAA,EAAK;AAAA,YACH,IAAA,EAAM,QAAA;AAAA,YACN,MAAA,EAAQ,WAAA;AAAA,YACR,WAAA,EAAa;AAAA,WACf;AAAA,UACA,IAAA,EAAM;AAAA,YACJ,IAAA,EAAM,QAAA;AAAA,YACN,WAAA,EAAa;AAAA;AACf,SACF;AAAA,QACA,oBAAA,EAAsB;AAAA,OACxB;AAAA,MACA,aAAa,eAAA,EAAgB;AAAA,MAC7B,MAAM,OAAA,CACJ,KAAA,EACA,EAAE,QAAO,EACT;AACA,QAAA,MAAM,MAAA,GAAS,MAAM,WAAA,EAAY,CAAE,OAAO,IAAA,CAAK,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA;AAChE,QAAA,OAAO,EAAE,MAAA,EAAO;AAAA,MAClB;AAAA,KACF;AAAA,IACA;AAAA,MACE,IAAA,EAAM,oBAAA;AAAA,MACN,KAAA,EAAO,oBAAA;AAAA,MACP,WAAA,EAAa,0DAAA;AAAA,MACb,WAAA,EAAa;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,IAAI,EAAE,IAAA,EAAM,UAAU,SAAA,EAAW,CAAA,EAAG,aAAa,kBAAA;AAAmB,SACtE;AAAA,QACA,QAAA,EAAU,CAAC,IAAI,CAAA;AAAA,QACf,oBAAA,EAAsB;AAAA,OACxB;AAAA,MACA,aAAa,eAAA,EAAgB;AAAA,MAC7B,MAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,QAAO,EAAG;AAC/B,QAAA,MAAM,EAAE,IAAG,GAAI,KAAA;AACf,QAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,EAAY,CAAE,OAAO,GAAA,CAAI,EAAA,EAAI,EAAE,MAAA,EAAQ,CAAA;AAC3D,QAAA,OAAO,EAAE,KAAA,EAAM;AAAA,MACjB;AAAA,KACF;AAAA,IACA;AAAA,MACE,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO,uBAAA;AAAA,MACP,WAAA,EACE,8IAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY,eAAA;AAAA,QACZ,QAAA,EAAU,CAAC,OAAA,EAAS,OAAO,CAAA;AAAA,QAC3B,oBAAA,EAAsB;AAAA,OACxB;AAAA,MACA,aAAa,gBAAA,EAAiB;AAAA,MAC9B,MAAM,OAAA,CAAQ,QAAA,EAAU,EAAE,QAAO,EAAG;AAClC,QAAA,MAAM,KAAA,GAAQ,QAAA;AACd,QAAA,MAAM,UAAU,WAAA,EAAY;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAO,KAAA,EAAO,EAAE,QAAQ,CAAA;AAC3D,QAAA,MAAM,QAAQ,eAAA,EAAgB;AAC9B,QAAA,OAAO,EAAE,KAAA,EAAM;AAAA,MACjB;AAAA,KACF;AAAA,IACA;AAAA,MACE,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO,uBAAA;AAAA,MACP,WAAA,EACE,oHAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,IAAI,EAAE,IAAA,EAAM,UAAU,SAAA,EAAW,CAAA,EAAG,aAAa,kBAAA,EAAmB;AAAA,UACpE,GAAG;AAAA,SACL;AAAA,QACA,QAAA,EAAU,CAAC,IAAI,CAAA;AAAA,QACf,aAAA,EAAe,CAAA;AAAA,QACf,oBAAA,EAAsB;AAAA,OACxB;AAAA,MACA,aAAa,gBAAA,EAAiB;AAAA,MAC9B,MAAM,OAAA,CAAQ,QAAA,EAAU,EAAE,QAAO,EAAG;AAClC,QAAA,MAAM,EAAE,EAAA,EAAI,GAAG,KAAA,EAAM,GAAI,QAAA;AAGzB,QAAA,MAAM,UAAU,WAAA,EAAY;AAC5B,QAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,MAAA,CAAO,OAAO,EAAA,EAAI,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA;AAC/D,QAAA,MAAM,QAAQ,eAAA,EAAgB;AAC9B,QAAA,OAAO,EAAE,KAAA,EAAM;AAAA,MACjB;AAAA,KACF;AAAA,IACA;AAAA,MACE,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO,uBAAA;AAAA,MACP,WAAA,EAAa,6DAAA;AAAA,MACb,WAAA,EAAa;AAAA,QACX,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,IAAI,EAAE,IAAA,EAAM,UAAU,SAAA,EAAW,CAAA,EAAG,aAAa,kBAAA;AAAmB,SACtE;AAAA,QACA,QAAA,EAAU,CAAC,IAAI,CAAA;AAAA,QACf,oBAAA,EAAsB;AAAA,OACxB;AAAA,MACA,aAAa,gBAAA,EAAiB;AAAA,MAC9B,MAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,QAAO,EAAG;AAC/B,QAAA,MAAM,EAAE,IAAG,GAAI,KAAA;AACf,QAAA,MAAM,UAAU,WAAA,EAAY;AAC5B,QAAA,MAAM,QAAQ,MAAA,CAAO,MAAA,CAAO,EAAA,EAAI,EAAE,QAAQ,CAAA;AAC1C,QAAA,MAAM,QAAQ,eAAA,EAAgB;AAC9B,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,EAAA,EAAG;AAAA,MAC7B;AAAA;AACF,GACF;AACF;;;AC/LA,IAAM,wBAAA,GAA2B,GAAA;AAE1B,SAAS,kCAAA,CACd,aACA,eAAA,EACA;AACA,EAAA,IAAI,UAAA;AAEJ,EAAA,MAAM,WAAW,YAAY;AAC3B,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAE7B,IAAA,MAAM,eAAe,QAAA,CAAS,YAAA;AAC9B,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,UAAA,GAAa,MAAA,CAAO,UAAA,CAAW,QAAA,EAAU,wBAAwB,CAAA;AACjE,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,YAAA,GAAe,IAAI,eAAA,EAAgB;AACzC,IAAA,MAAM,UAAA,GAAa,MAAM,YAAA,CAAa,KAAA,CAAM,gBAAgB,MAAM,CAAA;AAClE,IAAA,eAAA,CAAgB,iBAAiB,OAAA,EAAS,UAAA,EAAY,EAAE,IAAA,EAAM,MAAM,CAAA;AAEpE,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,QACZ,mBAAA,CAAoB,WAAW,CAAA,CAAE,GAAA;AAAA,UAAI,CAAC,SACpC,YAAA,CAAa,YAAA,CAAa,MAAM,EAAE,MAAA,EAAQ,YAAA,CAAa,MAAA,EAAQ;AAAA;AACjE,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,YAAA,CAAa,KAAA,EAAM;AACnB,MAAA,IAAI,CAAC,gBAAgB,OAAA,EAAS;AAC5B,QAAA,WAAA,EAAY,CAAE,sBAAsB,KAAK,CAAA;AAAA,MAC3C;AAAA,IACF;AAAA,EACF,CAAA;AAEA,EAAA,KAAK,QAAA,EAAS;AAEd,EAAA,eAAA,CAAgB,gBAAA;AAAA,IACd,OAAA;AAAA,IACA,MAAM;AACJ,MAAA,IAAI,UAAA,KAAe,MAAA,EAAW,MAAA,CAAO,YAAA,CAAa,UAAU,CAAA;AAAA,IAC9D,CAAA;AAAA,IACA,EAAE,MAAM,IAAA;AAAK,GACf;AACF;;;ACrCO,SAAS,sBAAsB,OAAA,EAA0C;AAC9E,EAAA,MAAM,aAAA,GAAgB,OAAO,OAAO,CAAA;AACpC,EAAA,aAAA,CAAc,OAAA,GAAU,OAAA;AAExB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,SAAA,GAAY,IAAI,eAAA,EAAgB;AACtC,IAAA,kCAAA;AAAA,MACE,MAAM,aAAA,CAAc,OAAA;AAAA,MACpB,SAAA,CAAU;AAAA,KACZ;AACA,IAAA,OAAO,MAAM,UAAU,KAAA,EAAM;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AACP","file":"index.js","sourcesContent":["/// <reference types=\"webmcp-types\" />\n\nimport type {\n CreateCalendarEventInput,\n FullCalendarWebMCPOptions,\n UpdateCalendarEventInput,\n} from \"./types\";\n\ntype OptionsReader = () => FullCalendarWebMCPOptions;\n\nconst emptySchema = {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n} as const;\n\nconst eventProperties = {\n title: {\n type: \"string\",\n minLength: 1,\n description: \"The human-readable event title.\",\n },\n start: {\n type: \"string\",\n format: \"date-time\",\n description: \"Inclusive event start as ISO 8601 with an explicit offset.\",\n },\n end: {\n type: [\"string\", \"null\"],\n format: \"date-time\",\n description: \"Exclusive event end as ISO 8601 with an explicit offset, or null.\",\n },\n allDay: {\n type: \"boolean\",\n description: \"Whether the event is an all-day event.\",\n },\n} as const;\n\nfunction readAnnotations(): WebMCP.ToolAnnotations {\n return { readOnlyHint: true, untrustedContentHint: true };\n}\n\nfunction writeAnnotations(): WebMCP.ToolAnnotations {\n return { readOnlyHint: false, untrustedContentHint: true };\n}\n\nexport function createCalendarTools(\n readOptions: OptionsReader,\n): WebMCP.ModelContextTool[] {\n return [\n {\n name: \"calendar_get_context\",\n title: \"Get calendar context\",\n description:\n \"Get the current time, resolved browser timezone, FullCalendar timezone, visible date range, and active view. Call this before interpreting relative dates such as Wednesday or tomorrow.\",\n inputSchema: emptySchema,\n annotations: readAnnotations(),\n async execute() {\n const api = readOptions().calendarRef.current?.getApi();\n return {\n now: new Date().toISOString(),\n browserTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n fullCalendarTimeZone: api?.getOption(\"timeZone\") ?? \"local\",\n view: api?.view.type ?? null,\n visibleRange: api\n ? {\n start: api.view.activeStart.toISOString(),\n end: api.view.activeEnd.toISOString(),\n }\n : null,\n };\n },\n },\n {\n name: \"calendar_list_events\",\n title: \"List calendar events\",\n description:\n \"List persisted calendar events, optionally filtered by an inclusive start, exclusive end, or case-insensitive title text. Use an end boundary one day after the requested day.\",\n inputSchema: {\n type: \"object\",\n properties: {\n start: {\n type: \"string\",\n format: \"date-time\",\n description: \"Inclusive ISO 8601 lower bound.\",\n },\n end: {\n type: \"string\",\n format: \"date-time\",\n description: \"Exclusive ISO 8601 upper bound.\",\n },\n text: {\n type: \"string\",\n description: \"Optional case-insensitive title substring.\",\n },\n },\n additionalProperties: false,\n },\n annotations: readAnnotations(),\n async execute(\n query: { start?: string; end?: string; text?: string },\n { signal },\n ) {\n const events = await readOptions().events.list(query, { signal });\n return { events };\n },\n },\n {\n name: \"calendar_get_event\",\n title: \"Get calendar event\",\n description: \"Get one persisted calendar event by its stable event ID.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", minLength: 1, description: \"Stable event ID.\" },\n },\n required: [\"id\"],\n additionalProperties: false,\n },\n annotations: readAnnotations(),\n async execute(input, { signal }) {\n const { id } = input as { id: string };\n const event = await readOptions().events.get(id, { signal });\n return { event };\n },\n },\n {\n name: \"calendar_create_event\",\n title: \"Create calendar event\",\n description:\n \"Create and persist a generic calendar event. Times must be ISO 8601 values with explicit offsets. Returns the host-assigned stable event ID.\",\n inputSchema: {\n type: \"object\",\n properties: eventProperties,\n required: [\"title\", \"start\"],\n additionalProperties: false,\n },\n annotations: writeAnnotations(),\n async execute(rawInput, { signal }) {\n const input = rawInput as unknown as CreateCalendarEventInput;\n const options = readOptions();\n const event = await options.events.create(input, { signal });\n await options.onEventsChanged();\n return { event };\n },\n },\n {\n name: \"calendar_update_event\",\n title: \"Update calendar event\",\n description:\n \"Update selected fields on one persisted calendar event using its stable event ID. Omitted fields remain unchanged.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", minLength: 1, description: \"Stable event ID.\" },\n ...eventProperties,\n },\n required: [\"id\"],\n minProperties: 2,\n additionalProperties: false,\n },\n annotations: writeAnnotations(),\n async execute(rawInput, { signal }) {\n const { id, ...input } = rawInput as unknown as UpdateCalendarEventInput & {\n id: string;\n };\n const options = readOptions();\n const event = await options.events.update(id, input, { signal });\n await options.onEventsChanged();\n return { event };\n },\n },\n {\n name: \"calendar_delete_event\",\n title: \"Delete calendar event\",\n description: \"Delete one persisted calendar event by its stable event ID.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", minLength: 1, description: \"Stable event ID.\" },\n },\n required: [\"id\"],\n additionalProperties: false,\n },\n annotations: writeAnnotations(),\n async execute(input, { signal }) {\n const { id } = input as { id: string };\n const options = readOptions();\n await options.events.delete(id, { signal });\n await options.onEventsChanged();\n return { deleted: true, id };\n },\n },\n ];\n}\n","import { createCalendarTools } from \"./tool-definitions\";\nimport type { FullCalendarWebMCPOptions } from \"./types\";\n\nconst RUNTIME_POLL_INTERVAL_MS = 250;\n\nexport function registerCalendarToolsWhenAvailable(\n readOptions: () => FullCalendarWebMCPOptions,\n lifecycleSignal: AbortSignal,\n) {\n let retryTimer: number | undefined;\n\n const register = async () => {\n if (lifecycleSignal.aborted) return;\n\n const modelContext = document.modelContext;\n if (!modelContext) {\n retryTimer = window.setTimeout(register, RUNTIME_POLL_INTERVAL_MS);\n return;\n }\n\n const registration = new AbortController();\n const unregister = () => registration.abort(lifecycleSignal.reason);\n lifecycleSignal.addEventListener(\"abort\", unregister, { once: true });\n\n try {\n await Promise.all(\n createCalendarTools(readOptions).map((tool) =>\n modelContext.registerTool(tool, { signal: registration.signal }),\n ),\n );\n } catch (error) {\n registration.abort();\n if (!lifecycleSignal.aborted) {\n readOptions().onRegistrationError?.(error);\n }\n }\n };\n\n void register();\n\n lifecycleSignal.addEventListener(\n \"abort\",\n () => {\n if (retryTimer !== undefined) window.clearTimeout(retryTimer);\n },\n { once: true },\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport { registerCalendarToolsWhenAvailable } from \"./register-tools\";\nimport type { FullCalendarWebMCPOptions } from \"./types\";\n\n/**\n * Primary React hook integrating FullCalendar with the browser WebMCP model context.\n *\n * Provides safe client-side registration, unmount cleanup, and continuous\n * binding to host persistence callbacks without re-registering tools across renders.\n */\nexport function useFullCalendarWebMCP(options: FullCalendarWebMCPOptions): void {\n const latestOptions = useRef(options);\n latestOptions.current = options;\n\n useEffect(() => {\n const lifecycle = new AbortController();\n registerCalendarToolsWhenAvailable(\n () => latestOptions.current,\n lifecycle.signal,\n );\n return () => lifecycle.abort();\n }, []);\n}\n"]}
1
+ {"version":3,"sources":["../src/tool-definitions.ts","../src/register-tools.ts","../src/use-fullcalendar-webmcp.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/// <reference types=\"webmcp-types\" />\n\nimport type {\n CreateCalendarEventInput,\n FullCalendarWebMCPOptions,\n UpdateCalendarEventInput,\n} from \"./types\";\n\ntype OptionsReader = () => FullCalendarWebMCPOptions;\n\nconst emptySchema = {\n type: \"object\",\n properties: {},\n additionalProperties: false,\n} as const;\n\nconst eventProperties = {\n title: {\n type: \"string\",\n minLength: 1,\n description: \"The human-readable event title.\",\n },\n start: {\n type: \"string\",\n format: \"date-time\",\n description: \"Inclusive event start as ISO 8601 with an explicit offset.\",\n },\n end: {\n type: [\"string\", \"null\"],\n format: \"date-time\",\n description: \"Exclusive event end as ISO 8601 with an explicit offset, or null.\",\n },\n allDay: {\n type: \"boolean\",\n description: \"Whether the event is an all-day event.\",\n },\n} as const;\n\nfunction readAnnotations(): WebMCP.ToolAnnotations {\n return { readOnlyHint: true, untrustedContentHint: true };\n}\n\nfunction writeAnnotations(): WebMCP.ToolAnnotations {\n return { readOnlyHint: false, untrustedContentHint: true };\n}\n\n/**\n * WebMCP imperative execute steps always pass ToolExecuteCallbackOptions with a\n * fresh AbortSignal. Some agent shims still call execute(input) with one argument.\n * Never require-destructure options; forward signal when present.\n */\nfunction executionSignal(\n executeOptions: WebMCP.ToolExecuteCallbackOptions | undefined,\n): AbortSignal | undefined {\n return executeOptions?.signal;\n}\n\nexport function createCalendarTools(\n readOptions: OptionsReader,\n): WebMCP.ModelContextTool[] {\n return [\n {\n name: \"calendar_get_context\",\n title: \"Get calendar context\",\n description:\n \"Get the current time, resolved browser timezone, FullCalendar timezone, visible date range, and active view. Call this before interpreting relative dates such as Wednesday or tomorrow.\",\n inputSchema: emptySchema,\n annotations: readAnnotations(),\n async execute() {\n const api = readOptions().calendarRef.current?.getApi();\n return {\n now: new Date().toISOString(),\n browserTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n fullCalendarTimeZone: api?.getOption(\"timeZone\") ?? \"local\",\n view: api?.view.type ?? null,\n visibleRange: api\n ? {\n start: api.view.activeStart.toISOString(),\n end: api.view.activeEnd.toISOString(),\n }\n : null,\n };\n },\n },\n {\n name: \"calendar_list_events\",\n title: \"List calendar events\",\n description:\n \"List persisted calendar events, optionally filtered by an inclusive start, exclusive end, or case-insensitive title text. Use an end boundary one day after the requested day. Events may include optional host-selected metadata (JSON object) for agent context; Protocol Tooling does not automatically expose FullCalendar extendedProps.\",\n inputSchema: {\n type: \"object\",\n properties: {\n start: {\n type: \"string\",\n format: \"date-time\",\n description: \"Inclusive ISO 8601 lower bound.\",\n },\n end: {\n type: \"string\",\n format: \"date-time\",\n description: \"Exclusive ISO 8601 upper bound.\",\n },\n text: {\n type: \"string\",\n description: \"Optional case-insensitive title substring.\",\n },\n },\n additionalProperties: false,\n },\n annotations: readAnnotations(),\n async execute(query, executeOptions) {\n const signal = executionSignal(executeOptions);\n const events = await readOptions().events.list(\n query as { start?: string; end?: string; text?: string },\n { signal },\n );\n return { events };\n },\n },\n {\n name: \"calendar_get_event\",\n title: \"Get calendar event\",\n description:\n \"Get one persisted calendar event by its stable event ID. The event may include optional host-selected metadata (JSON object) for agent context; metadata is read-only and is never inferred from FullCalendar extendedProps.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", minLength: 1, description: \"Stable event ID.\" },\n },\n required: [\"id\"],\n additionalProperties: false,\n },\n annotations: readAnnotations(),\n async execute(input, executeOptions) {\n const { id } = input as { id: string };\n const signal = executionSignal(executeOptions);\n const event = await readOptions().events.get(id, { signal });\n return { event };\n },\n },\n {\n name: \"calendar_create_event\",\n title: \"Create calendar event\",\n description:\n \"Create and persist a generic calendar event. Times must be ISO 8601 values with explicit offsets. Returns the host-assigned stable event ID. Metadata cannot be supplied on create; only title, start, end, and allDay are accepted.\",\n inputSchema: {\n type: \"object\",\n properties: eventProperties,\n required: [\"title\", \"start\"],\n additionalProperties: false,\n },\n annotations: writeAnnotations(),\n async execute(rawInput, executeOptions) {\n const input = rawInput as unknown as CreateCalendarEventInput;\n const signal = executionSignal(executeOptions);\n const options = readOptions();\n const event = await options.events.create(input, { signal });\n await options.onEventsChanged();\n return { event };\n },\n },\n {\n name: \"calendar_update_event\",\n title: \"Update calendar event\",\n description:\n \"Update selected fields on one persisted calendar event using its stable event ID. Omitted fields remain unchanged. Metadata cannot be supplied on update; only title, start, end, and allDay may be changed. Host-owned metadata is preserved by the repository.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", minLength: 1, description: \"Stable event ID.\" },\n ...eventProperties,\n },\n required: [\"id\"],\n minProperties: 2,\n additionalProperties: false,\n },\n annotations: writeAnnotations(),\n async execute(rawInput, executeOptions) {\n const { id, ...input } = rawInput as unknown as UpdateCalendarEventInput & {\n id: string;\n };\n const signal = executionSignal(executeOptions);\n const options = readOptions();\n const event = await options.events.update(id, input, { signal });\n await options.onEventsChanged();\n return { event };\n },\n },\n {\n name: \"calendar_delete_event\",\n title: \"Delete calendar event\",\n description: \"Delete one persisted calendar event by its stable event ID.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", minLength: 1, description: \"Stable event ID.\" },\n },\n required: [\"id\"],\n additionalProperties: false,\n },\n annotations: writeAnnotations(),\n async execute(input, executeOptions) {\n const { id } = input as { id: string };\n const signal = executionSignal(executeOptions);\n const options = readOptions();\n await options.events.delete(id, { signal });\n await options.onEventsChanged();\n return { deleted: true, id };\n },\n },\n ];\n}\n","import { createCalendarTools } from \"./tool-definitions\";\nimport type { FullCalendarWebMCPOptions } from \"./types\";\n\nconst RUNTIME_POLL_INTERVAL_MS = 250;\n\nexport function registerCalendarToolsWhenAvailable(\n readOptions: () => FullCalendarWebMCPOptions,\n lifecycleSignal: AbortSignal,\n) {\n let retryTimer: number | undefined;\n\n const register = async () => {\n if (lifecycleSignal.aborted) return;\n\n const modelContext = document.modelContext;\n if (!modelContext) {\n retryTimer = window.setTimeout(register, RUNTIME_POLL_INTERVAL_MS);\n return;\n }\n\n const registration = new AbortController();\n const unregister = () => registration.abort(lifecycleSignal.reason);\n lifecycleSignal.addEventListener(\"abort\", unregister, { once: true });\n\n try {\n await Promise.all(\n createCalendarTools(readOptions).map((tool) =>\n modelContext.registerTool(tool, { signal: registration.signal }),\n ),\n );\n } catch (error) {\n registration.abort();\n if (!lifecycleSignal.aborted) {\n readOptions().onRegistrationError?.(error);\n }\n }\n };\n\n void register();\n\n lifecycleSignal.addEventListener(\n \"abort\",\n () => {\n if (retryTimer !== undefined) window.clearTimeout(retryTimer);\n },\n { once: true },\n );\n}\n","import { useEffect, useRef } from \"react\";\nimport { registerCalendarToolsWhenAvailable } from \"./register-tools\";\nimport type { FullCalendarWebMCPOptions } from \"./types\";\n\n/**\n * Primary React hook integrating FullCalendar with the browser WebMCP model context.\n *\n * Provides safe client-side registration, unmount cleanup, and continuous\n * binding to host persistence callbacks without re-registering tools across renders.\n */\nexport function useFullCalendarWebMCP(options: FullCalendarWebMCPOptions): void {\n const latestOptions = useRef(options);\n latestOptions.current = options;\n\n useEffect(() => {\n const lifecycle = new AbortController();\n registerCalendarToolsWhenAvailable(\n () => latestOptions.current,\n lifecycle.signal,\n );\n return () => lifecycle.abort();\n }, []);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protocoltooling/fullcalendar",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Add WebMCP tools to FullCalendar React applications.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -55,7 +55,8 @@
55
55
  "test": "vitest run",
56
56
  "test:watch": "vitest",
57
57
  "test:types": "tsc --noEmit -p tsconfig.json",
58
- "test:pack": "node ./scripts/test-pack.js"
58
+ "test:pack": "node ./scripts/test-pack.js",
59
+ "test:pack:smoke": "npm run build:lib && npm pack && node ./scripts/smoke-packed-tools.mjs protocoltooling-fullcalendar-$npm_package_version.tgz"
59
60
  },
60
61
  "peerDependencies": {
61
62
  "@fullcalendar/react": "^6.0.0 || ^7.0.0",