figmanage 1.3.8 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +164 -133
  2. package/dist/auth/client.d.ts +1 -0
  3. package/dist/auth/health.js +2 -1
  4. package/dist/cli/comments.js +79 -2
  5. package/dist/cli/components.js +66 -0
  6. package/dist/cli/compound-commands.js +2 -0
  7. package/dist/cli/org.js +143 -5
  8. package/dist/cli/teams.js +41 -1
  9. package/dist/cli/webhooks.js +20 -1
  10. package/dist/clients/internal-api.js +1 -1
  11. package/dist/clients/public-api.js +1 -1
  12. package/dist/mcp.d.ts +1 -0
  13. package/dist/mcp.js +10 -4
  14. package/dist/operations/comments.d.ts +25 -0
  15. package/dist/operations/comments.js +22 -0
  16. package/dist/operations/compound-manager.d.ts +1 -0
  17. package/dist/operations/compound-manager.js +17 -3
  18. package/dist/operations/dev-resources.d.ts +25 -0
  19. package/dist/operations/dev-resources.js +31 -0
  20. package/dist/operations/navigate.d.ts +5 -0
  21. package/dist/operations/navigate.js +20 -0
  22. package/dist/operations/org.d.ts +68 -1
  23. package/dist/operations/org.js +112 -1
  24. package/dist/operations/teams.d.ts +9 -0
  25. package/dist/operations/teams.js +23 -0
  26. package/dist/operations/webhooks.d.ts +14 -0
  27. package/dist/operations/webhooks.js +12 -0
  28. package/dist/tools/analytics.js +2 -0
  29. package/dist/tools/comments.js +99 -3
  30. package/dist/tools/compound-manager.js +7 -2
  31. package/dist/tools/compound.js +3 -0
  32. package/dist/tools/dev-resources.d.ts +2 -0
  33. package/dist/tools/dev-resources.js +78 -0
  34. package/dist/tools/org.js +203 -8
  35. package/dist/tools/permissions.js +3 -0
  36. package/dist/tools/register.d.ts +2 -1
  37. package/dist/tools/register.js +4 -1
  38. package/dist/tools/teams.js +53 -1
  39. package/dist/tools/webhooks.js +25 -2
  40. package/package.json +1 -1
package/dist/tools/org.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { z } from 'zod';
2
2
  import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
3
3
  import { formatApiError } from '../helpers.js';
4
- import { listAdmins, listOrgTeams, seatUsage, listTeamMembers, billingOverview, listInvoices, orgDomains, aiCreditUsage, exportMembers, listOrgMembers, contractRates, changeSeat, } from '../operations/org.js';
4
+ import { listAdmins, listOrgTeams, seatUsage, listTeamMembers, billingOverview, listInvoices, orgDomains, aiCreditUsage, exportMembers, listOrgMembers, contractRates, changeSeat, activityLog, listPayments, removeOrgMember, createUserGroup, deleteUserGroups, addUserGroupMembers, removeUserGroupMembers, } from '../operations/org.js';
5
5
  // -- list_admins --
6
6
  defineTool({
7
7
  toolset: 'org',
8
+ adminOnly: true,
8
9
  auth: 'cookie',
9
10
  register(server, config) {
10
11
  server.registerTool('list_admins', {
@@ -27,6 +28,7 @@ defineTool({
27
28
  // -- list_org_teams --
28
29
  defineTool({
29
30
  toolset: 'org',
31
+ adminOnly: true,
30
32
  auth: 'cookie',
31
33
  register(server, config) {
32
34
  server.registerTool('list_org_teams', {
@@ -49,6 +51,7 @@ defineTool({
49
51
  // -- seat_usage --
50
52
  defineTool({
51
53
  toolset: 'org',
54
+ adminOnly: true,
52
55
  auth: 'cookie',
53
56
  register(server, config) {
54
57
  server.registerTool('seat_usage', {
@@ -60,7 +63,7 @@ defineTool({
60
63
  }, async ({ org_id, search_query }) => {
61
64
  try {
62
65
  const result = await seatUsage(config, { org_id, search_query });
63
- return toolSummary('Seat usage breakdown:', result);
66
+ return toolSummary('Seat usage breakdown:', result, 'Use seat_optimization to find inactive seats, or change_seat to modify.');
64
67
  }
65
68
  catch (e) {
66
69
  return toolError(`Failed to fetch seat usage: ${formatApiError(e)}`);
@@ -71,6 +74,7 @@ defineTool({
71
74
  // -- list_team_members --
72
75
  defineTool({
73
76
  toolset: 'org',
77
+ adminOnly: true,
74
78
  auth: 'cookie',
75
79
  register(server, config) {
76
80
  server.registerTool('list_team_members', {
@@ -81,7 +85,7 @@ defineTool({
81
85
  }, async ({ team_id }) => {
82
86
  try {
83
87
  const result = await listTeamMembers(config, { team_id });
84
- return toolSummary(`${result.length} member(s).`, result);
88
+ return toolSummary(`${result.length} member(s).`, result, 'Use add_team_member or remove_team_member to manage membership.');
85
89
  }
86
90
  catch (e) {
87
91
  return toolError(`Failed to list team members: ${formatApiError(e)}`);
@@ -92,6 +96,7 @@ defineTool({
92
96
  // -- billing_overview --
93
97
  defineTool({
94
98
  toolset: 'org',
99
+ adminOnly: true,
95
100
  auth: 'cookie',
96
101
  register(server, config) {
97
102
  server.registerTool('billing_overview', {
@@ -102,7 +107,7 @@ defineTool({
102
107
  }, async ({ org_id }) => {
103
108
  try {
104
109
  const result = await billingOverview(config, { org_id });
105
- return toolSummary('Billing overview:', result);
110
+ return toolSummary('Billing overview:', result, 'Use list_invoices for open invoices, list_payments for payment history, or contract_rates for per-seat pricing.');
106
111
  }
107
112
  catch (e) {
108
113
  return toolError(`Failed to fetch billing overview: ${formatApiError(e)}`);
@@ -113,6 +118,7 @@ defineTool({
113
118
  // -- list_invoices --
114
119
  defineTool({
115
120
  toolset: 'org',
121
+ adminOnly: true,
116
122
  auth: 'cookie',
117
123
  register(server, config) {
118
124
  server.registerTool('list_invoices', {
@@ -134,6 +140,7 @@ defineTool({
134
140
  // -- org_domains --
135
141
  defineTool({
136
142
  toolset: 'org',
143
+ adminOnly: true,
137
144
  auth: 'cookie',
138
145
  register(server, config) {
139
146
  server.registerTool('org_domains', {
@@ -155,16 +162,18 @@ defineTool({
155
162
  // -- ai_credit_usage --
156
163
  defineTool({
157
164
  toolset: 'org',
165
+ adminOnly: true,
158
166
  auth: 'cookie',
159
167
  register(server, config) {
160
168
  server.registerTool('ai_credit_usage', {
161
- description: 'AI credit usage summary for a billing plan. Get the plan_id from billing_overview.',
169
+ description: 'AI credit usage summary. Provide a team_id and the plan is resolved automatically, or pass plan_id directly.',
162
170
  inputSchema: {
163
- plan_id: figmaId.describe('Plan ID (from billing_overview response)'),
171
+ team_id: figmaId.describe('Team ID (used to resolve the billing plan)'),
172
+ plan_id: figmaId.optional().describe('Plan ID override (skips team folder lookup)'),
164
173
  },
165
- }, async ({ plan_id }) => {
174
+ }, async ({ team_id, plan_id }) => {
166
175
  try {
167
- const result = await aiCreditUsage(config, { plan_id });
176
+ const result = await aiCreditUsage(config, { team_id, plan_id });
168
177
  return toolSummary('AI credit usage:', result);
169
178
  }
170
179
  catch (e) {
@@ -176,6 +185,7 @@ defineTool({
176
185
  // -- export_members --
177
186
  defineTool({
178
187
  toolset: 'org',
188
+ adminOnly: true,
179
189
  auth: 'cookie',
180
190
  mutates: true,
181
191
  register(server, config) {
@@ -198,6 +208,7 @@ defineTool({
198
208
  // -- list_org_members --
199
209
  defineTool({
200
210
  toolset: 'org',
211
+ adminOnly: true,
201
212
  auth: 'cookie',
202
213
  register(server, config) {
203
214
  server.registerTool('list_org_members', {
@@ -220,6 +231,7 @@ defineTool({
220
231
  // -- contract_rates --
221
232
  defineTool({
222
233
  toolset: 'org',
234
+ adminOnly: true,
223
235
  auth: 'cookie',
224
236
  register(server, config) {
225
237
  server.registerTool('contract_rates', {
@@ -241,6 +253,7 @@ defineTool({
241
253
  // -- change_seat --
242
254
  defineTool({
243
255
  toolset: 'org',
256
+ adminOnly: true,
244
257
  auth: 'cookie',
245
258
  mutates: true,
246
259
  destructive: true,
@@ -266,4 +279,186 @@ defineTool({
266
279
  });
267
280
  },
268
281
  });
282
+ // -- activity_log --
283
+ defineTool({
284
+ toolset: 'org',
285
+ adminOnly: true,
286
+ auth: 'cookie',
287
+ register(server, config) {
288
+ server.registerTool('activity_log', {
289
+ description: 'Org audit log. Shows who did what, when. Filter by email for per-user activity. Supports date ranges and cursor pagination.',
290
+ inputSchema: {
291
+ org_id: figmaId.optional().describe('Org ID override (defaults to current workspace)'),
292
+ emails: z.string().optional().describe('Comma-separated emails to filter (e.g. "alice@acme.com,bob@acme.com")'),
293
+ start_time: z.string().optional().describe('Start date (ISO or YYYY-MM-DD). Defaults to 30 days ago.'),
294
+ end_time: z.string().optional().describe('End date (ISO or YYYY-MM-DD). Defaults to now.'),
295
+ page_size: z.number().int().optional().describe('Entries per page (default: 50)'),
296
+ after: z.string().optional().describe('Pagination cursor from previous response'),
297
+ },
298
+ }, async ({ org_id, emails, start_time, end_time, page_size, after }) => {
299
+ try {
300
+ const result = await activityLog(config, { org_id, emails, start_time, end_time, page_size, after });
301
+ if (result.entries.length === 0)
302
+ return toolResult('No activity log entries found.');
303
+ const paginationNote = result.pagination
304
+ ? `\nMore results available. Pass after: "${result.pagination.after}" to get the next page.`
305
+ : '';
306
+ return toolSummary(`${result.entries.length} log entry/entries.${paginationNote}`, result.entries);
307
+ }
308
+ catch (e) {
309
+ return toolError(`Failed to fetch activity log: ${formatApiError(e)}`);
310
+ }
311
+ });
312
+ },
313
+ });
314
+ // -- list_payments --
315
+ defineTool({
316
+ toolset: 'org',
317
+ adminOnly: true,
318
+ auth: 'cookie',
319
+ register(server, config) {
320
+ server.registerTool('list_payments', {
321
+ description: 'List paid invoices / payment history for the org.',
322
+ inputSchema: {
323
+ org_id: figmaId.optional().describe('Org ID override (defaults to current workspace)'),
324
+ },
325
+ }, async ({ org_id }) => {
326
+ try {
327
+ const result = await listPayments(config, { org_id });
328
+ if (result.length === 0)
329
+ return toolResult('No paid invoices found.');
330
+ return toolSummary(`${result.length} paid invoice(s).`, result, 'Use billing_overview for current billing status, or list_invoices for open invoices.');
331
+ }
332
+ catch (e) {
333
+ return toolError(`Failed to list payments: ${formatApiError(e)}`);
334
+ }
335
+ });
336
+ },
337
+ });
338
+ // -- remove_org_member --
339
+ defineTool({
340
+ toolset: 'org',
341
+ adminOnly: true,
342
+ auth: 'cookie',
343
+ mutates: true,
344
+ destructive: true,
345
+ register(server, config) {
346
+ server.registerTool('remove_org_member', {
347
+ description: 'Permanently remove a member from the org. They lose all access to teams, projects, files, and apps. Cannot be undone. Requires confirm: true.',
348
+ inputSchema: {
349
+ user_identifier: z.string().describe('Email or user_id of the member to remove'),
350
+ org_id: figmaId.optional().describe('Org ID override (defaults to current workspace)'),
351
+ confirm: z.boolean().optional().describe('Must be true to execute. Without it, returns a warning explaining consequences.'),
352
+ },
353
+ }, async ({ user_identifier, org_id, confirm }) => {
354
+ try {
355
+ const msg = await removeOrgMember(config, { user_identifier, org_id, confirm });
356
+ return toolResult(msg);
357
+ }
358
+ catch (e) {
359
+ return toolError(`${formatApiError(e)}`);
360
+ }
361
+ });
362
+ },
363
+ });
364
+ // -- create_user_group --
365
+ defineTool({
366
+ toolset: 'org',
367
+ adminOnly: true,
368
+ auth: 'cookie',
369
+ mutates: true,
370
+ register(server, config) {
371
+ server.registerTool('create_user_group', {
372
+ description: 'Create a user group. Provide team_id to auto-resolve the billing plan, or pass plan_id directly.',
373
+ inputSchema: {
374
+ name: z.string().describe('Group name'),
375
+ description: z.string().optional().describe('Group description'),
376
+ team_id: figmaId.optional().describe('Team ID (used to resolve billing plan)'),
377
+ plan_id: figmaId.optional().describe('Plan ID override (skips team lookup)'),
378
+ emails: z.array(z.string()).optional().describe('Emails to add as initial members'),
379
+ should_notify: z.boolean().optional().describe('Notify members (default true)'),
380
+ },
381
+ }, async ({ name, description, team_id, plan_id, emails, should_notify }) => {
382
+ try {
383
+ const result = await createUserGroup(config, { name, description, team_id, plan_id, emails, should_notify });
384
+ return toolSummary(`User group "${name}" created.`, result, 'Use add_user_group_members to add members, or delete_user_groups to remove.');
385
+ }
386
+ catch (e) {
387
+ return toolError(`Failed to create user group: ${formatApiError(e)}`);
388
+ }
389
+ });
390
+ },
391
+ });
392
+ // -- delete_user_groups --
393
+ defineTool({
394
+ toolset: 'org',
395
+ adminOnly: true,
396
+ auth: 'cookie',
397
+ mutates: true,
398
+ destructive: true,
399
+ register(server, config) {
400
+ server.registerTool('delete_user_groups', {
401
+ description: 'Delete one or more user groups by ID.',
402
+ inputSchema: {
403
+ user_group_ids: z.array(figmaId).describe('User group IDs to delete'),
404
+ },
405
+ }, async ({ user_group_ids }) => {
406
+ try {
407
+ const msg = await deleteUserGroups(config, { user_group_ids });
408
+ return toolResult(msg);
409
+ }
410
+ catch (e) {
411
+ return toolError(`Failed to delete user groups: ${formatApiError(e)}`);
412
+ }
413
+ });
414
+ },
415
+ });
416
+ // -- add_user_group_members --
417
+ defineTool({
418
+ toolset: 'org',
419
+ adminOnly: true,
420
+ auth: 'cookie',
421
+ mutates: true,
422
+ register(server, config) {
423
+ server.registerTool('add_user_group_members', {
424
+ description: 'Add members to a user group by email.',
425
+ inputSchema: {
426
+ user_group_id: figmaId.describe('User group ID'),
427
+ emails: z.array(z.string()).describe('Email addresses to add'),
428
+ },
429
+ }, async ({ user_group_id, emails }) => {
430
+ try {
431
+ const result = await addUserGroupMembers(config, { user_group_id, emails });
432
+ return toolSummary(`Added ${emails.length} member(s) to group.`, result);
433
+ }
434
+ catch (e) {
435
+ return toolError(`Failed to add members to group: ${formatApiError(e)}`);
436
+ }
437
+ });
438
+ },
439
+ });
440
+ // -- remove_user_group_members --
441
+ defineTool({
442
+ toolset: 'org',
443
+ adminOnly: true,
444
+ auth: 'cookie',
445
+ mutates: true,
446
+ register(server, config) {
447
+ server.registerTool('remove_user_group_members', {
448
+ description: 'Remove members from a user group by user ID.',
449
+ inputSchema: {
450
+ user_group_id: figmaId.describe('User group ID'),
451
+ user_ids: z.array(z.string()).describe('User IDs to remove'),
452
+ },
453
+ }, async ({ user_group_id, user_ids }) => {
454
+ try {
455
+ const msg = await removeUserGroupMembers(config, { user_group_id, user_ids });
456
+ return toolResult(msg);
457
+ }
458
+ catch (e) {
459
+ return toolError(`Failed to remove members from group: ${formatApiError(e)}`);
460
+ }
461
+ });
462
+ },
463
+ });
269
464
  //# sourceMappingURL=org.js.map
@@ -106,6 +106,7 @@ defineTool({
106
106
  defineTool({
107
107
  toolset: 'permissions',
108
108
  auth: 'cookie',
109
+ adminOnly: true,
109
110
  register(server, config) {
110
111
  server.registerTool('list_role_requests', {
111
112
  description: 'List pending file access requests. These come through the notification system.',
@@ -128,6 +129,7 @@ defineTool({
128
129
  toolset: 'permissions',
129
130
  auth: 'cookie',
130
131
  mutates: true,
132
+ adminOnly: true,
131
133
  register(server, config) {
132
134
  server.registerTool('approve_role_request', {
133
135
  description: 'Approve a pending file access request by notification ID.',
@@ -150,6 +152,7 @@ defineTool({
150
152
  toolset: 'permissions',
151
153
  auth: 'cookie',
152
154
  mutates: true,
155
+ adminOnly: true,
153
156
  register(server, config) {
154
157
  server.registerTool('deny_role_request', {
155
158
  description: 'Decline a pending file access request by notification ID.',
@@ -10,10 +10,11 @@ export interface ToolDef {
10
10
  auth: AuthRequirement;
11
11
  mutates?: boolean;
12
12
  destructive?: boolean;
13
+ adminOnly?: boolean;
13
14
  register: (server: McpServer, config: AuthConfig) => void;
14
15
  }
15
16
  export declare function defineTool(def: ToolDef): void;
16
- export declare function registerTools(server: McpServer, config: AuthConfig, enabledToolsets: Set<Toolset>, readOnly: boolean): void;
17
+ export declare function registerTools(server: McpServer, config: AuthConfig, enabledToolsets: Set<Toolset>, readOnly: boolean, isAdmin?: boolean): void;
17
18
  export declare function toolResult(text: string): {
18
19
  content: Array<{
19
20
  type: 'text';
@@ -35,11 +35,14 @@ function withAnnotations(server, tool) {
35
35
  },
36
36
  });
37
37
  }
38
- export function registerTools(server, config, enabledToolsets, readOnly) {
38
+ export function registerTools(server, config, enabledToolsets, readOnly, isAdmin = true) {
39
39
  for (const tool of allTools) {
40
40
  // Filter by enabled toolsets
41
41
  if (!enabledToolsets.has(tool.toolset))
42
42
  continue;
43
+ // Filter admin-only tools for non-admin users
44
+ if (tool.adminOnly && !isAdmin)
45
+ continue;
43
46
  // Filter by read-only mode
44
47
  if (readOnly && tool.mutates)
45
48
  continue;
@@ -1,12 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
3
3
  import { formatApiError } from '../helpers.js';
4
- import { createTeam, renameTeam, deleteTeam } from '../operations/teams.js';
4
+ import { createTeam, renameTeam, deleteTeam, addTeamMember, removeTeamMember } from '../operations/teams.js';
5
5
  // -- create_team --
6
6
  defineTool({
7
7
  toolset: 'teams',
8
8
  auth: 'cookie',
9
9
  mutates: true,
10
+ adminOnly: true,
10
11
  register(server, config) {
11
12
  server.registerTool('create_team', {
12
13
  description: 'Create a new team in the org.',
@@ -54,6 +55,7 @@ defineTool({
54
55
  auth: 'cookie',
55
56
  mutates: true,
56
57
  destructive: true,
58
+ adminOnly: true,
57
59
  register(server, config) {
58
60
  server.registerTool('delete_team', {
59
61
  description: 'Permanently delete a team and all its projects/files. This cannot be undone. All team members lose access.',
@@ -71,4 +73,54 @@ defineTool({
71
73
  });
72
74
  },
73
75
  });
76
+ // -- add_team_member --
77
+ defineTool({
78
+ toolset: 'teams',
79
+ auth: 'cookie',
80
+ mutates: true,
81
+ adminOnly: true,
82
+ register(server, config) {
83
+ server.registerTool('add_team_member', {
84
+ description: 'Add a member to a team by email. Level: 100 = can view (default), 300 = can edit, 999 = admin.',
85
+ inputSchema: {
86
+ team_id: figmaId.describe('Team ID'),
87
+ email: z.string().describe('Email address of the user to add'),
88
+ level: z.number().int().optional().describe('Permission level: 100 = view (default), 300 = edit, 999 = admin'),
89
+ },
90
+ }, async ({ team_id, email, level }) => {
91
+ try {
92
+ const msg = await addTeamMember(config, { team_id, email, level });
93
+ return toolResult(msg);
94
+ }
95
+ catch (e) {
96
+ return toolError(`Failed to add team member: ${formatApiError(e)}`);
97
+ }
98
+ });
99
+ },
100
+ });
101
+ // -- remove_team_member --
102
+ defineTool({
103
+ toolset: 'teams',
104
+ auth: 'cookie',
105
+ mutates: true,
106
+ destructive: true,
107
+ adminOnly: true,
108
+ register(server, config) {
109
+ server.registerTool('remove_team_member', {
110
+ description: 'Remove a member from a team. The user loses access to all team projects and files.',
111
+ inputSchema: {
112
+ team_id: figmaId.describe('Team ID'),
113
+ user_id: figmaId.describe('User ID to remove'),
114
+ },
115
+ }, async ({ team_id, user_id }) => {
116
+ try {
117
+ const msg = await removeTeamMember(config, { team_id, user_id });
118
+ return toolResult(msg);
119
+ }
120
+ catch (e) {
121
+ return toolError(`Failed to remove team member: ${formatApiError(e)}`);
122
+ }
123
+ });
124
+ },
125
+ });
74
126
  //# sourceMappingURL=teams.js.map
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { defineTool, toolResult, toolError, toolSummary, figmaId } from './register.js';
3
3
  import { formatApiError } from '../helpers.js';
4
- import { listWebhooks, createWebhook, updateWebhook, deleteWebhook, } from '../operations/webhooks.js';
4
+ import { listWebhooks, createWebhook, updateWebhook, deleteWebhook, webhookRequests, } from '../operations/webhooks.js';
5
5
  const eventTypeEnum = z.enum([
6
6
  'FILE_UPDATE',
7
7
  'FILE_DELETE',
@@ -25,7 +25,7 @@ defineTool({
25
25
  const result = await listWebhooks(config, { team_id });
26
26
  if (result.count === 0)
27
27
  return toolResult('No webhooks configured for this team.');
28
- return toolSummary(`${result.count} webhook(s).`, result, 'Use create_webhook to add, or update_webhook/delete_webhook to manage.');
28
+ return toolSummary(`${result.count} webhook(s).`, result, 'Use webhook_requests to check delivery history, create_webhook to add, or update_webhook/delete_webhook to manage.');
29
29
  }
30
30
  catch (e) {
31
31
  return toolError(`Failed to list webhooks: ${formatApiError(e)}`);
@@ -86,6 +86,29 @@ defineTool({
86
86
  });
87
87
  },
88
88
  });
89
+ // -- webhook_requests --
90
+ defineTool({
91
+ toolset: 'webhooks',
92
+ auth: 'pat',
93
+ register(server, config) {
94
+ server.registerTool('webhook_requests', {
95
+ description: 'List recent webhook delivery attempts (last 7 days). Shows payload, response status, and errors.',
96
+ inputSchema: {
97
+ webhook_id: figmaId.describe('Webhook ID'),
98
+ },
99
+ }, async ({ webhook_id }) => {
100
+ try {
101
+ const result = await webhookRequests(config, { webhook_id });
102
+ if (result.count === 0)
103
+ return toolResult('No webhook deliveries in the last 7 days.');
104
+ return toolSummary(`${result.count} delivery attempt(s).`, result, 'Use update_webhook to fix failing endpoints.');
105
+ }
106
+ catch (e) {
107
+ return toolError(`Failed to list webhook requests: ${formatApiError(e)}`);
108
+ }
109
+ });
110
+ },
111
+ });
89
112
  // -- delete_webhook --
90
113
  defineTool({
91
114
  toolset: 'webhooks',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "figmanage",
3
3
  "mcpName": "io.github.dannykeane/figmanage",
4
- "version": "1.3.8",
4
+ "version": "1.4.1",
5
5
  "description": "MCP server for managing your Figma workspace from the terminal.",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",