@critical-path/mcp 0.8.0 → 0.9.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.
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { zodToJsonSchema } from 'zod-to-json-schema';
2
3
  import type { CriticalPathEngine } from '@critical-path/core';
3
4
  import type { CriticalPathClient } from '@critical-path/client';
4
5
 
@@ -9,6 +10,7 @@ export interface ToolDefinition<TParams = any, TResult = any> {
9
10
  title: string;
10
11
  description: string;
11
12
  zodSchema: z.ZodObject<any>;
13
+ /** JSON Schema shown to MCP clients. Generated from `zodSchema` by `defineTool`. */
12
14
  inputSchema: Record<string, unknown>;
13
15
  annotations?: {
14
16
  readOnlyHint?: boolean;
@@ -17,6 +19,17 @@ export interface ToolDefinition<TParams = any, TResult = any> {
17
19
  execute: (args: TParams, target: BackendContext, ambientContext?: { projectId?: string }) => Promise<TResult>;
18
20
  }
19
21
 
22
+ /**
23
+ * Declares a tool, generating its JSON Schema `inputSchema` from `zodSchema` so the schema the
24
+ * model sees and the one arguments are validated against cannot drift apart.
25
+ */
26
+ export function defineTool<TParams = any, TResult = any>(
27
+ spec: Omit<ToolDefinition<TParams, TResult>, 'inputSchema'>
28
+ ): ToolDefinition<TParams, TResult> {
29
+ const { $schema: _schema, ...inputSchema } = zodToJsonSchema(spec.zodSchema, { $refStrategy: 'none' }) as Record<string, unknown>;
30
+ return { ...spec, inputSchema };
31
+ }
32
+
20
33
  export class ToolArgumentError extends Error {
21
34
  constructor(toolName: string, details: string) {
22
35
  super(`Invalid arguments for tool "${toolName}": ${details}`);
@@ -45,44 +58,31 @@ export async function resolveBackend(target: BackendContext) {
45
58
  return { isEngine };
46
59
  }
47
60
 
48
- export const listProjectsTool: ToolDefinition = {
61
+ export const listProjectsTool = defineTool({
49
62
  name: 'list_projects',
50
63
  title: 'List Projects',
51
64
  description: 'Retrieve all projects in the workspace.',
52
65
  zodSchema: z.object({}),
53
- inputSchema: {
54
- type: 'object',
55
- properties: {},
56
- additionalProperties: false
57
- },
58
66
  annotations: { readOnlyHint: true },
59
67
  execute: async (_args, target) => {
60
68
  return target.getProjects();
61
69
  }
62
- };
70
+ });
63
71
 
64
- export const getProjectTool: ToolDefinition<{ id: string }> = {
72
+ export const getProjectTool = defineTool<{ id: string }>({
65
73
  name: 'get_project',
66
74
  title: 'Get Project',
67
75
  description: 'Get details of a specific project by its ID.',
68
76
  zodSchema: z.object({
69
77
  id: z.string().describe('The project ID')
70
78
  }),
71
- inputSchema: {
72
- type: 'object',
73
- properties: {
74
- id: { type: 'string', description: 'The project ID' }
75
- },
76
- required: ['id'],
77
- additionalProperties: false
78
- },
79
79
  annotations: { readOnlyHint: true },
80
80
  execute: async (args, target) => {
81
81
  return target.getProject(args.id);
82
82
  }
83
- };
83
+ });
84
84
 
85
- export const createProjectTool: ToolDefinition<{ name: string; description?: string; key?: string }> = {
85
+ export const createProjectTool = defineTool<{ name: string; description?: string; key?: string }>({
86
86
  name: 'create_project',
87
87
  title: 'Create Project',
88
88
  description: 'Create a new project workspace.',
@@ -91,27 +91,17 @@ export const createProjectTool: ToolDefinition<{ name: string; description?: str
91
91
  description: z.string().optional().describe('Description of the project'),
92
92
  key: z.string().optional().describe('Short project key/prefix (e.g. "PROJ")')
93
93
  }),
94
- inputSchema: {
95
- type: 'object',
96
- properties: {
97
- name: { type: 'string', description: 'Name of the project' },
98
- description: { type: 'string', description: 'Description of the project' },
99
- key: { type: 'string', description: 'Short project key/prefix (e.g. "PROJ")' }
100
- },
101
- required: ['name'],
102
- additionalProperties: false
103
- },
104
94
  execute: async (args, target) => {
105
95
  return target.createProject(args);
106
96
  }
107
- };
97
+ });
108
98
 
109
- export const listTasksTool: ToolDefinition<{
99
+ export const listTasksTool = defineTool<{
110
100
  projectId?: string;
111
101
  status?: string;
112
102
  priority?: string;
113
103
  assigneeId?: string;
114
- }> = {
104
+ }>({
115
105
  name: 'list_tasks',
116
106
  title: 'List Tasks',
117
107
  description: 'List tasks, optionally filtered by project, status, priority, or assignee.',
@@ -121,20 +111,6 @@ export const listTasksTool: ToolDefinition<{
121
111
  priority: z.enum(['urgent', 'high', 'medium', 'low', 'none']).optional().describe('Filter by priority'),
122
112
  assigneeId: z.string().optional().describe('Filter by assignee ID')
123
113
  }),
124
- inputSchema: {
125
- type: 'object',
126
- properties: {
127
- projectId: { type: 'string', description: 'Filter by project ID' },
128
- status: { type: 'string', description: 'Filter by task status key' },
129
- priority: {
130
- type: 'string',
131
- enum: ['urgent', 'high', 'medium', 'low', 'none'],
132
- description: 'Filter by priority'
133
- },
134
- assigneeId: { type: 'string', description: 'Filter by assignee ID' }
135
- },
136
- additionalProperties: false
137
- },
138
114
  annotations: { readOnlyHint: true },
139
115
  execute: async (args, target, ambientContext) => {
140
116
  const projectId = args.projectId || ambientContext?.projectId;
@@ -150,30 +126,22 @@ export const listTasksTool: ToolDefinition<{
150
126
  }
151
127
  return tasks;
152
128
  }
153
- };
129
+ });
154
130
 
155
- export const getTaskTool: ToolDefinition<{ id: string }> = {
131
+ export const getTaskTool = defineTool<{ id: string }>({
156
132
  name: 'get_task',
157
133
  title: 'Get Task',
158
134
  description: 'Get task details by ID.',
159
135
  zodSchema: z.object({
160
136
  id: z.string().describe('The task ID')
161
137
  }),
162
- inputSchema: {
163
- type: 'object',
164
- properties: {
165
- id: { type: 'string', description: 'The task ID' }
166
- },
167
- required: ['id'],
168
- additionalProperties: false
169
- },
170
138
  annotations: { readOnlyHint: true },
171
139
  execute: async (args, target) => {
172
140
  return target.getTask(args.id);
173
141
  }
174
- };
142
+ });
175
143
 
176
- export const createTaskTool: ToolDefinition<{
144
+ export const createTaskTool = defineTool<{
177
145
  projectId?: string;
178
146
  title: string;
179
147
  description?: string;
@@ -185,7 +153,7 @@ export const createTaskTool: ToolDefinition<{
185
153
  estimatedHours?: number;
186
154
  isBlocked?: boolean;
187
155
  blockedReason?: string;
188
- }> = {
156
+ }>({
189
157
  name: 'create_task',
190
158
  title: 'Create Task',
191
159
  description: 'Create a new task within a project.',
@@ -202,24 +170,6 @@ export const createTaskTool: ToolDefinition<{
202
170
  isBlocked: z.boolean().optional().describe('Whether the task is blocked'),
203
171
  blockedReason: z.string().optional().describe('Reason why the task is blocked')
204
172
  }),
205
- inputSchema: {
206
- type: 'object',
207
- properties: {
208
- projectId: { type: 'string', description: 'Project ID (inferred from active view if omitted)' },
209
- title: { type: 'string', description: 'Title of the task' },
210
- description: { type: 'string', description: 'Detailed description' },
211
- status: { type: 'string', description: 'Status key' },
212
- priority: { type: 'string', enum: ['urgent', 'high', 'medium', 'low', 'none'] },
213
- assigneeId: { type: 'string', description: 'User ID of assignee' },
214
- dueDate: { type: 'string', description: 'Due date in ISO 8601 format' },
215
- tags: { type: 'array', items: { type: 'string' } },
216
- estimatedHours: { type: 'number' },
217
- isBlocked: { type: 'boolean', description: 'Whether the task is blocked' },
218
- blockedReason: { type: 'string', description: 'Reason why the task is blocked' }
219
- },
220
- required: ['title'],
221
- additionalProperties: false
222
- },
223
173
  execute: async (args, target, ambientContext) => {
224
174
  const projectId = args.projectId || ambientContext?.projectId;
225
175
  if (!projectId) {
@@ -240,9 +190,9 @@ export const createTaskTool: ToolDefinition<{
240
190
  };
241
191
  return target.createTask(input);
242
192
  }
243
- };
193
+ });
244
194
 
245
- export const updateTaskTool: ToolDefinition<{
195
+ export const updateTaskTool = defineTool<{
246
196
  id: string;
247
197
  title?: string;
248
198
  description?: string;
@@ -255,7 +205,7 @@ export const updateTaskTool: ToolDefinition<{
255
205
  loggedHours?: number;
256
206
  isBlocked?: boolean;
257
207
  blockedReason?: string;
258
- }> = {
208
+ }>({
259
209
  name: 'update_task',
260
210
  title: 'Update Task',
261
211
  description: 'Update fields of an existing task (e.g. title, status, priority, assignee).',
@@ -270,70 +220,36 @@ export const updateTaskTool: ToolDefinition<{
270
220
  tags: z.array(z.string()).optional(),
271
221
  estimatedHours: z.number().optional(),
272
222
  loggedHours: z.number().optional(),
273
- isBlocked: z.boolean().optional(),
274
- blockedReason: z.string().optional()
223
+ isBlocked: z.boolean().optional().describe('Whether the task is blocked'),
224
+ blockedReason: z.string().optional().describe('Reason why the task is blocked')
275
225
  }),
276
- inputSchema: {
277
- type: 'object',
278
- properties: {
279
- id: { type: 'string', description: 'Task ID' },
280
- title: { type: 'string' },
281
- description: { type: 'string' },
282
- status: { type: 'string' },
283
- priority: { type: 'string', enum: ['urgent', 'high', 'medium', 'low', 'none'] },
284
- assigneeId: { type: 'string' },
285
- dueDate: { type: 'string' },
286
- tags: { type: 'array', items: { type: 'string' } },
287
- estimatedHours: { type: 'number' },
288
- loggedHours: { type: 'number' },
289
- isBlocked: { type: 'boolean', description: 'Whether the task is blocked' },
290
- blockedReason: { type: 'string', description: 'Reason why the task is blocked' }
291
- },
292
- required: ['id'],
293
- additionalProperties: false
294
- },
295
226
  execute: async (args, target) => {
296
227
  const { id, ...updates } = args;
297
228
  return target.updateTask(id, updates);
298
229
  }
299
- };
230
+ });
300
231
 
301
- export const deleteTaskTool: ToolDefinition<{ id: string }> = {
232
+ export const deleteTaskTool = defineTool<{ id: string }>({
302
233
  name: 'delete_task',
303
234
  title: 'Delete Task',
304
235
  description: 'Delete a task by ID.',
305
236
  zodSchema: z.object({
306
237
  id: z.string().describe('The task ID to delete')
307
238
  }),
308
- inputSchema: {
309
- type: 'object',
310
- properties: {
311
- id: { type: 'string', description: 'The task ID' }
312
- },
313
- required: ['id'],
314
- additionalProperties: false
315
- },
316
239
  annotations: { requiresConfirmation: true },
317
240
  execute: async (args, target) => {
318
241
  const success = await target.deleteTask(args.id);
319
242
  return { success };
320
243
  }
321
- };
244
+ });
322
245
 
323
- export const listDeliverablesTool: ToolDefinition<{ projectId?: string }> = {
246
+ export const listDeliverablesTool = defineTool<{ projectId?: string }>({
324
247
  name: 'list_deliverables',
325
248
  title: 'List Deliverables',
326
249
  description: 'List deliverables/milestones for a project.',
327
250
  zodSchema: z.object({
328
251
  projectId: z.string().optional().describe('Project ID')
329
252
  }),
330
- inputSchema: {
331
- type: 'object',
332
- properties: {
333
- projectId: { type: 'string', description: 'Project ID' }
334
- },
335
- additionalProperties: false
336
- },
337
253
  annotations: { readOnlyHint: true },
338
254
  execute: async (args, target, ambientContext) => {
339
255
  const projectId = args.projectId || ambientContext?.projectId;
@@ -343,15 +259,15 @@ export const listDeliverablesTool: ToolDefinition<{ projectId?: string }> = {
343
259
  }
344
260
  return [];
345
261
  }
346
- };
262
+ });
347
263
 
348
- export const createDeliverableTool: ToolDefinition<{
264
+ export const createDeliverableTool = defineTool<{
349
265
  projectId?: string;
350
266
  title: string;
351
267
  description?: string;
352
268
  dueDate?: string;
353
269
  taskIds?: string[];
354
- }> = {
270
+ }>({
355
271
  name: 'create_deliverable',
356
272
  title: 'Create Deliverable',
357
273
  description: 'Create a milestone deliverable within a project.',
@@ -362,18 +278,6 @@ export const createDeliverableTool: ToolDefinition<{
362
278
  dueDate: z.string().optional(),
363
279
  taskIds: z.array(z.string()).optional()
364
280
  }),
365
- inputSchema: {
366
- type: 'object',
367
- properties: {
368
- projectId: { type: 'string' },
369
- title: { type: 'string' },
370
- description: { type: 'string' },
371
- dueDate: { type: 'string' },
372
- taskIds: { type: 'array', items: { type: 'string' } }
373
- },
374
- required: ['title'],
375
- additionalProperties: false
376
- },
377
281
  execute: async (args, target, ambientContext) => {
378
282
  const projectId = args.projectId || ambientContext?.projectId;
379
283
  if (!projectId) throw new Error('projectId is required to create a deliverable.');
@@ -385,23 +289,15 @@ export const createDeliverableTool: ToolDefinition<{
385
289
  }
386
290
  throw new Error('createDeliverable is not supported by this backend target.');
387
291
  }
388
- };
292
+ });
389
293
 
390
- export const listCommentsTool: ToolDefinition<{ taskId: string }> = {
294
+ export const listCommentsTool = defineTool<{ taskId: string }>({
391
295
  name: 'list_comments',
392
296
  title: 'List Comments',
393
297
  description: 'List comments associated with a task.',
394
298
  zodSchema: z.object({
395
299
  taskId: z.string().describe('The task ID')
396
300
  }),
397
- inputSchema: {
398
- type: 'object',
399
- properties: {
400
- taskId: { type: 'string', description: 'The task ID' }
401
- },
402
- required: ['taskId'],
403
- additionalProperties: false
404
- },
405
301
  annotations: { readOnlyHint: true },
406
302
  execute: async (args, target) => {
407
303
  if ('getComments' in target && typeof (target as any).getComments === 'function') {
@@ -409,9 +305,9 @@ export const listCommentsTool: ToolDefinition<{ taskId: string }> = {
409
305
  }
410
306
  return [];
411
307
  }
412
- };
308
+ });
413
309
 
414
- export const addCommentTool: ToolDefinition<{ taskId: string; content: string; authorId: string }> = {
310
+ export const addCommentTool = defineTool<{ taskId: string; content: string; authorId: string }>({
415
311
  name: 'add_comment',
416
312
  title: 'Add Comment',
417
313
  description: 'Add a comment to a task.',
@@ -420,16 +316,6 @@ export const addCommentTool: ToolDefinition<{ taskId: string; content: string; a
420
316
  content: z.string().describe('Comment body/markdown'),
421
317
  authorId: z.string().describe('Author user ID')
422
318
  }),
423
- inputSchema: {
424
- type: 'object',
425
- properties: {
426
- taskId: { type: 'string', description: 'The task ID' },
427
- content: { type: 'string', description: 'Comment body/markdown' },
428
- authorId: { type: 'string', description: 'Author user ID' }
429
- },
430
- required: ['taskId', 'content', 'authorId'],
431
- additionalProperties: false
432
- },
433
319
  execute: async (args, target) => {
434
320
  return (target as any).addComment({
435
321
  taskId: args.taskId,
@@ -437,22 +323,15 @@ export const addCommentTool: ToolDefinition<{ taskId: string; content: string; a
437
323
  authorId: args.authorId
438
324
  });
439
325
  }
440
- };
326
+ });
441
327
 
442
- export const calculateCriticalPathTool: ToolDefinition<{ projectId?: string }> = {
328
+ export const calculateCriticalPathTool = defineTool<{ projectId?: string }>({
443
329
  name: 'calculate_critical_path',
444
330
  title: 'Calculate Critical Path',
445
331
  description: 'Calculate Critical Path Method (CPM) schedule, early/late start and finish, total slack, and critical bottlenecks for a project.',
446
332
  zodSchema: z.object({
447
333
  projectId: z.string().optional().describe('Project ID (falls back to ambient context if omitted)')
448
334
  }),
449
- inputSchema: {
450
- type: 'object',
451
- properties: {
452
- projectId: { type: 'string', description: 'Project ID (falls back to ambient context if omitted)' }
453
- },
454
- additionalProperties: false
455
- },
456
335
  annotations: { readOnlyHint: true },
457
336
  execute: async (args, target, ambientContext) => {
458
337
  const projectId = args.projectId || ambientContext?.projectId;
@@ -461,14 +340,14 @@ export const calculateCriticalPathTool: ToolDefinition<{ projectId?: string }> =
461
340
  }
462
341
  return (target as any).calculateCriticalPath(projectId);
463
342
  }
464
- };
343
+ });
465
344
 
466
- export const getTimelineLadderTool: ToolDefinition<{
345
+ export const getTimelineLadderTool = defineTool<{
467
346
  projectId?: string;
468
347
  level?: 'macro' | 'standard' | 'concrete' | 'all';
469
348
  containerId?: string;
470
349
  iterationId?: string;
471
- }> = {
350
+ }>({
472
351
  name: 'get_timeline_ladder',
473
352
  title: 'Get Timeline Ladder of Abstraction',
474
353
  description: 'Retrieve Ladder of Abstraction for a project timeline across macro phase envelopes, standard Gantt tasks & CPM, and concrete deliverables/time/attachments.',
@@ -478,16 +357,6 @@ export const getTimelineLadderTool: ToolDefinition<{
478
357
  containerId: z.string().optional().describe('Optional container ID filter'),
479
358
  iterationId: z.string().optional().describe('Optional iteration/sprint ID filter')
480
359
  }),
481
- inputSchema: {
482
- type: 'object',
483
- properties: {
484
- projectId: { type: 'string', description: 'Project ID (falls back to ambient context if omitted)' },
485
- level: { type: 'string', enum: ['macro', 'standard', 'concrete', 'all'], description: 'Abstraction level' },
486
- containerId: { type: 'string', description: 'Optional container ID filter' },
487
- iterationId: { type: 'string', description: 'Optional iteration/sprint ID filter' }
488
- },
489
- additionalProperties: false
490
- },
491
360
  annotations: { readOnlyHint: true },
492
361
  execute: async (args, target, ambientContext) => {
493
362
  const projectId = args.projectId || ambientContext?.projectId;
@@ -500,72 +369,48 @@ export const getTimelineLadderTool: ToolDefinition<{
500
369
  iterationId: args.iterationId
501
370
  });
502
371
  }
503
- };
372
+ });
504
373
 
505
- export const getTaskLadderTool: ToolDefinition<{ taskId: string }> = {
374
+ export const getTaskLadderTool = defineTool<{ taskId: string }>({
506
375
  name: 'get_task_ladder',
507
376
  title: 'Get Task Ladder View',
508
377
  description: 'Retrieve multi-scale ladder view for a single task, connecting its macro phase, standard CPM timeline position, and concrete work evidence.',
509
378
  zodSchema: z.object({
510
379
  taskId: z.string().describe('The task ID')
511
380
  }),
512
- inputSchema: {
513
- type: 'object',
514
- properties: {
515
- taskId: { type: 'string', description: 'The task ID' }
516
- },
517
- required: ['taskId'],
518
- additionalProperties: false
519
- },
520
381
  annotations: { readOnlyHint: true },
521
382
  execute: async (args, target) => {
522
383
  return (target as any).getTaskLadder(args.taskId);
523
384
  }
524
- };
385
+ });
525
386
 
526
- export const getTaskMetricsTool: ToolDefinition<{ taskId: string }> = {
387
+ export const getTaskMetricsTool = defineTool<{ taskId: string }>({
527
388
  name: 'get_task_metrics',
528
389
  title: 'Get Task Metrics',
529
390
  description: 'Retrieve multi-dimensional task metrics including inferred actuals, active working duration, effort/duration/schedule variances, progress inference, and Earned Value Management (EVM) metrics.',
530
391
  zodSchema: z.object({
531
392
  taskId: z.string().describe('The task ID')
532
393
  }),
533
- inputSchema: {
534
- type: 'object',
535
- properties: {
536
- taskId: { type: 'string', description: 'The task ID' }
537
- },
538
- required: ['taskId'],
539
- additionalProperties: false
540
- },
541
394
  annotations: { readOnlyHint: true },
542
395
  execute: async (args, target) => {
543
396
  return (target as any).getTaskMetrics(args.taskId);
544
397
  }
545
- };
398
+ });
546
399
 
547
- export const getTaskProgressHistoryTool: ToolDefinition<{ taskId: string }> = {
400
+ export const getTaskProgressHistoryTool = defineTool<{ taskId: string }>({
548
401
  name: 'get_task_progress_history',
549
402
  title: 'Get Task Progress History',
550
403
  description: 'Retrieve time-series progress data points and curve shape classification (linear, s_curve, early_surge, late_rush, stalled) for a task.',
551
404
  zodSchema: z.object({
552
405
  taskId: z.string().describe('The task ID')
553
406
  }),
554
- inputSchema: {
555
- type: 'object',
556
- properties: {
557
- taskId: { type: 'string', description: 'The task ID' }
558
- },
559
- required: ['taskId'],
560
- additionalProperties: false
561
- },
562
407
  annotations: { readOnlyHint: true },
563
408
  execute: async (args, target) => {
564
409
  return (target as any).getTaskProgressHistory(args.taskId);
565
410
  }
566
- };
411
+ });
567
412
 
568
- export const getWorkloadDistributionTool: ToolDefinition<{
413
+ export const getWorkloadDistributionTool = defineTool<{
569
414
  projectId?: string;
570
415
  startDate?: string;
571
416
  endDate?: string;
@@ -573,7 +418,7 @@ export const getWorkloadDistributionTool: ToolDefinition<{
573
418
  groupBy?: 'assignee' | 'team' | 'taskType' | 'priority' | 'status';
574
419
  metric?: 'scheduled' | 'logged' | 'remaining' | 'blended';
575
420
  defaultWeeklyCapacityHours?: number;
576
- }> = {
421
+ }>({
577
422
  name: 'get_workload_distribution',
578
423
  title: 'Get Workload Distribution',
579
424
  description: 'Retrieve time-series workload and capacity distribution suitable for streamgraphs, stacked charts, and team capacity planning.',
@@ -586,19 +431,6 @@ export const getWorkloadDistributionTool: ToolDefinition<{
586
431
  metric: z.enum(['scheduled', 'logged', 'remaining', 'blended']).optional().describe('Effort metric mode'),
587
432
  defaultWeeklyCapacityHours: z.number().optional().describe('Default weekly capacity hours per person (default 40)')
588
433
  }),
589
- inputSchema: {
590
- type: 'object',
591
- properties: {
592
- projectId: { type: 'string', description: 'Project ID (optional, defaults to workspace-wide or ambient project)' },
593
- startDate: { type: 'string', description: 'Start date ISO (YYYY-MM-DD)' },
594
- endDate: { type: 'string', description: 'End date ISO (YYYY-MM-DD)' },
595
- interval: { type: 'string', enum: ['day', 'week', 'month'], description: 'Bucket interval' },
596
- groupBy: { type: 'string', enum: ['assignee', 'team', 'taskType', 'priority', 'status'], description: 'Dimension to segment by' },
597
- metric: { type: 'string', enum: ['scheduled', 'logged', 'remaining', 'blended'], description: 'Effort metric mode' },
598
- defaultWeeklyCapacityHours: { type: 'number', description: 'Default weekly capacity hours per person' }
599
- },
600
- additionalProperties: false
601
- },
602
434
  annotations: { readOnlyHint: true },
603
435
  execute: async (args, target, ambientContext) => {
604
436
  const projectId = args.projectId || ambientContext?.projectId;
@@ -611,7 +443,7 @@ export const getWorkloadDistributionTool: ToolDefinition<{
611
443
  defaultWeeklyCapacityHours: args.defaultWeeklyCapacityHours
612
444
  });
613
445
  }
614
- };
446
+ });
615
447
 
616
448
  export const ALL_TOOLS: ToolDefinition[] = [
617
449
  listProjectsTool,