@ganju/utils 0.0.10 → 0.0.11

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.
@@ -15,6 +15,45 @@
15
15
  // Adding a tool: add the entry here, add its handler to `toolRegistry` under the
16
16
  // same key. TypeScript fails the build until both exist.
17
17
 
18
+ // MCP tool annotations: what a tool does to the world, as hints a client can
19
+ // act on. `destructiveHint` is also what the channel runner reads when an
20
+ // organization asks to confirm sensitive actions, so it is set on anything
21
+ // that reaches another person or can't be taken back — a sent email, a posted
22
+ // message, a booking or calendar change (attendees are notified), a deletion —
23
+ // and left off drafts, labels and moves, which stay in the owner's own account
24
+ // and can be undone.
25
+ export interface ToolAnnotations {
26
+ readOnlyHint: boolean;
27
+ destructiveHint: boolean;
28
+ openWorldHint: boolean;
29
+ }
30
+
31
+ const READ_ONLY: ToolAnnotations = {
32
+ readOnlyHint: true,
33
+ destructiveHint: false,
34
+ openWorldHint: false
35
+ };
36
+ const WEB_READ: ToolAnnotations = {
37
+ readOnlyHint: true,
38
+ destructiveHint: false,
39
+ openWorldHint: true
40
+ };
41
+ const WRITE: ToolAnnotations = {
42
+ readOnlyHint: false,
43
+ destructiveHint: false,
44
+ openWorldHint: false
45
+ };
46
+ const REACHES_OTHERS: ToolAnnotations = {
47
+ readOnlyHint: false,
48
+ destructiveHint: true,
49
+ openWorldHint: true
50
+ };
51
+ const DELETES: ToolAnnotations = {
52
+ readOnlyHint: false,
53
+ destructiveHint: true,
54
+ openWorldHint: false
55
+ };
56
+
18
57
  export interface CatalogTool {
19
58
  // Doubles as the MCP tool name for native tools, which is why it is also what
20
59
  // `isReservedToolName` protects from user-authored tools.
@@ -25,6 +64,10 @@ export interface CatalogTool {
25
64
  // prompt for incremental re-authorization. Null when the group's grant covers
26
65
  // it.
27
66
  requiredScopes: string | null;
67
+ // Required, so a new tool can't ship without saying whether it is sensitive.
68
+ // Null for the three definitions whose tools the user authors: each
69
+ // installed tool is annotated on its own when it registers.
70
+ annotations: ToolAnnotations | null;
28
71
  }
29
72
 
30
73
  export interface CatalogGroup {
@@ -55,114 +98,132 @@ export const TOOL_CATALOG = [
55
98
  title: 'Batch Modify Labels',
56
99
  description:
57
100
  'Add or remove labels on many emails at once (archive, mark read, etc.).',
58
- requiredScopes: 'https://www.googleapis.com/auth/gmail.modify'
101
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.modify',
102
+ annotations: WRITE
59
103
  },
60
104
  {
61
105
  key: 'gmail-create-draft',
62
106
  title: 'Create Draft',
63
107
  description: 'Save a new draft in Gmail without sending it yet.',
64
- requiredScopes: 'https://www.googleapis.com/auth/gmail.compose'
108
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.compose',
109
+ annotations: WRITE
65
110
  },
66
111
  {
67
112
  key: 'gmail-delete-draft',
68
113
  title: 'Delete Draft',
69
114
  description: 'Permanently delete a draft.',
70
- requiredScopes: 'https://www.googleapis.com/auth/gmail.compose'
115
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.compose',
116
+ annotations: DELETES
71
117
  },
72
118
  {
73
119
  key: 'gmail-forward-email',
74
120
  title: 'Forward Email',
75
121
  description: 'Forward an email to a new recipient.',
76
- requiredScopes: 'https://www.googleapis.com/auth/gmail.send'
122
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.send',
123
+ annotations: REACHES_OTHERS
77
124
  },
78
125
  {
79
126
  key: 'gmail-get-draft',
80
127
  title: 'Get Draft',
81
128
  description: 'Open a saved draft to review its contents.',
82
- requiredScopes: 'https://www.googleapis.com/auth/gmail.compose'
129
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.compose',
130
+ annotations: READ_ONLY
83
131
  },
84
132
  {
85
133
  key: 'gmail-get-profile',
86
134
  title: 'Get Profile',
87
135
  description:
88
136
  'Show the email address and inbox stats for the connected Gmail account.',
89
- requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly'
137
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly',
138
+ annotations: READ_ONLY
90
139
  },
91
140
  {
92
141
  key: 'gmail-get-thread',
93
142
  title: 'Get Thread',
94
143
  description: 'See every message inside one conversation.',
95
- requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly'
144
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly',
145
+ annotations: READ_ONLY
96
146
  },
97
147
  {
98
148
  key: 'gmail-list-drafts',
99
149
  title: 'List Drafts',
100
150
  description: 'Browse your saved drafts.',
101
- requiredScopes: 'https://www.googleapis.com/auth/gmail.compose'
151
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.compose',
152
+ annotations: READ_ONLY
102
153
  },
103
154
  {
104
155
  key: 'gmail-list-emails',
105
156
  title: 'List Emails',
106
157
  description: 'Browse your Gmail inbox, with optional search filters.',
107
- requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly'
158
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly',
159
+ annotations: READ_ONLY
108
160
  },
109
161
  {
110
162
  key: 'gmail-list-labels',
111
163
  title: 'List Labels',
112
164
  description: 'See all of your Gmail labels and folders.',
113
- requiredScopes: 'https://www.googleapis.com/auth/gmail.labels'
165
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.labels',
166
+ annotations: READ_ONLY
114
167
  },
115
168
  {
116
169
  key: 'gmail-list-threads',
117
170
  title: 'List Threads',
118
171
  description: 'List your Gmail conversations.',
119
- requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly'
172
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly',
173
+ annotations: READ_ONLY
120
174
  },
121
175
  {
122
176
  key: 'gmail-modify-labels',
123
177
  title: 'Modify Labels',
124
178
  description:
125
179
  'Add or remove labels on a single email — archive it, mark it read, star it, and more.',
126
- requiredScopes: 'https://www.googleapis.com/auth/gmail.modify'
180
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.modify',
181
+ annotations: WRITE
127
182
  },
128
183
  {
129
184
  key: 'gmail-read-email',
130
185
  title: 'Read Email',
131
186
  description: 'Open and read a specific email.',
132
- requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly'
187
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.readonly',
188
+ annotations: READ_ONLY
133
189
  },
134
190
  {
135
191
  key: 'gmail-reply-email',
136
192
  title: 'Reply Email',
137
193
  description:
138
194
  'Reply to an email so the response stays in the same conversation.',
139
- requiredScopes: 'https://www.googleapis.com/auth/gmail.send'
195
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.send',
196
+ annotations: REACHES_OTHERS
140
197
  },
141
198
  {
142
199
  key: 'gmail-send-draft',
143
200
  title: 'Send Draft',
144
201
  description: "Send a draft you've already saved.",
145
- requiredScopes: 'https://www.googleapis.com/auth/gmail.send'
202
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.send',
203
+ annotations: REACHES_OTHERS
146
204
  },
147
205
  {
148
206
  key: 'gmail-send-email',
149
207
  title: 'Send Email',
150
208
  description:
151
209
  'Compose and send a new email from your connected Gmail account.',
152
- requiredScopes: 'https://www.googleapis.com/auth/gmail.send'
210
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.send',
211
+ annotations: REACHES_OTHERS
153
212
  },
154
213
  {
155
214
  key: 'gmail-trash-email',
156
215
  title: 'Move to Trash',
157
216
  description:
158
217
  'Move an email to Trash. It stays recoverable for 30 days.',
159
- requiredScopes: 'https://www.googleapis.com/auth/gmail.modify'
218
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.modify',
219
+ annotations: DELETES
160
220
  },
161
221
  {
162
222
  key: 'gmail-update-draft',
163
223
  title: 'Update Draft',
164
224
  description: 'Edit the contents of a saved draft.',
165
- requiredScopes: 'https://www.googleapis.com/auth/gmail.compose'
225
+ requiredScopes: 'https://www.googleapis.com/auth/gmail.compose',
226
+ annotations: WRITE
166
227
  }
167
228
  ]
168
229
  },
@@ -177,110 +238,128 @@ export const TOOL_CATALOG = [
177
238
  key: 'outlook-batch-move-messages',
178
239
  title: 'Batch Move Messages',
179
240
  description: 'Move up to 20 messages to the same folder.',
180
- requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite'
241
+ requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite',
242
+ annotations: WRITE
181
243
  },
182
244
  {
183
245
  key: 'outlook-create-draft',
184
246
  title: 'Create Draft',
185
247
  description: 'Create a draft email saved in Drafts.',
186
- requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite'
248
+ requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite',
249
+ annotations: WRITE
187
250
  },
188
251
  {
189
252
  key: 'outlook-delete-draft',
190
253
  title: 'Delete Draft',
191
254
  description: 'Permanently delete a draft.',
192
- requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite'
255
+ requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite',
256
+ annotations: DELETES
193
257
  },
194
258
  {
195
259
  key: 'outlook-forward-email',
196
260
  title: 'Forward',
197
261
  description: 'Forward an existing message to a new recipient.',
198
- requiredScopes: 'https://graph.microsoft.com/Mail.Send'
262
+ requiredScopes: 'https://graph.microsoft.com/Mail.Send',
263
+ annotations: REACHES_OTHERS
199
264
  },
200
265
  {
201
266
  key: 'outlook-get-draft',
202
267
  title: 'Get Draft',
203
268
  description: 'Read the full contents of a draft.',
204
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
269
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
270
+ annotations: READ_ONLY
205
271
  },
206
272
  {
207
273
  key: 'outlook-get-profile',
208
274
  title: 'Get Profile',
209
275
  description: "Get the connected account's profile and inbox totals.",
210
- requiredScopes: 'https://graph.microsoft.com/User.Read'
276
+ requiredScopes: 'https://graph.microsoft.com/User.Read',
277
+ annotations: READ_ONLY
211
278
  },
212
279
  {
213
280
  key: 'outlook-get-thread',
214
281
  title: 'Get Thread',
215
282
  description: 'Get summaries of every message in a conversation.',
216
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
283
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
284
+ annotations: READ_ONLY
217
285
  },
218
286
  {
219
287
  key: 'outlook-list-drafts',
220
288
  title: 'List Drafts',
221
289
  description: 'List drafts in the Drafts folder.',
222
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
290
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
291
+ annotations: READ_ONLY
223
292
  },
224
293
  {
225
294
  key: 'outlook-list-emails',
226
295
  title: 'List Emails',
227
296
  description: 'List inbox messages, optionally filtered by search.',
228
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
297
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
298
+ annotations: READ_ONLY
229
299
  },
230
300
  {
231
301
  key: 'outlook-list-folders',
232
302
  title: 'List Folders',
233
303
  description: 'List every mail folder on the account.',
234
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
304
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
305
+ annotations: READ_ONLY
235
306
  },
236
307
  {
237
308
  key: 'outlook-list-threads',
238
309
  title: 'List Threads',
239
310
  description: 'List inbox conversation threads.',
240
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
311
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
312
+ annotations: READ_ONLY
241
313
  },
242
314
  {
243
315
  key: 'outlook-move-message',
244
316
  title: 'Move Message',
245
317
  description: 'Move a message to a different folder.',
246
- requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite'
318
+ requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite',
319
+ annotations: WRITE
247
320
  },
248
321
  {
249
322
  key: 'outlook-read-email',
250
323
  title: 'Read Email',
251
324
  description: 'Read the full contents of one message by ID.',
252
- requiredScopes: 'https://graph.microsoft.com/Mail.Read'
325
+ requiredScopes: 'https://graph.microsoft.com/Mail.Read',
326
+ annotations: READ_ONLY
253
327
  },
254
328
  {
255
329
  key: 'outlook-reply-email',
256
330
  title: 'Reply',
257
331
  description:
258
332
  'Reply to an existing message, preserving the conversation.',
259
- requiredScopes: 'https://graph.microsoft.com/Mail.Send'
333
+ requiredScopes: 'https://graph.microsoft.com/Mail.Send',
334
+ annotations: REACHES_OTHERS
260
335
  },
261
336
  {
262
337
  key: 'outlook-send-draft',
263
338
  title: 'Send Draft',
264
339
  description: 'Send an existing draft as-is.',
265
- requiredScopes: 'https://graph.microsoft.com/Mail.Send'
340
+ requiredScopes: 'https://graph.microsoft.com/Mail.Send',
341
+ annotations: REACHES_OTHERS
266
342
  },
267
343
  {
268
344
  key: 'outlook-send-email',
269
345
  title: 'Send Email',
270
346
  description: 'Send a brand-new email from the connected account.',
271
- requiredScopes: 'https://graph.microsoft.com/Mail.Send'
347
+ requiredScopes: 'https://graph.microsoft.com/Mail.Send',
348
+ annotations: REACHES_OTHERS
272
349
  },
273
350
  {
274
351
  key: 'outlook-trash-email',
275
352
  title: 'Move to Trash',
276
353
  description: 'Move a message to the Deleted Items folder.',
277
- requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite'
354
+ requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite',
355
+ annotations: DELETES
278
356
  },
279
357
  {
280
358
  key: 'outlook-update-draft',
281
359
  title: 'Update Draft',
282
360
  description: 'Replace the contents of an existing draft.',
283
- requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite'
361
+ requiredScopes: 'https://graph.microsoft.com/Mail.ReadWrite',
362
+ annotations: WRITE
284
363
  }
285
364
  ]
286
365
  },
@@ -296,25 +375,29 @@ export const TOOL_CATALOG = [
296
375
  key: 'slack-get-user',
297
376
  title: 'Get User',
298
377
  description: 'Look up a Slack user by ID or email.',
299
- requiredScopes: 'users:read,users:read.email'
378
+ requiredScopes: 'users:read,users:read.email',
379
+ annotations: READ_ONLY
300
380
  },
301
381
  {
302
382
  key: 'slack-list-channels',
303
383
  title: 'List Channels',
304
384
  description: 'Browse the channels and DMs the agent can see.',
305
- requiredScopes: 'channels:read,groups:read,mpim:read,im:read'
385
+ requiredScopes: 'channels:read,groups:read,mpim:read,im:read',
386
+ annotations: READ_ONLY
306
387
  },
307
388
  {
308
389
  key: 'slack-send-message',
309
390
  title: 'Send Message',
310
391
  description: 'Post a message to a Slack channel, DM, or thread.',
311
- requiredScopes: 'chat:write'
392
+ requiredScopes: 'chat:write',
393
+ annotations: REACHES_OTHERS
312
394
  },
313
395
  {
314
396
  key: 'slack-upload-file',
315
397
  title: 'Upload File',
316
398
  description: 'Upload a stored resource into a Slack channel.',
317
- requiredScopes: 'files:write,chat:write'
399
+ requiredScopes: 'files:write,chat:write',
400
+ annotations: REACHES_OTHERS
318
401
  }
319
402
  ]
320
403
  },
@@ -331,7 +414,8 @@ export const TOOL_CATALOG = [
331
414
  title: 'Search Messages',
332
415
  description:
333
416
  'Search messages across the workspace. Requires a Slack user token (xoxp).',
334
- requiredScopes: 'search:read'
417
+ requiredScopes: 'search:read',
418
+ annotations: READ_ONLY
335
419
  }
336
420
  ]
337
421
  },
@@ -346,37 +430,43 @@ export const TOOL_CATALOG = [
346
430
  key: 'calendar-create-event',
347
431
  title: 'Create Event',
348
432
  description: 'Add a new event to a calendar.',
349
- requiredScopes: 'https://www.googleapis.com/auth/calendar.events'
433
+ requiredScopes: 'https://www.googleapis.com/auth/calendar.events',
434
+ annotations: REACHES_OTHERS
350
435
  },
351
436
  {
352
437
  key: 'calendar-delete-event',
353
438
  title: 'Delete Event',
354
439
  description: 'Permanently remove an event from a calendar.',
355
- requiredScopes: 'https://www.googleapis.com/auth/calendar.events'
440
+ requiredScopes: 'https://www.googleapis.com/auth/calendar.events',
441
+ annotations: REACHES_OTHERS
356
442
  },
357
443
  {
358
444
  key: 'calendar-find-free-slots',
359
445
  title: 'Find Free Slots',
360
446
  description: 'Find open time gaps on a calendar.',
361
- requiredScopes: 'https://www.googleapis.com/auth/calendar.readonly'
447
+ requiredScopes: 'https://www.googleapis.com/auth/calendar.readonly',
448
+ annotations: READ_ONLY
362
449
  },
363
450
  {
364
451
  key: 'calendar-list-calendars',
365
452
  title: 'List Calendars',
366
453
  description: 'See all calendars on the connected Google account.',
367
- requiredScopes: 'https://www.googleapis.com/auth/calendar.readonly'
454
+ requiredScopes: 'https://www.googleapis.com/auth/calendar.readonly',
455
+ annotations: READ_ONLY
368
456
  },
369
457
  {
370
458
  key: 'calendar-list-events',
371
459
  title: 'List Events',
372
460
  description: 'Browse events on a calendar within a time range.',
373
- requiredScopes: 'https://www.googleapis.com/auth/calendar.readonly'
461
+ requiredScopes: 'https://www.googleapis.com/auth/calendar.readonly',
462
+ annotations: READ_ONLY
374
463
  },
375
464
  {
376
465
  key: 'calendar-update-event',
377
466
  title: 'Update Event',
378
467
  description: 'Change the details of an existing event.',
379
- requiredScopes: 'https://www.googleapis.com/auth/calendar.events'
468
+ requiredScopes: 'https://www.googleapis.com/auth/calendar.events',
469
+ annotations: REACHES_OTHERS
380
470
  }
381
471
  ]
382
472
  },
@@ -391,27 +481,31 @@ export const TOOL_CATALOG = [
391
481
  key: 'calcom-cancel-booking',
392
482
  title: 'Cancel Booking',
393
483
  description: 'Cancel an existing booking by its UID.',
394
- requiredScopes: null
484
+ requiredScopes: null,
485
+ annotations: REACHES_OTHERS
395
486
  },
396
487
  {
397
488
  key: 'calcom-create-booking',
398
489
  title: 'Create Booking',
399
490
  description: 'Book an available slot for an attendee.',
400
- requiredScopes: null
491
+ requiredScopes: null,
492
+ annotations: REACHES_OTHERS
401
493
  },
402
494
  {
403
495
  key: 'calcom-list-available-slots',
404
496
  title: 'List Available Slots',
405
497
  description:
406
498
  'Find open booking times for an event type in a date range.',
407
- requiredScopes: null
499
+ requiredScopes: null,
500
+ annotations: READ_ONLY
408
501
  },
409
502
  {
410
503
  key: 'calcom-list-event-types',
411
504
  title: 'List Event Types',
412
505
  description:
413
506
  'See the bookable meeting types on the connected Cal.com account.',
414
- requiredScopes: null
507
+ requiredScopes: null,
508
+ annotations: READ_ONLY
415
509
  }
416
510
  ]
417
511
  },
@@ -428,14 +522,16 @@ export const TOOL_CATALOG = [
428
522
  title: 'Web Extract',
429
523
  description:
430
524
  'Fetch the full cleaned text of specific web pages by URL for in-depth reading.',
431
- requiredScopes: null
525
+ requiredScopes: null,
526
+ annotations: WEB_READ
432
527
  },
433
528
  {
434
529
  key: 'web-search',
435
530
  title: 'Web Search',
436
531
  description:
437
532
  'Search the live web and return the top results plus a synthesized answer so the model can cite sources.',
438
- requiredScopes: null
533
+ requiredScopes: null,
534
+ annotations: WEB_READ
439
535
  }
440
536
  ]
441
537
  },
@@ -451,32 +547,37 @@ export const TOOL_CATALOG = [
451
547
  title: 'List Prompts',
452
548
  description:
453
549
  'List the prompts and commands this assistant exposes, and how to run them on the current channel.',
454
- requiredScopes: null
550
+ requiredScopes: null,
551
+ annotations: READ_ONLY
455
552
  },
456
553
  {
457
554
  key: 'list-resources',
458
555
  title: 'List Resources',
459
556
  description: 'List every resource available to this assistant.',
460
- requiredScopes: null
557
+ requiredScopes: null,
558
+ annotations: READ_ONLY
461
559
  },
462
560
  {
463
561
  key: 'read-resource',
464
562
  title: 'Read Resource',
465
563
  description: 'Read the contents of a stored resource.',
466
- requiredScopes: null
564
+ requiredScopes: null,
565
+ annotations: READ_ONLY
467
566
  },
468
567
  {
469
568
  key: 'search-resources',
470
569
  title: 'Search Resources',
471
570
  description:
472
571
  'Find the resources most relevant to a question, by meaning and by exact keywords.',
473
- requiredScopes: null
572
+ requiredScopes: null,
573
+ annotations: READ_ONLY
474
574
  },
475
575
  {
476
576
  key: 'send-resource',
477
577
  title: 'Send Resource',
478
578
  description: 'Deliver a resource to the user as a chat attachment.',
479
- requiredScopes: null
579
+ requiredScopes: null,
580
+ annotations: WRITE
480
581
  }
481
582
  ]
482
583
  },
@@ -492,7 +593,8 @@ export const TOOL_CATALOG = [
492
593
  title: 'Greeting',
493
594
  description:
494
595
  'Reply with a friendly hello in English or Spanish (demo tool).',
495
- requiredScopes: null
596
+ requiredScopes: null,
597
+ annotations: READ_ONLY
496
598
  }
497
599
  ]
498
600
  },
@@ -509,7 +611,8 @@ export const TOOL_CATALOG = [
509
611
  title: 'HTTP Endpoint',
510
612
  description:
511
613
  'A user-configured HTTP request exposed to the agent as its own named tool.',
512
- requiredScopes: null
614
+ requiredScopes: null,
615
+ annotations: null
513
616
  }
514
617
  ]
515
618
  },
@@ -526,7 +629,8 @@ export const TOOL_CATALOG = [
526
629
  title: 'MCP Server',
527
630
  description:
528
631
  'A connected remote MCP server. Each server you add exposes its tools to the agent under a vendor prefix.',
529
- requiredScopes: null
632
+ requiredScopes: null,
633
+ annotations: null
530
634
  }
531
635
  ]
532
636
  },
@@ -543,7 +647,8 @@ export const TOOL_CATALOG = [
543
647
  title: 'Custom code',
544
648
  description:
545
649
  'Tools implemented by your own code. One script per artifact; names and schemas come from the published version.',
546
- requiredScopes: null
650
+ requiredScopes: null,
651
+ annotations: null
547
652
  }
548
653
  ]
549
654
  }
@@ -610,6 +715,7 @@ export interface CatalogToolDescriptor {
610
715
  title: string;
611
716
  description: string | null;
612
717
  requiredScopes: string | null;
718
+ annotations: ToolAnnotations | null;
613
719
  group: Omit<CatalogGroup, 'tools'>;
614
720
  }
615
721
 
@@ -624,6 +730,7 @@ export const describeCatalogTool = (
624
730
  title: tool.title,
625
731
  description: tool.description,
626
732
  requiredScopes: tool.requiredScopes,
733
+ annotations: tool.annotations,
627
734
  group: {
628
735
  key: group.key,
629
736
  title: group.title,