@taazkareem/clickup-mcp-server 0.6.3 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build/config.js +2 -3
- package/build/index.js +17 -33
- package/build/logger.js +5 -6
- package/build/server.js +33 -15
- package/build/services/clickup/bulk.js +92 -81
- package/build/services/clickup/task/task-core.js +18 -56
- package/build/tools/tag.js +7 -14
- package/build/tools/task/attachments.js +16 -16
- package/build/tools/task/bulk-operations.js +68 -100
- package/build/tools/task/handlers.js +51 -33
- package/build/tools/task/main.js +125 -31
- package/build/tools/task/single-operations.js +49 -58
- package/build/tools/task/utilities.js +23 -4
- package/build/tools/task/workspace-operations.js +8 -15
- package/package.json +1 -1
|
@@ -52,17 +52,16 @@ export const createTaskTool = {
|
|
|
52
52
|
|
|
53
53
|
Valid Usage:
|
|
54
54
|
1. Provide listId (preferred if available)
|
|
55
|
-
2. Provide listName (
|
|
55
|
+
2. Provide listName (will look up the list ID)
|
|
56
56
|
|
|
57
57
|
Requirements:
|
|
58
58
|
- name: REQUIRED
|
|
59
|
-
- EITHER listId OR listName
|
|
59
|
+
- List identification: EITHER listId OR listName REQUIRED
|
|
60
60
|
|
|
61
61
|
Notes:
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
- Custom fields can be set using the custom_fields parameter (array of {id, value} objects)`,
|
|
62
|
+
- Use create_bulk_tasks for multiple tasks
|
|
63
|
+
- Set parent parameter to create a subtask
|
|
64
|
+
- Custom fields can be set via custom_fields parameter`,
|
|
66
65
|
inputSchema: {
|
|
67
66
|
type: "object",
|
|
68
67
|
properties: {
|
|
@@ -145,31 +144,31 @@ export const updateTaskTool = {
|
|
|
145
144
|
description: `Purpose: Modify properties of an existing task.
|
|
146
145
|
|
|
147
146
|
Valid Usage:
|
|
148
|
-
1. Use taskId
|
|
149
|
-
2. Use taskName + listName
|
|
147
|
+
1. Use taskId (preferred) - works with both regular and custom IDs
|
|
148
|
+
2. Use taskName + listName for targeted search
|
|
150
149
|
|
|
151
150
|
Requirements:
|
|
152
|
-
-
|
|
153
|
-
-
|
|
151
|
+
- Task identification: EITHER taskId OR taskName REQUIRED
|
|
152
|
+
- Updates: At least one update field (name, description, status, priority, dueDate) REQUIRED
|
|
154
153
|
|
|
155
154
|
Notes:
|
|
156
155
|
- Only specified fields will be updated
|
|
157
|
-
-
|
|
158
|
-
-
|
|
156
|
+
- Custom fields can be set using the custom_fields parameter
|
|
157
|
+
- Using taskName without listName may match multiple tasks`,
|
|
159
158
|
inputSchema: {
|
|
160
159
|
type: "object",
|
|
161
160
|
properties: {
|
|
162
161
|
taskId: {
|
|
163
162
|
type: "string",
|
|
164
|
-
description: "ID of
|
|
163
|
+
description: "ID of task to update (preferred). Works with both regular task IDs (9 characters) and custom IDs with uppercase prefixes (like 'DEV-1234')."
|
|
165
164
|
},
|
|
166
165
|
taskName: {
|
|
167
166
|
type: "string",
|
|
168
|
-
description: "Name of
|
|
167
|
+
description: "Name of task to update. The tool will search for tasks with this name across all lists unless listName is specified."
|
|
169
168
|
},
|
|
170
169
|
listName: {
|
|
171
170
|
type: "string",
|
|
172
|
-
description: "Name of
|
|
171
|
+
description: "Optional: Name of list containing the task. Providing this narrows the search to a specific list, improving performance and reducing ambiguity."
|
|
173
172
|
},
|
|
174
173
|
name: {
|
|
175
174
|
type: "string",
|
|
@@ -228,16 +227,15 @@ export const moveTaskTool = {
|
|
|
228
227
|
description: `Purpose: Move a task to a different list.
|
|
229
228
|
|
|
230
229
|
Valid Usage:
|
|
231
|
-
1. Use taskId +
|
|
232
|
-
2. Use taskName + sourceListName +
|
|
230
|
+
1. Use taskId + destination list (preferred)
|
|
231
|
+
2. Use taskName + sourceListName + destination list
|
|
233
232
|
|
|
234
233
|
Requirements:
|
|
235
|
-
-
|
|
236
|
-
-
|
|
234
|
+
- Task identification: EITHER taskId OR (taskName + sourceListName) REQUIRED
|
|
235
|
+
- Destination: EITHER listId OR listName REQUIRED
|
|
237
236
|
|
|
238
237
|
Warning:
|
|
239
|
-
- Task statuses may reset if destination list has different status options
|
|
240
|
-
- System cannot find a task by name without knowing which list to search in`,
|
|
238
|
+
- Task statuses may reset if destination list has different status options`,
|
|
241
239
|
inputSchema: {
|
|
242
240
|
type: "object",
|
|
243
241
|
properties: {
|
|
@@ -273,18 +271,15 @@ export const duplicateTaskTool = {
|
|
|
273
271
|
description: `Purpose: Create a copy of a task in the same or different list.
|
|
274
272
|
|
|
275
273
|
Valid Usage:
|
|
276
|
-
1. Use taskId
|
|
277
|
-
2. Use taskName + sourceListName
|
|
274
|
+
1. Use taskId (preferred)
|
|
275
|
+
2. Use taskName + sourceListName
|
|
278
276
|
|
|
279
277
|
Requirements:
|
|
280
|
-
-
|
|
278
|
+
- Task identification: EITHER taskId OR (taskName + sourceListName) REQUIRED
|
|
279
|
+
- Destination: OPTIONAL - defaults to original list
|
|
281
280
|
|
|
282
281
|
Notes:
|
|
283
|
-
- The duplicate preserves the original task's properties
|
|
284
|
-
- If no destination list specified, uses same list as original task
|
|
285
|
-
|
|
286
|
-
Warning:
|
|
287
|
-
- System cannot find a task by name without knowing which list to search in`,
|
|
282
|
+
- The duplicate preserves the original task's properties`,
|
|
288
283
|
inputSchema: {
|
|
289
284
|
type: "object",
|
|
290
285
|
properties: {
|
|
@@ -320,18 +315,14 @@ export const getTaskTool = {
|
|
|
320
315
|
description: `Purpose: Retrieve detailed information about a specific task.
|
|
321
316
|
|
|
322
317
|
Valid Usage:
|
|
323
|
-
1. Use taskId
|
|
324
|
-
2. Use taskName + listName
|
|
325
|
-
3. Use customTaskId for explicit custom ID lookup
|
|
318
|
+
1. Use taskId (preferred) - works with both regular and custom IDs
|
|
319
|
+
2. Use taskName + listName for targeted search
|
|
326
320
|
|
|
327
321
|
Requirements:
|
|
328
|
-
-
|
|
329
|
-
- When using customTaskId, listName is recommended for faster lookup
|
|
322
|
+
- Task identification: EITHER taskId OR (taskName + listName) REQUIRED
|
|
330
323
|
|
|
331
|
-
|
|
332
|
-
- Task names are only unique within a list
|
|
333
|
-
- Regular task IDs are always 9 characters long (e.g., "86b394eqa")
|
|
334
|
-
- Custom IDs have an uppercase prefix followed by a hyphen and number (e.g., "DEV-1234")
|
|
324
|
+
Notes:
|
|
325
|
+
- Task names are only unique within a list
|
|
335
326
|
- Set subtasks=true to include all subtasks in the response`,
|
|
336
327
|
inputSchema: {
|
|
337
328
|
type: "object",
|
|
@@ -356,8 +347,7 @@ Note:
|
|
|
356
347
|
type: "boolean",
|
|
357
348
|
description: "Whether to include subtasks in the response. Set to true to retrieve full details of all subtasks."
|
|
358
349
|
}
|
|
359
|
-
}
|
|
360
|
-
required: []
|
|
350
|
+
}
|
|
361
351
|
}
|
|
362
352
|
};
|
|
363
353
|
/**
|
|
@@ -372,12 +362,11 @@ Valid Usage:
|
|
|
372
362
|
2. Use listName
|
|
373
363
|
|
|
374
364
|
Requirements:
|
|
375
|
-
- EITHER listId OR listName
|
|
365
|
+
- List identification: EITHER listId OR listName REQUIRED
|
|
376
366
|
|
|
377
367
|
Notes:
|
|
378
|
-
- Use filters (archived, statuses
|
|
379
|
-
- Pagination
|
|
380
|
-
- Sorting available through order_by and reverse parameters`,
|
|
368
|
+
- Use filters (archived, statuses) to narrow down results
|
|
369
|
+
- Pagination and sorting available`,
|
|
381
370
|
inputSchema: {
|
|
382
371
|
type: "object",
|
|
383
372
|
properties: {
|
|
@@ -427,12 +416,14 @@ export const getTaskCommentsTool = {
|
|
|
427
416
|
|
|
428
417
|
Valid Usage:
|
|
429
418
|
1. Use taskId (preferred)
|
|
430
|
-
2. Use taskName +
|
|
419
|
+
2. Use taskName + listName for targeted search
|
|
420
|
+
|
|
421
|
+
Requirements:
|
|
422
|
+
- Task identification: EITHER taskId OR taskName REQUIRED
|
|
431
423
|
|
|
432
424
|
Notes:
|
|
433
|
-
- If using taskName, providing listName helps locate the correct task
|
|
434
425
|
- Task names may not be unique across different lists
|
|
435
|
-
- Use start
|
|
426
|
+
- Use start/startId parameters for pagination`,
|
|
436
427
|
inputSchema: {
|
|
437
428
|
type: "object",
|
|
438
429
|
properties: {
|
|
@@ -471,13 +462,11 @@ Valid Usage:
|
|
|
471
462
|
2. Use taskName + listName
|
|
472
463
|
|
|
473
464
|
Requirements:
|
|
474
|
-
- EITHER taskId OR (taskName + listName)
|
|
475
|
-
- commentText
|
|
465
|
+
- Task identification: EITHER taskId OR (taskName + listName) REQUIRED
|
|
466
|
+
- commentText: REQUIRED
|
|
476
467
|
|
|
477
468
|
Notes:
|
|
478
|
-
-
|
|
479
|
-
- Set notifyAll to true to send notifications to all task assignees
|
|
480
|
-
- Use assignee to assign the comment to a specific user (optional)`,
|
|
469
|
+
- Set notifyAll=true to notify all task assignees`,
|
|
481
470
|
inputSchema: {
|
|
482
471
|
type: "object",
|
|
483
472
|
properties: {
|
|
@@ -517,13 +506,15 @@ export const deleteTaskTool = {
|
|
|
517
506
|
description: `Purpose: PERMANENTLY DELETE a task.
|
|
518
507
|
|
|
519
508
|
Valid Usage:
|
|
520
|
-
1. Use taskId
|
|
521
|
-
2. Use taskName +
|
|
509
|
+
1. Use taskId (preferred and safest)
|
|
510
|
+
2. Use taskName + listName for targeted search
|
|
511
|
+
|
|
512
|
+
Requirements:
|
|
513
|
+
- Task identification: EITHER taskId OR taskName REQUIRED
|
|
522
514
|
|
|
523
515
|
Warning:
|
|
524
516
|
- This action CANNOT be undone
|
|
525
|
-
- Using taskName
|
|
526
|
-
- Provide listName when using taskName for more precise targeting`,
|
|
517
|
+
- Using taskName without listName may match multiple tasks`,
|
|
527
518
|
inputSchema: {
|
|
528
519
|
type: "object",
|
|
529
520
|
properties: {
|
|
@@ -533,11 +524,11 @@ Warning:
|
|
|
533
524
|
},
|
|
534
525
|
taskName: {
|
|
535
526
|
type: "string",
|
|
536
|
-
description: "Name of task to delete.
|
|
527
|
+
description: "Name of task to delete. The tool will search for tasks with this name across all lists unless listName is specified."
|
|
537
528
|
},
|
|
538
529
|
listName: {
|
|
539
530
|
type: "string",
|
|
540
|
-
description: "Name of list containing the task.
|
|
531
|
+
description: "Optional: Name of list containing the task. Providing this narrows the search to a specific list, improving performance and reducing ambiguity."
|
|
541
532
|
}
|
|
542
533
|
}
|
|
543
534
|
}
|
|
@@ -117,12 +117,31 @@ export function validateTaskUpdateData(updateData) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
/**
|
|
120
|
-
* Validate bulk
|
|
120
|
+
* Validate bulk task array and task identification
|
|
121
|
+
* @param tasks Array of tasks to validate
|
|
122
|
+
* @param operation The bulk operation type ('create', 'update', 'move', 'delete')
|
|
121
123
|
*/
|
|
122
|
-
export function validateBulkTasks(tasks) {
|
|
123
|
-
if (!
|
|
124
|
-
throw new Error(
|
|
124
|
+
export function validateBulkTasks(tasks, operation = 'update') {
|
|
125
|
+
if (!Array.isArray(tasks) || tasks.length === 0) {
|
|
126
|
+
throw new Error("tasks must be a non-empty array");
|
|
125
127
|
}
|
|
128
|
+
tasks.forEach((task, index) => {
|
|
129
|
+
if (!task || typeof task !== 'object') {
|
|
130
|
+
throw new Error(`Task at index ${index} must be an object`);
|
|
131
|
+
}
|
|
132
|
+
// Skip task identification validation for create operations
|
|
133
|
+
if (operation === 'create') {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// For bulk operations, require listName when using taskName
|
|
137
|
+
if (task.taskName && !task.listName) {
|
|
138
|
+
throw new Error(`Task at index ${index} using taskName must also provide listName`);
|
|
139
|
+
}
|
|
140
|
+
// At least one identifier is required for non-create operations
|
|
141
|
+
if (!task.taskId && !task.taskName && !task.customTaskId) {
|
|
142
|
+
throw new Error(`Task at index ${index} must provide either taskId, taskName + listName, or customTaskId`);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
126
145
|
}
|
|
127
146
|
/**
|
|
128
147
|
* Parse options for bulk operations
|
|
@@ -12,27 +12,20 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export const getWorkspaceTasksTool = {
|
|
14
14
|
name: "get_workspace_tasks",
|
|
15
|
-
description: `Purpose: Retrieve tasks from across the entire workspace with
|
|
15
|
+
description: `Purpose: Retrieve tasks from across the entire workspace with filtering.
|
|
16
16
|
|
|
17
17
|
Valid Usage:
|
|
18
|
-
1. Apply any combination of filters (tags, lists,
|
|
19
|
-
2. Use pagination
|
|
18
|
+
1. Apply any combination of filters (tags, lists, statuses, etc.)
|
|
19
|
+
2. Use pagination for large result sets
|
|
20
20
|
|
|
21
21
|
Requirements:
|
|
22
|
-
- At least one filter parameter
|
|
23
|
-
- Pagination parameters (page, order_by, reverse) alone are not considered filters
|
|
22
|
+
- At least one filter parameter REQUIRED (tags, list_ids, statuses, etc.)
|
|
24
23
|
|
|
25
24
|
Notes:
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- Use pagination for large result sets
|
|
31
|
-
- Use the detail_level parameter to control the amount of data returned:
|
|
32
|
-
- "summary": Returns lightweight task data (name, status, list, tags)
|
|
33
|
-
- "detailed": Returns complete task data with all fields (DEFAULT if not specified)
|
|
34
|
-
- Responses exceeding 50,000 tokens automatically switch to summary format to avoid hitting LLM token limits
|
|
35
|
-
`,
|
|
25
|
+
- Searches across all lists in the workspace
|
|
26
|
+
- Tag filtering allows cross-list organization
|
|
27
|
+
- Set detail_level=summary for lightweight responses
|
|
28
|
+
- detail_level=detailed (default) returns complete data`,
|
|
36
29
|
parameters: {
|
|
37
30
|
type: 'object',
|
|
38
31
|
properties: {
|
package/package.json
CHANGED