@chronary/toolkit 1.0.1 → 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.
package/dist/mcp.js CHANGED
@@ -6,72 +6,90 @@ import { Chronary } from "@chronary/sdk";
6
6
 
7
7
  // src/schemas.ts
8
8
  import { z } from "zod";
9
+ var WEBHOOK_EVENT_TYPES = [
10
+ "agent.created",
11
+ "agent.updated",
12
+ "event.created",
13
+ "event.updated",
14
+ "event.deleted",
15
+ "event.started",
16
+ "event.ended",
17
+ "event.reminder",
18
+ "event.hold_created",
19
+ "event.hold_expired",
20
+ "event.hold_released",
21
+ "event.hold_confirmed",
22
+ "proposal.created",
23
+ "proposal.responded",
24
+ "proposal.confirmed",
25
+ "proposal.expired",
26
+ "proposal.cancelled",
27
+ "webhook.deactivated"
28
+ ];
29
+ var WEBHOOK_DELIVERY_STATUSES = ["pending", "delivered", "failed"];
9
30
  var ListCalendarsSchema = z.object({
10
- agent_id: z.string().optional().describe("Filter calendars by agent ID"),
11
- include: z.enum(["all"]).optional().describe('Set to "all" to include soft-deleted calendars'),
12
- limit: z.number().int().min(1).max(200).optional().describe("Max results per page (default 50)"),
13
- offset: z.number().int().min(0).optional().describe("Pagination offset (default 0)")
31
+ include: z.enum(["all"]).optional().describe('Pass "all" to include calendars across all agents (org keys only)'),
32
+ limit: z.number().int().min(1).max(200).default(50).describe("Max results to return"),
33
+ offset: z.number().int().min(0).default(0).describe("Pagination offset")
14
34
  });
15
35
  var GetCalendarSchema = z.object({
16
- calendar_id: z.string().describe("The calendar ID to retrieve")
36
+ calendar_id: z.string().describe("Calendar ID to fetch")
17
37
  });
18
38
  var CreateCalendarSchema = z.object({
19
- name: z.string().describe("Calendar name"),
20
- timezone: z.string().describe('IANA timezone (e.g., "America/New_York")'),
21
- agent_id: z.string().optional().describe("Agent ID to associate the calendar with"),
22
- default_reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("Default reminder offsets in minutes before start, inherited by events that don't set their own (e.g. [10, 1440]). null/omit = system default (10 min); [] = no reminders. Max 5, each 1\u201340320."),
23
- metadata: z.record(z.string(), z.unknown()).optional().describe("Arbitrary key-value metadata")
39
+ name: z.string().min(1).max(255).describe("Calendar name"),
40
+ agent_id: z.string().optional().describe("Agent ID to own this calendar (omit for org-level)"),
41
+ timezone: z.string().min(1).describe("IANA timezone (e.g. America/New_York)"),
42
+ default_reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("Default reminder offsets in minutes before start, inherited by events on this calendar that don't set their own. Omit or null to use the system default (10 min); [] for no reminders.")
24
43
  });
25
44
  var UpdateCalendarSchema = z.object({
26
- calendar_id: z.string().describe("The calendar ID to update"),
27
- name: z.string().optional().describe("New calendar name"),
28
- timezone: z.string().optional().describe("New IANA timezone"),
29
- default_reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("New default reminder offsets in minutes before start. null = system default (10 min); [] = no reminders. Max 5, each 1\u201340320."),
30
- metadata: z.record(z.string(), z.unknown()).optional().describe("Updated metadata")
45
+ calendar_id: z.string().describe("Calendar ID to update"),
46
+ name: z.string().min(1).max(255).optional().describe("New calendar name"),
47
+ timezone: z.string().min(1).optional().describe("New IANA timezone (e.g. America/New_York)"),
48
+ agent_status: z.enum(["idle", "working", "waiting", "error"]).optional().describe("Owning agent's status"),
49
+ default_reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("Default reminder offsets in minutes; null for system default, [] for none"),
50
+ metadata: z.record(z.string(), z.unknown()).optional().describe("Arbitrary metadata (max 16KB)")
31
51
  });
32
52
  var DeleteCalendarSchema = z.object({
33
- calendar_id: z.string().describe("The calendar ID to delete")
53
+ calendar_id: z.string().describe("Calendar ID to delete")
34
54
  });
35
55
  var ListEventsSchema = z.object({
36
- calendar_id: z.string().optional().describe("Calendar ID to list events from (provide this or agent_id)"),
37
- agent_id: z.string().optional().describe("Agent ID to list events for (provide this or calendar_id)"),
38
- start_after: z.string().optional().describe("Only events starting after this ISO 8601 datetime"),
39
- start_before: z.string().optional().describe("Only events starting before this ISO 8601 datetime"),
40
- status: z.enum(["confirmed", "tentative", "cancelled"]).optional().describe("Filter by event status"),
41
- source: z.enum(["internal", "external_ical"]).optional().describe("Filter by event source"),
42
- limit: z.number().int().min(1).max(200).optional().describe("Max results per page (default 50)"),
43
- offset: z.number().int().min(0).optional().describe("Pagination offset (default 0)")
56
+ calendar_id: z.string().describe("Calendar ID to list events from"),
57
+ start_after: z.string().datetime().optional().describe("Filter events starting after this time"),
58
+ start_before: z.string().datetime().optional().describe("Filter events starting before this time"),
59
+ limit: z.number().int().min(1).max(200).default(50).describe("Max results to return"),
60
+ offset: z.number().int().min(0).default(0).describe("Pagination offset")
44
61
  });
45
62
  var GetEventSchema = z.object({
46
- calendar_id: z.string().describe("Calendar ID the event belongs to"),
47
- event_id: z.string().describe("The event ID to retrieve")
63
+ event_id: z.string().describe("Event ID to retrieve"),
64
+ calendar_id: z.string().describe("Calendar ID that owns the event. Required \u2014 the SDK is calendar-scoped (unlike the hosted MCP, which can resolve the calendar from event_id).")
48
65
  });
49
66
  var CreateEventSchema = z.object({
50
- calendar_id: z.string().describe("Calendar ID to create the event on"),
51
- title: z.string().describe("Event title"),
52
- start_time: z.string().describe("Start time in ISO 8601 format"),
53
- end_time: z.string().describe("End time in ISO 8601 format"),
54
- description: z.string().optional().describe("Event description"),
55
- all_day: z.boolean().optional().describe("Whether this is an all-day event"),
56
- status: z.enum(["confirmed", "tentative", "cancelled"]).optional().describe('Event status (default "confirmed")'),
57
- reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("Reminder offsets in minutes before start (e.g. [10, 1440]). Each fires an event.reminder webhook. null/omit = inherit calendar default (then 10 min); [] = no reminders. Max 5, each 1\u201340320."),
58
- metadata: z.record(z.string(), z.unknown()).optional().describe("Arbitrary key-value metadata")
67
+ calendar_id: z.string().describe("Calendar ID to add the event to"),
68
+ title: z.string().min(1).max(500).describe("Event title"),
69
+ start_time: z.string().datetime().describe("Start time (ISO 8601)"),
70
+ end_time: z.string().datetime().describe("End time (ISO 8601)"),
71
+ description: z.string().optional().describe("Optional event description"),
72
+ all_day: z.boolean().default(false).describe("Whether this is an all-day event"),
73
+ status: z.enum(["confirmed", "tentative", "hold"]).optional().describe('Event status. "hold" creates a tentative reservation that auto-expires at hold_expires_at. Defaults to "confirmed".'),
74
+ reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("Reminder offsets in minutes before start_time (e.g. [10, 1440]). Each fires an event.reminder webhook and shows as an alarm in the iCal feed. Omit or null to inherit the calendar default (then the system default of 10 min); [] for no reminders."),
75
+ hold_expires_at: z.string().datetime().optional().describe('Required when status="hold". ISO 8601 timestamp 30s-15min in the future. Auto-releases the hold when reached.'),
76
+ hold_priority: z.number().int().min(0).max(100).optional().describe('Only valid with status="hold". Higher-priority overlapping holds pre-empt lower-priority ones. Defaults to 0.')
59
77
  });
60
78
  var UpdateEventSchema = z.object({
61
- calendar_id: z.string().describe("Calendar ID the event belongs to"),
62
- event_id: z.string().describe("The event ID to update"),
63
- title: z.string().optional().describe("New event title"),
64
- description: z.string().nullable().optional().describe("New description (null to clear)"),
65
- start_time: z.string().optional().describe("New start time in ISO 8601 format"),
66
- end_time: z.string().optional().describe("New end time in ISO 8601 format"),
79
+ event_id: z.string().describe("Event ID to update"),
80
+ calendar_id: z.string().describe("Calendar ID that owns the event. Required \u2014 the SDK is calendar-scoped (unlike the hosted MCP, which can resolve the calendar from event_id)."),
81
+ title: z.string().min(1).max(500).optional().describe("New event title"),
82
+ description: z.string().nullable().optional().describe("New description, or null to clear it"),
83
+ start_time: z.string().datetime().optional().describe("New start time (ISO 8601)"),
84
+ end_time: z.string().datetime().optional().describe("New end time (ISO 8601)"),
67
85
  all_day: z.boolean().optional().describe("Whether this is an all-day event"),
68
86
  status: z.enum(["confirmed", "tentative", "cancelled"]).optional().describe("New event status"),
69
- reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("New reminder offsets in minutes before start. null = inherit calendar default; [] = no reminders. Max 5, each 1\u201340320."),
70
- metadata: z.record(z.string(), z.unknown()).optional().describe("Updated metadata")
87
+ metadata: z.record(z.string(), z.unknown()).optional().describe("Replacement metadata object"),
88
+ reminders: z.array(z.number().int().min(1).max(40320)).max(5).nullable().optional().describe("Reminder offsets in minutes before start_time. Omit to leave unchanged, null to inherit the calendar default, [] for no reminders.")
71
89
  });
72
90
  var CancelEventSchema = z.object({
73
- calendar_id: z.string().describe("Calendar ID that owns the event"),
74
- event_id: z.string().describe("Event ID to cancel")
91
+ event_id: z.string().describe("Event ID to cancel"),
92
+ calendar_id: z.string().describe("Calendar ID that owns the event. Required \u2014 the SDK is calendar-scoped (unlike the hosted MCP, which can resolve the calendar from event_id).")
75
93
  });
76
94
  var ConfirmEventSchema = z.object({
77
95
  event_id: z.string().describe("Event ID of the hold to confirm")
@@ -82,14 +100,13 @@ var ReleaseEventSchema = z.object({
82
100
  var CreateAgentSchema = z.object({
83
101
  name: z.string().min(1).max(255).describe("Display name for the agent"),
84
102
  type: z.enum(["ai", "human", "resource"]).describe("Agent type"),
85
- description: z.string().optional().describe("Optional description"),
86
- metadata: z.record(z.string(), z.unknown()).optional().describe("Arbitrary key-value metadata")
103
+ description: z.string().optional().describe("Optional description")
87
104
  });
88
105
  var ListAgentsSchema = z.object({
89
106
  type: z.enum(["ai", "human", "resource"]).optional().describe("Filter by agent type"),
90
107
  status: z.enum(["active", "paused", "decommissioned"]).optional().describe("Filter by status"),
91
- limit: z.number().int().min(1).max(200).optional().describe("Max results per page (default 50)"),
92
- offset: z.number().int().min(0).optional().describe("Pagination offset (default 0)")
108
+ limit: z.number().int().min(1).max(200).default(50).describe("Max results to return"),
109
+ offset: z.number().int().min(0).default(0).describe("Pagination offset")
93
110
  });
94
111
  var GetAgentSchema = z.object({
95
112
  agent_id: z.string().describe("Agent ID to fetch")
@@ -106,27 +123,32 @@ var DeleteAgentSchema = z.object({
106
123
  });
107
124
  var GetAvailabilitySchema = z.object({
108
125
  agent_id: z.string().describe("Agent ID to check availability for"),
109
- start: z.string().describe("Range start (ISO 8601)"),
110
- end: z.string().describe("Range end (ISO 8601)"),
111
- slot_duration: z.enum(["15m", "30m", "45m", "1h", "2h"]).optional().describe('Minimum slot duration required (default "30m")'),
112
- include_busy: z.boolean().optional().describe("Include busy blocks in response")
126
+ start: z.string().datetime().optional().describe("Range start (ISO 8601). Alias: start_time."),
127
+ end: z.string().datetime().optional().describe("Range end (ISO 8601). Alias: end_time."),
128
+ start_time: z.string().datetime().optional().describe("Alias for `start` (matches REST events naming)."),
129
+ end_time: z.string().datetime().optional().describe("Alias for `end` (matches REST events naming)."),
130
+ slot_duration: z.enum(["15m", "30m", "45m", "1h", "2h"]).default("30m").describe("Minimum slot duration required \u2014 only free blocks at least this long are returned"),
131
+ include_busy: z.boolean().default(false).describe("Include busy blocks in response")
113
132
  });
114
133
  var FindMeetingTimeSchema = z.object({
115
- agents: z.array(z.string()).min(1).describe("Array of agent IDs to find common free time for. All agents must be free during the returned slots."),
116
- start: z.string().describe("Search range start (ISO 8601)"),
117
- end: z.string().describe("Search range end (ISO 8601)"),
118
- slot_duration: z.enum(["15m", "30m", "45m", "1h", "2h"]).optional().describe('Minimum slot duration required (default "30m")'),
134
+ agents: z.array(z.string()).min(1).optional().describe("Array of agent IDs to find common free time for. All agents must be free during the returned slots. Alias: agent_ids."),
135
+ agent_ids: z.array(z.string()).min(1).optional().describe("Alias for `agents` (matches REST/scheduling-proposal naming)."),
136
+ start: z.string().datetime().optional().describe("Search range start (ISO 8601). Alias: start_time."),
137
+ end: z.string().datetime().optional().describe("Search range end (ISO 8601). Alias: end_time."),
138
+ start_time: z.string().datetime().optional().describe("Alias for `start` (matches REST events naming)."),
139
+ end_time: z.string().datetime().optional().describe("Alias for `end` (matches REST events naming)."),
140
+ slot_duration: z.enum(["15m", "30m", "45m", "1h", "2h"]).default("30m").describe("Minimum slot duration required \u2014 only free blocks at least this long are returned"),
119
141
  calendars: z.array(z.string()).optional().describe("Additional shared calendar IDs to treat as busy"),
120
- include_busy: z.boolean().optional().describe("Include per-agent busy blocks in response")
142
+ include_busy: z.boolean().default(false).describe("Include per-agent busy blocks in response")
121
143
  });
122
144
  var GetCalendarContextSchema = z.object({
123
145
  calendar_id: z.string().describe("Calendar ID")
124
146
  });
125
147
  var proposalSlotSchema = z.object({
126
- start_time: z.string().describe("Slot start (ISO 8601)"),
127
- end_time: z.string().describe("Slot end (ISO 8601)"),
128
- weight: z.number().min(0).max(10).optional().describe("Preference weight (default 1.0)"),
129
- calendar_id: z.string().optional().describe("Override calendar for this slot")
148
+ start_time: z.string().datetime(),
149
+ end_time: z.string().datetime(),
150
+ weight: z.number().min(0).max(10).default(1).optional(),
151
+ calendar_id: z.string().optional()
130
152
  });
131
153
  var CreateProposalSchema = z.object({
132
154
  title: z.string().min(1).max(500).describe("Short description of what the meeting is about"),
@@ -135,7 +157,7 @@ var CreateProposalSchema = z.object({
135
157
  participant_agent_ids: z.array(z.string()).min(1).max(50).describe("Agent IDs invited to respond"),
136
158
  calendar_id: z.string().describe("Calendar the resolved event will be created on"),
137
159
  slots: z.array(proposalSlotSchema).min(1).max(20).describe("Candidate time slots (up to 20)"),
138
- expires_at: z.string().optional().describe("Auto-cancel cutoff if unresolved (ISO 8601)")
160
+ expires_at: z.string().datetime().optional().describe("Auto-cancel cutoff if unresolved")
139
161
  });
140
162
  var ListProposalsSchema = z.object({
141
163
  status: z.enum(["pending", "confirmed", "expired", "cancelled"]).optional().describe("Filter by proposal status"),
@@ -160,9 +182,10 @@ var ResolveProposalSchema = z.object({
160
182
  var CancelProposalSchema = z.object({
161
183
  proposal_id: z.string().describe("Proposal to cancel")
162
184
  });
185
+ var timeOfDay = z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "must be HH:MM in 24-hour time");
163
186
  var workingHoursDaySchema = z.object({
164
- start: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "must be HH:MM in 24-hour time"),
165
- end: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "must be HH:MM in 24-hour time")
187
+ start: timeOfDay,
188
+ end: timeOfDay
166
189
  });
167
190
  var workingHoursSchema = z.object({
168
191
  mon: workingHoursDaySchema.optional(),
@@ -175,10 +198,10 @@ var workingHoursSchema = z.object({
175
198
  }).nullable();
176
199
  var SetAvailabilityRulesSchema = z.object({
177
200
  calendar_id: z.string().describe("Calendar to configure"),
178
- buffer_before_minutes: z.number().int().min(0).max(120).optional().describe("Minutes of buffer before each event (0\u2013120)"),
179
- buffer_after_minutes: z.number().int().min(0).max(120).optional().describe("Minutes of buffer after each event (0\u2013120)"),
180
- working_hours: workingHoursSchema.optional().describe("Per-day working hours map in the calendar's timezone; omit keys for off-days. Pass null to remove any working-hours constraint."),
181
- timezone: z.string().min(1).max(64).optional().describe("IANA timezone used to interpret working_hours (e.g. America/New_York)")
201
+ buffer_before_minutes: z.number().int().min(0).max(120).default(0).describe("Minutes of buffer before each event (0\u2013120)"),
202
+ buffer_after_minutes: z.number().int().min(0).max(120).default(0).describe("Minutes of buffer after each event (0\u2013120)"),
203
+ working_hours: workingHoursSchema.default(null).describe("Per-day working hours map in the calendar's timezone; omit keys for off-days. Pass null to remove any working-hours constraint."),
204
+ timezone: z.string().min(1).max(64).default("UTC").describe("IANA timezone used to interpret working_hours (e.g. America/New_York)")
182
205
  });
183
206
  var GetAvailabilityRulesSchema = z.object({
184
207
  calendar_id: z.string().describe("Calendar to read")
@@ -195,8 +218,8 @@ var RevokeScopedKeySchema = z.object({
195
218
  key_id: z.string().describe("ID of the scoped key to revoke")
196
219
  });
197
220
  var GetAuditLogSchema = z.object({
198
- from: z.string().optional().describe("Start of the window (ISO 8601). Silently clamped to the plan retention window if older."),
199
- to: z.string().optional().describe("End of the window (ISO 8601)"),
221
+ from: z.string().datetime({ offset: true }).optional().describe("Start of the window (ISO 8601). Silently clamped to the plan retention window if older."),
222
+ to: z.string().datetime({ offset: true }).optional().describe("End of the window (ISO 8601)"),
200
223
  action: z.string().min(1).max(64).optional().describe("Filter by action name (e.g. event.created)"),
201
224
  actor_key_prefix: z.string().min(1).max(32).optional().describe("Filter by the API key prefix that performed the action"),
202
225
  cursor: z.string().min(1).max(256).optional().describe("Opaque pagination cursor from a previous response"),
@@ -206,33 +229,40 @@ var AcceptTermsSchema = z.object({
206
229
  tos_version: z.string().min(1).describe("The terms-of-service version to accept; must match the current version")
207
230
  });
208
231
  var ListWebhooksSchema = z.object({
209
- limit: z.number().int().min(1).max(100).optional().describe("Max results per page (default 20)"),
210
- offset: z.number().int().min(0).optional().describe("Pagination offset (default 0)")
232
+ limit: z.number().int().min(1).max(100).default(20).describe("Max results to return"),
233
+ offset: z.number().int().min(0).default(0).describe("Pagination offset")
211
234
  });
212
235
  var GetWebhookSchema = z.object({
213
- webhook_id: z.string().describe("The webhook ID to retrieve")
236
+ webhook_id: z.string().describe("Webhook subscription to fetch")
214
237
  });
215
238
  var CreateWebhookSchema = z.object({
216
- url: z.string().describe("HTTPS URL to receive webhook payloads"),
217
- events: z.array(z.string()).describe('Event types to subscribe to (e.g., ["event.created", "event.updated"])')
239
+ url: z.string().url().describe("HTTPS endpoint that will receive event deliveries"),
240
+ events: z.array(z.enum(WEBHOOK_EVENT_TYPES)).min(1).describe("Event types to subscribe to")
218
241
  });
219
242
  var UpdateWebhookSchema = z.object({
220
- webhook_id: z.string().describe("The webhook ID to update"),
221
- url: z.string().optional().describe("New webhook URL"),
222
- events: z.array(z.string()).optional().describe("New event type subscriptions"),
223
- active: z.boolean().optional().describe("Enable or disable the webhook")
243
+ webhook_id: z.string().describe("Webhook subscription to update"),
244
+ url: z.string().url().optional().describe("New HTTPS delivery endpoint"),
245
+ events: z.array(z.enum(WEBHOOK_EVENT_TYPES)).min(1).optional().describe("Replacement set of event types to subscribe to"),
246
+ active: z.boolean().optional().describe("Set false to pause deliveries, true to resume")
224
247
  });
225
248
  var DeleteWebhookSchema = z.object({
226
- webhook_id: z.string().describe("The webhook ID to delete")
249
+ webhook_id: z.string().describe("Webhook subscription to delete")
250
+ });
251
+ var ListWebhookDeliveriesSchema = z.object({
252
+ webhook_id: z.string().describe("Webhook subscription whose deliveries to list"),
253
+ limit: z.number().int().min(1).max(100).default(20).describe("Max results to return"),
254
+ offset: z.number().int().min(0).default(0).describe("Pagination offset"),
255
+ status: z.enum(WEBHOOK_DELIVERY_STATUSES).optional().describe("Filter to a single delivery status"),
256
+ include_payload: z.boolean().optional().describe("Include the full event payload sent on each delivery")
227
257
  });
228
258
  var ListICalSubscriptionsSchema = z.object({
229
- agent_id: z.string().describe("Agent ID to list subscriptions for"),
259
+ agent_id: z.string().describe("Agent ID whose iCal subscriptions to list"),
230
260
  status: z.enum(["active", "error", "paused"]).optional().describe("Filter by subscription status"),
231
- limit: z.number().int().min(1).max(200).optional().describe("Max results per page (default 50)"),
232
- offset: z.number().int().min(0).optional().describe("Pagination offset (default 0)")
261
+ limit: z.number().int().min(1).max(200).default(50).describe("Max results to return"),
262
+ offset: z.number().int().min(0).default(0).describe("Pagination offset")
233
263
  });
234
264
  var GetICalSubscriptionSchema = z.object({
235
- subscription_id: z.string().describe("The iCal subscription ID to retrieve")
265
+ subscription_id: z.string().describe("iCal subscription ID to fetch")
236
266
  });
237
267
  var SubscribeICalSchema = z.object({
238
268
  agent_id: z.string().describe("Agent ID that will own this subscription"),
@@ -240,23 +270,16 @@ var SubscribeICalSchema = z.object({
240
270
  url: z.string().url().describe("HTTPS URL of the iCal feed (.ics) to subscribe to"),
241
271
  label: z.string().optional().describe("Optional label for this subscription")
242
272
  });
243
- var ListWebhookDeliveriesSchema = z.object({
244
- webhook_id: z.string().describe("Webhook subscription whose deliveries to list"),
245
- limit: z.number().int().min(1).max(100).optional().describe("Max results to return (default 20)"),
246
- offset: z.number().int().min(0).optional().describe("Pagination offset (default 0)"),
247
- status: z.enum(["pending", "delivered", "failed"]).optional().describe("Filter to a single delivery status"),
248
- include_payload: z.boolean().optional().describe("Include the full event payload sent on each delivery")
249
- });
250
273
  var UpdateICalSubscriptionSchema = z.object({
251
- subscription_id: z.string().describe("The iCal subscription ID to update"),
252
- label: z.string().optional().describe("New label"),
253
- url: z.string().optional().describe("New iCal feed URL")
274
+ subscription_id: z.string().describe("iCal subscription ID to update"),
275
+ label: z.string().min(1).max(255).optional().describe("New label for this subscription"),
276
+ url: z.string().url().startsWith("https://", "URL must use HTTPS").optional().describe("New HTTPS URL of the iCal feed (.ics)")
254
277
  });
255
278
  var DeleteICalSubscriptionSchema = z.object({
256
- subscription_id: z.string().describe("The iCal subscription ID to delete")
279
+ subscription_id: z.string().describe("iCal subscription ID to delete")
257
280
  });
258
281
  var SyncICalSubscriptionSchema = z.object({
259
- subscription_id: z.string().describe("The iCal subscription ID to sync immediately")
282
+ subscription_id: z.string().describe("iCal subscription ID to sync")
260
283
  });
261
284
  var GetUsageSchema = z.object({});
262
285
 
@@ -286,7 +309,7 @@ async function fetchPage(iterator, offset, limit) {
286
309
  }
287
310
  var listCalendars = safeFunc(async (ctx) => {
288
311
  const { client, params } = ctx;
289
- const iter = client.calendars.list({ agentId: params.agent_id, include: params.include, limit: params.limit });
312
+ const iter = client.calendars.list({ include: params.include, limit: params.limit });
290
313
  return fetchPage(iter, params.offset, params.limit);
291
314
  });
292
315
  var getCalendar = safeFunc(async (ctx) => {
@@ -315,11 +338,8 @@ var listEvents = safeFunc(async (ctx) => {
315
338
  const { client, params } = ctx;
316
339
  const iter = client.events.list({
317
340
  calendarId: params.calendar_id,
318
- agentId: params.agent_id,
319
341
  start_after: params.start_after,
320
342
  start_before: params.start_before,
321
- status: params.status,
322
- source: params.source,
323
343
  limit: params.limit
324
344
  });
325
345
  return fetchPage(iter, params.offset, params.limit);
@@ -369,15 +389,34 @@ var deleteAgent = safeFunc(async (ctx) => {
369
389
  });
370
390
  var getAvailability = safeFunc(async (ctx) => {
371
391
  const { client, params } = ctx;
392
+ const start = params.start ?? params.start_time;
393
+ const end = params.end ?? params.end_time;
394
+ if (!start || !end) {
395
+ throw new Error("start (or start_time) and end (or end_time) are required");
396
+ }
372
397
  return client.availability.forAgent(params.agent_id, {
373
- start: params.start,
374
- end: params.end,
398
+ start,
399
+ end,
375
400
  slot_duration: params.slot_duration,
376
401
  include_busy: params.include_busy
377
402
  });
378
403
  });
379
404
  var findMeetingTime = safeFunc(async (ctx) => {
380
- return ctx.client.availability.check(ctx.params);
405
+ const { client, params } = ctx;
406
+ const agents = params.agents ?? params.agent_ids;
407
+ const start = params.start ?? params.start_time;
408
+ const end = params.end ?? params.end_time;
409
+ if (!agents || !start || !end) {
410
+ throw new Error("agents (or agent_ids), start (or start_time), and end (or end_time) are required");
411
+ }
412
+ return client.availability.check({
413
+ agents,
414
+ start,
415
+ end,
416
+ slot_duration: params.slot_duration,
417
+ calendars: params.calendars,
418
+ include_busy: params.include_busy
419
+ });
381
420
  });
382
421
  var getCalendarContext = safeFunc(async (ctx) => {
383
422
  return ctx.client.calendars.getContext(ctx.params.calendar_id);
@@ -551,35 +590,35 @@ var TOOL_DEFINITIONS = [
551
590
  // ── Calendars ──────────────────────────────────────────────────
552
591
  {
553
592
  name: "list_calendars",
554
- description: "List calendars, optionally filtered by agent. Returns paginated results.",
593
+ description: "List calendars in the org. Org-level API keys see every calendar (agent-owned and shared); agent-scoped keys see only their own agent's calendars. Use this to discover calendar IDs before creating or listing events.",
555
594
  schema: ListCalendarsSchema,
556
595
  annotations: { title: "List Calendars", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
557
596
  execute: createExecutor(listCalendars)
558
597
  },
559
598
  {
560
599
  name: "get_calendar",
561
- description: "Get a calendar by its ID, including its name, timezone, and iCal feed URL.",
600
+ description: "Fetch a single calendar by ID, including its name, timezone, agent status, and default reminders. Agent-scoped keys may only read calendars owned by their agent.",
562
601
  schema: GetCalendarSchema,
563
602
  annotations: { title: "Get Calendar", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
564
603
  execute: createExecutor(getCalendar)
565
604
  },
566
605
  {
567
606
  name: "create_calendar",
568
- description: "Create a new calendar. Specify a name and IANA timezone. Optionally scope it to an agent.",
607
+ description: 'Create a calendar to hold events and track availability. Calendars are required before creating events \u2014 call this first when setting up a new agent. An agent can have multiple calendars (e.g. "Work", "Personal"). Org-level calendars (no agent_id) can be used as shared resources like meeting rooms.',
569
608
  schema: CreateCalendarSchema,
570
609
  annotations: { title: "Create Calendar", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
571
610
  execute: createExecutor(createCalendar)
572
611
  },
573
612
  {
574
613
  name: "update_calendar",
575
- description: "Update a calendar's name, timezone, or metadata.",
614
+ description: "Update a calendar's name, timezone, agent status, default reminders, or metadata. Agent-scoped keys may only update calendars owned by their agent.",
576
615
  schema: UpdateCalendarSchema,
577
616
  annotations: { title: "Update Calendar", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
578
617
  execute: createExecutor(updateCalendar)
579
618
  },
580
619
  {
581
620
  name: "delete_calendar",
582
- description: "Permanently delete a calendar and all its events.",
621
+ description: "Delete a calendar (soft delete). Its events are no longer returned and it stops contributing to availability. Agent-scoped keys may only delete calendars owned by their agent.",
583
622
  schema: DeleteCalendarSchema,
584
623
  annotations: { title: "Delete Calendar", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
585
624
  execute: createExecutor(deleteCalendar)
@@ -587,42 +626,42 @@ var TOOL_DEFINITIONS = [
587
626
  // ── Events ─────────────────────────────────────────────────────
588
627
  {
589
628
  name: "list_events",
590
- description: "List events on a calendar or for an agent. Supports date range and status filters. Provide calendar_id or agent_id.",
629
+ description: "List all events on a calendar, including internally created events and externally synced events from iCal subscriptions (e.g. Google Calendar, Outlook). Use start_after and start_before to query a specific time window.",
591
630
  schema: ListEventsSchema,
592
631
  annotations: { title: "List Events", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
593
632
  execute: createExecutor(listEvents)
594
633
  },
595
634
  {
596
635
  name: "get_event",
597
- description: "Get a specific event by its calendar ID and event ID.",
636
+ description: "Retrieve a single event by ID, including its title, times, status, location, reminders, and metadata. Works for both internally created events and externally synced iCal events. `calendar_id` is optional \u2014 if omitted the calendar is resolved from the event. Provide `calendar_id` to fail fast on cross-calendar typos.",
598
637
  schema: GetEventSchema,
599
638
  annotations: { title: "Get Event", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
600
639
  execute: createExecutor(getEvent)
601
640
  },
602
641
  {
603
642
  name: "create_event",
604
- description: "Create a new event on a calendar. The event blocks the agent's availability during the specified time window and appears in availability queries.",
643
+ description: `Create a booking, appointment, meeting, hold, or any scheduled event on a calendar. The calendar_id comes from create_calendar or list_events. Once created, this event blocks the agent's availability during that time and appears in availability queries. Use status="hold" with hold_expires_at to tentatively reserve a slot that auto-releases on TTL.`,
605
644
  schema: CreateEventSchema,
606
645
  annotations: { title: "Create Event", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
607
646
  execute: createExecutor(createEvent)
608
647
  },
609
648
  {
610
649
  name: "update_event",
611
- description: "Update an existing event's title, times, status, or other properties.",
650
+ description: "Reschedule or edit an event \u2014 change its title, description, start/end times, location, status, reminders, or metadata. Use this to move an appointment to a new time or update its details. Provide only the fields you want to change. Holds cannot be edited via this tool (use confirm_event / release_event). External iCal events are read-only. `calendar_id` is optional \u2014 if omitted it is resolved from the event.",
612
651
  schema: UpdateEventSchema,
613
652
  annotations: { title: "Update Event", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
614
653
  execute: createExecutor(updateEvent)
615
654
  },
616
655
  {
617
656
  name: "cancel_event",
618
- description: "Delete or cancel an event from a calendar. The event is marked cancelled and excluded from future availability calculations.",
657
+ description: "Delete or cancel an event from a calendar. Use this to remove, cancel, or delete any scheduled event or appointment. The event is marked cancelled and excluded from future availability calculations. `calendar_id` is optional \u2014 if omitted the calendar is looked up from the event. Provide `calendar_id` to fail fast on cross-calendar typos.",
619
658
  schema: CancelEventSchema,
620
659
  annotations: { title: "Cancel Event", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
621
660
  execute: createExecutor(cancelEvent)
622
661
  },
623
662
  {
624
663
  name: "confirm_event",
625
- description: 'Promote a held event to a confirmed booking. The event must currently have status="hold" and its hold_expires_at must not have passed.',
664
+ description: 'Promote a held event to a confirmed booking. The event must currently have status="hold" and its hold_expires_at must not have passed. After confirmation, event.started and event.ended lifecycle webhooks fire at the scheduled times.',
626
665
  schema: ConfirmEventSchema,
627
666
  annotations: { title: "Confirm Event", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
628
667
  execute: createExecutor(confirmEvent)
@@ -644,28 +683,28 @@ var TOOL_DEFINITIONS = [
644
683
  },
645
684
  {
646
685
  name: "list_agents",
647
- description: "List all agents in your organization. Returns paginated results.",
686
+ description: "List all agents in your organization",
648
687
  schema: ListAgentsSchema,
649
688
  annotations: { title: "List Agents", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
650
689
  execute: createExecutor(listAgents)
651
690
  },
652
691
  {
653
692
  name: "get_agent",
654
- description: "Fetch a single agent by ID. An agent represents an AI assistant, human, or shared resource (e.g. a meeting room).",
693
+ description: "Fetch a single agent by ID. An agent represents an AI assistant, human, or shared resource (e.g. a meeting room). Agent-scoped API keys may only read their own agent.",
655
694
  schema: GetAgentSchema,
656
695
  annotations: { title: "Get Agent", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
657
696
  execute: createExecutor(getAgent)
658
697
  },
659
698
  {
660
699
  name: "update_agent",
661
- description: "Update an agent's name, description, metadata, or status (active/paused). Requires an org-level API key.",
700
+ description: "Update an agent's name, description, metadata, or status (active/paused). Requires an org-level API key \u2014 agent-scoped keys cannot mutate agents.",
662
701
  schema: UpdateAgentSchema,
663
702
  annotations: { title: "Update Agent", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
664
703
  execute: createExecutor(updateAgent)
665
704
  },
666
705
  {
667
706
  name: "delete_agent",
668
- description: "Decommission an agent. This marks the agent as decommissioned and revokes all of its scoped API keys. Requires an org-level API key.",
707
+ description: "Decommission an agent. This marks the agent as decommissioned and revokes all of its scoped API keys. Requires an org-level API key \u2014 agent-scoped keys cannot delete agents.",
669
708
  schema: DeleteAgentSchema,
670
709
  annotations: { title: "Delete Agent", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
671
710
  execute: createExecutor(deleteAgent)
@@ -673,14 +712,14 @@ var TOOL_DEFINITIONS = [
673
712
  // ── Availability ───────────────────────────────────────────────
674
713
  {
675
714
  name: "get_availability",
676
- description: "Check when a single agent is free within a time range. Returns available time slots and optionally busy blocks.",
715
+ description: "Check when a single agent is free within a time range. Accepts `start`/`end` (preferred \u2014 matches the underlying availability service) or `start_time`/`end_time` (aliases that match the REST events schema).",
677
716
  schema: GetAvailabilitySchema,
678
717
  annotations: { title: "Get Availability", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
679
718
  execute: createExecutor(getAvailability)
680
719
  },
681
720
  {
682
721
  name: "find_meeting_time",
683
- description: "Find time slots when multiple agents are all free simultaneously. All agents must be free during the returned slots.",
722
+ description: "Find time slots when multiple agents are all free simultaneously. Accepts `agents`/`start`/`end` (preferred \u2014 matches the availability service) or `agent_ids`/`start_time`/`end_time` (aliases that match the REST/scheduling-proposal naming).",
684
723
  schema: FindMeetingTimeSchema,
685
724
  annotations: { title: "Find Meeting Time", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
686
725
  execute: createExecutor(findMeetingTime)
@@ -688,7 +727,7 @@ var TOOL_DEFINITIONS = [
688
727
  // ── Calendar context ───────────────────────────────────────────
689
728
  {
690
729
  name: "get_calendar_context",
691
- description: "Get a calendar's temporal context in a single call: the current event, the next upcoming event, recent past events, a short upcoming window, and the owning agent's status.",
730
+ description: `Get a calendar's temporal context in a single call: the current event (if one is happening now), the next upcoming event, recent past events, a short upcoming window, and the owning agent's status (idle/working/waiting/error). Use this to answer "what is this agent doing right now?" without issuing multiple list_events queries.`,
692
731
  schema: GetCalendarContextSchema,
693
732
  annotations: { title: "Get Calendar Context", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
694
733
  execute: createExecutor(getCalendarContext)
@@ -696,14 +735,14 @@ var TOOL_DEFINITIONS = [
696
735
  // ── Scheduling proposals ───────────────────────────────────────
697
736
  {
698
737
  name: "create_proposal",
699
- description: "Create a scheduling proposal \u2014 send candidate time slots to one or more participant agents so they can accept, decline, or counter-propose. Requires an org-level API key. Pro plan only.",
738
+ description: "Create a scheduling proposal \u2014 send a set of candidate time slots to one or more participant agents so they can accept, decline, or counter-propose. The organizer agent owns the proposal; once every participant responds, the system auto-resolves to the highest-scoring slot (or cancels if all decline). Requires an org-level API key. Pro plan only.",
700
739
  schema: CreateProposalSchema,
701
740
  annotations: { title: "Create Proposal", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
702
741
  execute: createExecutor(createProposal)
703
742
  },
704
743
  {
705
744
  name: "list_proposals",
706
- description: "List scheduling proposals for the org. Filter by status or organizer_agent_id. Requires an org-level API key.",
745
+ description: "List scheduling proposals for the org. Filter by status (pending|confirmed|expired|cancelled) or organizer_agent_id. Requires an org-level API key.",
707
746
  schema: ListProposalsSchema,
708
747
  annotations: { title: "List Proposals", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
709
748
  execute: createExecutor(listProposals)
@@ -717,14 +756,14 @@ var TOOL_DEFINITIONS = [
717
756
  },
718
757
  {
719
758
  name: "respond_to_proposal",
720
- description: "Submit a response (accept / decline / counter) on behalf of one participant agent to an open proposal. Requires an org-level API key. Pro plan only.",
759
+ description: 'Submit a response (accept / decline / counter) on behalf of one participant agent to an open proposal. An "accept" requires the slot id from the proposal; a "counter" can suggest alternative slots. When all participants have responded the proposal auto-resolves \u2014 no separate resolve call needed in the normal flow. Requires an org-level API key. Pro plan only.',
721
760
  schema: RespondToProposalSchema,
722
761
  annotations: { title: "Respond To Proposal", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
723
762
  execute: createExecutor(respondToProposal)
724
763
  },
725
764
  {
726
765
  name: "resolve_proposal",
727
- description: "Force-resolve an open proposal using responses collected so far. Picks the highest-scoring slot and creates a confirmed calendar event. Requires an org-level API key. Pro plan only.",
766
+ description: 'Force-resolve an open proposal using responses collected so far. Picks the highest-scoring slot among those accepted by the most participants and creates a confirmed calendar event. If every response was "decline", the proposal is cancelled instead. Use when you want to close out a proposal without waiting for every participant. Requires an org-level API key. Pro plan only.',
728
767
  schema: ResolveProposalSchema,
729
768
  annotations: { title: "Resolve Proposal", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
730
769
  execute: createExecutor(resolveProposal)
@@ -739,7 +778,7 @@ var TOOL_DEFINITIONS = [
739
778
  // ── Availability rules ─────────────────────────────────────────
740
779
  {
741
780
  name: "set_availability_rules",
742
- description: "Set or replace the availability rules on a calendar \u2014 buffer times before/after events and optional per-day working hours. Upsert: overwrites any existing rules.",
781
+ description: "Set or replace the availability rules on a calendar \u2014 buffer times before/after events and optional per-day working hours. When these rules are set, every availability query on this calendar automatically applies them (busy-block expansion for buffers, masking outside working hours). Upsert: overwrites any existing rules.",
743
782
  schema: SetAvailabilityRulesSchema,
744
783
  annotations: { title: "Set Availability Rules", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
745
784
  execute: createExecutor(setAvailabilityRules)
@@ -753,7 +792,7 @@ var TOOL_DEFINITIONS = [
753
792
  },
754
793
  {
755
794
  name: "clear_availability_rules",
756
- description: "Remove the availability rules from a calendar, reverting to the default (no buffers, no working-hours mask).",
795
+ description: "Remove the availability rules from a calendar, reverting to the default (no buffers, no working-hours mask). Returns the deleted row, or an error if none were set.",
757
796
  schema: ClearAvailabilityRulesSchema,
758
797
  annotations: { title: "Clear Availability Rules", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
759
798
  execute: createExecutor(clearAvailabilityRules)
@@ -761,35 +800,35 @@ var TOOL_DEFINITIONS = [
761
800
  // ── Webhooks ───────────────────────────────────────────────────
762
801
  {
763
802
  name: "list_webhooks",
764
- description: "List all webhook subscriptions for the organization.",
803
+ description: "List the org's webhook subscriptions with their subscribed event types and active state. Signing secrets are never returned. Requires an org-level API key.",
765
804
  schema: ListWebhooksSchema,
766
805
  annotations: { title: "List Webhooks", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
767
806
  execute: createExecutor(listWebhooks)
768
807
  },
769
808
  {
770
809
  name: "get_webhook",
771
- description: "Get a webhook subscription by its ID.",
810
+ description: "Get a single webhook subscription by id, including its subscribed event types and active state. The signing secret is never returned. Requires an org-level API key.",
772
811
  schema: GetWebhookSchema,
773
812
  annotations: { title: "Get Webhook", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
774
813
  execute: createExecutor(getWebhook)
775
814
  },
776
815
  {
777
816
  name: "create_webhook",
778
- description: "Create a webhook subscription to receive event notifications at a URL. Payloads are signed with HMAC-SHA256.",
817
+ description: "Create a webhook subscription so the org receives HTTP POST notifications when events occur (e.g. event.created, proposal.confirmed). The signing secret is returned ONCE in this response \u2014 store it to verify the HMAC-SHA256 signature on delivered payloads. Requires an org-level API key.",
779
818
  schema: CreateWebhookSchema,
780
819
  annotations: { title: "Create Webhook", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
781
820
  execute: createExecutor(createWebhook)
782
821
  },
783
822
  {
784
823
  name: "update_webhook",
785
- description: "Update a webhook's URL, subscribed events, or active status.",
824
+ description: "Update a webhook subscription \u2014 change its delivery URL, the set of subscribed event types, or pause/resume it via active. At least one field must be supplied. Requires an org-level API key.",
786
825
  schema: UpdateWebhookSchema,
787
826
  annotations: { title: "Update Webhook", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
788
827
  execute: createExecutor(updateWebhook)
789
828
  },
790
829
  {
791
830
  name: "delete_webhook",
792
- description: "Delete a webhook subscription. No further events will be delivered to this URL.",
831
+ description: "Permanently delete a webhook subscription. This frees its endpoint slot against the per-plan cap. Requires an org-level API key.",
793
832
  schema: DeleteWebhookSchema,
794
833
  annotations: { title: "Delete Webhook", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
795
834
  execute: createExecutor(deleteWebhook)
@@ -804,42 +843,42 @@ var TOOL_DEFINITIONS = [
804
843
  // ── iCal Subscriptions ─────────────────────────────────────────
805
844
  {
806
845
  name: "list_ical_subscriptions",
807
- description: "List external calendar imports (iCal subscriptions) for an agent.",
846
+ description: "List an agent's external iCal feed subscriptions (e.g. linked Google Calendar / Outlook feeds), including their sync status and last sync time.",
808
847
  schema: ListICalSubscriptionsSchema,
809
848
  annotations: { title: "List iCal Subscriptions", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
810
849
  execute: createExecutor(listICalSubscriptions)
811
850
  },
812
851
  {
813
852
  name: "get_ical_subscription",
814
- description: "Get an iCal subscription by its ID, including sync status and last error.",
853
+ description: "Get a single external iCal feed subscription by id, including its sync status, last sync time, and last error.",
815
854
  schema: GetICalSubscriptionSchema,
816
855
  annotations: { title: "Get iCal Subscription", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
817
856
  execute: createExecutor(getICalSubscription)
818
857
  },
819
858
  {
820
859
  name: "subscribe_ical",
821
- description: "Link an external iCal feed (e.g. a human's Google Calendar) to an agent's calendar so external events appear in availability calculations. Events are synced every 30 minutes.",
860
+ description: "Link an external iCal feed (e.g. a human's Google Calendar) to an agent's calendar so external events appear in availability calculations. The target calendar must be owned by the specified agent \u2014 create the calendar with that agent_id first (org-level calendars without an agent_id cannot host external iCal subscriptions; create a dedicated per-agent calendar for sync targets).",
822
861
  schema: SubscribeICalSchema,
823
862
  annotations: { title: "Subscribe iCal", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
824
863
  execute: createExecutor(subscribeICal)
825
864
  },
826
865
  {
827
866
  name: "update_ical_subscription",
828
- description: "Update an iCal subscription's label or feed URL.",
867
+ description: "Update an external iCal feed subscription \u2014 change its label or its feed URL. Changing the URL forces a full re-sync on the next poll.",
829
868
  schema: UpdateICalSubscriptionSchema,
830
869
  annotations: { title: "Update iCal Subscription", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
831
870
  execute: createExecutor(updateICalSubscription)
832
871
  },
833
872
  {
834
873
  name: "delete_ical_subscription",
835
- description: "Remove an external calendar import. Previously synced events remain on the calendar.",
874
+ description: "Delete an external iCal feed subscription. Events previously synced from the feed are no longer refreshed.",
836
875
  schema: DeleteICalSubscriptionSchema,
837
876
  annotations: { title: "Delete iCal Subscription", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
838
877
  execute: createExecutor(deleteICalSubscription)
839
878
  },
840
879
  {
841
880
  name: "sync_ical_subscription",
842
- description: "Trigger an immediate sync of an iCal subscription instead of waiting for the next 30-minute poll.",
881
+ description: "Trigger an immediate sync of an external iCal feed subscription instead of waiting for the next scheduled poll. Returns once the sync has been queued.",
843
882
  schema: SyncICalSubscriptionSchema,
844
883
  annotations: { title: "Sync iCal Subscription", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
845
884
  execute: createExecutor(syncICalSubscription)
@@ -847,14 +886,14 @@ var TOOL_DEFINITIONS = [
847
886
  // ── Scoped keys ────────────────────────────────────────────────
848
887
  {
849
888
  name: "create_scoped_key",
850
- description: "Create an agent-scoped API key (chr_ak_*) that can only act on behalf of a single agent. The plaintext key is returned exactly once. Requires an org-level API key.",
889
+ description: "Create an agent-scoped API key (chr_ak_*) that can only act on behalf of a single agent. Use this to self-provision or rotate per-agent credentials. The plaintext key is returned exactly once in the response \u2014 store it immediately, it cannot be retrieved later. Requires an org-level API key.",
851
890
  schema: CreateScopedKeySchema,
852
891
  annotations: { title: "Create Scoped Key", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
853
892
  execute: createExecutor(createScopedKey)
854
893
  },
855
894
  {
856
895
  name: "list_scoped_keys",
857
- description: "List all live (non-revoked) agent-scoped API keys for this org. Returns key metadata only \u2014 never the plaintext secret. Requires an org-level API key.",
896
+ description: "List all live (non-revoked) agent-scoped API keys for this org. Returns key metadata only (id, prefix, agent_id, label, created_at) \u2014 never the plaintext secret. Requires an org-level API key.",
858
897
  schema: ListScopedKeysSchema,
859
898
  annotations: { title: "List Scoped Keys", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
860
899
  execute: createExecutor(listScopedKeys)
@@ -869,7 +908,7 @@ var TOOL_DEFINITIONS = [
869
908
  // ── Audit log ──────────────────────────────────────────────────
870
909
  {
871
910
  name: "get_audit_log",
872
- description: "List audit-log entries for the calling org \u2014 mutating operations and auth-lifecycle events, newest first. Results are clamped to the plan's retention window. Requires an org-level API key.",
911
+ description: "List audit-log entries for the calling org \u2014 mutating operations and auth-lifecycle events, newest first. Results are clamped to the plan's retention window. Requires an org-level API key (chr_sk_*); agent-scoped keys cannot read the org-wide audit log.",
873
912
  schema: GetAuditLogSchema,
874
913
  annotations: { title: "Get Audit Log", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
875
914
  execute: createExecutor(getAuditLog)
@@ -877,7 +916,7 @@ var TOOL_DEFINITIONS = [
877
916
  // ── Terms ──────────────────────────────────────────────────────
878
917
  {
879
918
  name: "accept_terms",
880
- description: "Re-accept the current Chronary terms of service on behalf of the calling org. Use this when responses carry the Chronary-Terms-Upgrade-Required header. Requires an org-level API key.",
919
+ description: "Re-accept the current Chronary terms of service on behalf of the calling org. Use this when responses carry the Chronary-Terms-Upgrade-Required header \u2014 a material ToS bump otherwise leaves MCP-only agents stuck without a console session. Pass the current tos_version (read it from GET /v1/auth/terms/current). Requires an org-level API key (chr_sk_*); agent-scoped keys cannot accept org-wide terms.",
881
920
  schema: AcceptTermsSchema,
882
921
  annotations: { title: "Accept Terms", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
883
922
  execute: createExecutor(acceptTerms)
@@ -885,7 +924,7 @@ var TOOL_DEFINITIONS = [
885
924
  // ── Usage ──────────────────────────────────────────────────────
886
925
  {
887
926
  name: "get_usage",
888
- description: "Get quota and usage statistics for the current billing period.",
927
+ description: "Get the calling org's current-period usage and plan limits (agents, calendars, events, API calls, webhooks, availability queries, iCal subscriptions, proposals, scoped keys, holds, cross-calendar queries). Requires an org-level API key (chr_sk_*); agent-scoped keys cannot read org-wide usage.",
889
928
  schema: GetUsageSchema,
890
929
  annotations: { title: "Get Usage", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
891
930
  execute: createExecutor(getUsage)