@taazkareem/clickup-mcp-server 0.4.57 → 0.4.58
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 +0 -1
- package/build/index.js +154 -40
- package/build/services/clickup.js +21 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/build/index.js
CHANGED
|
@@ -109,7 +109,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
109
109
|
description: "Due date of the task (Unix timestamp in milliseconds). Convert dates to this format before submitting."
|
|
110
110
|
}
|
|
111
111
|
},
|
|
112
|
-
required: []
|
|
112
|
+
required: ["name"],
|
|
113
|
+
oneOf: [
|
|
114
|
+
{ required: ["listId"] },
|
|
115
|
+
{ required: ["listName"] }
|
|
116
|
+
]
|
|
113
117
|
}
|
|
114
118
|
},
|
|
115
119
|
{
|
|
@@ -164,11 +168,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
164
168
|
description: "Array of user IDs to assign to the task"
|
|
165
169
|
}
|
|
166
170
|
},
|
|
167
|
-
required: []
|
|
171
|
+
required: ["name"]
|
|
168
172
|
}
|
|
169
173
|
}
|
|
170
174
|
},
|
|
171
|
-
required: []
|
|
175
|
+
required: ["tasks"],
|
|
176
|
+
oneOf: [
|
|
177
|
+
{ required: ["listId"] },
|
|
178
|
+
{ required: ["listName"] }
|
|
179
|
+
]
|
|
172
180
|
}
|
|
173
181
|
},
|
|
174
182
|
{
|
|
@@ -179,11 +187,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
179
187
|
properties: {
|
|
180
188
|
spaceId: {
|
|
181
189
|
type: "string",
|
|
182
|
-
description: "ID of the space to create the list in (
|
|
190
|
+
description: "ID of the space to create the list in (required if not using folderId). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
183
191
|
},
|
|
184
|
-
|
|
192
|
+
folderId: {
|
|
185
193
|
type: "string",
|
|
186
|
-
description: "
|
|
194
|
+
description: "ID of the folder to create the list in (required if not using spaceId). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
187
195
|
},
|
|
188
196
|
name: {
|
|
189
197
|
type: "string",
|
|
@@ -193,24 +201,34 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
193
201
|
type: "string",
|
|
194
202
|
description: "Description or content of the list"
|
|
195
203
|
},
|
|
196
|
-
|
|
197
|
-
type: "
|
|
198
|
-
description: "
|
|
204
|
+
assignee: {
|
|
205
|
+
type: "number",
|
|
206
|
+
description: "User ID to assign the list to"
|
|
199
207
|
},
|
|
200
208
|
priority: {
|
|
201
209
|
type: "number",
|
|
202
210
|
description: "Priority of the list (1-4), where 1 is urgent/highest priority and 4 is lowest priority. Only set when explicitly requested."
|
|
203
211
|
},
|
|
204
|
-
|
|
205
|
-
type: "
|
|
206
|
-
description: "
|
|
212
|
+
dueDate: {
|
|
213
|
+
type: "string",
|
|
214
|
+
description: "Due date for the list (Unix timestamp in milliseconds). Convert dates to this format before submitting."
|
|
207
215
|
},
|
|
208
216
|
status: {
|
|
209
217
|
type: "string",
|
|
210
218
|
description: "Status of the list"
|
|
211
219
|
}
|
|
212
220
|
},
|
|
213
|
-
|
|
221
|
+
allOf: [
|
|
222
|
+
{
|
|
223
|
+
oneOf: [
|
|
224
|
+
{ required: ["spaceId"] },
|
|
225
|
+
{ required: ["folderId"] }
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
required: ["name"]
|
|
230
|
+
}
|
|
231
|
+
]
|
|
214
232
|
}
|
|
215
233
|
},
|
|
216
234
|
{
|
|
@@ -236,7 +254,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
236
254
|
description: "Whether to override space statuses with folder-specific statuses"
|
|
237
255
|
}
|
|
238
256
|
},
|
|
239
|
-
required: []
|
|
257
|
+
required: ["name"],
|
|
258
|
+
oneOf: [
|
|
259
|
+
{ required: ["spaceId"] },
|
|
260
|
+
{ required: ["spaceName"] }
|
|
261
|
+
]
|
|
240
262
|
}
|
|
241
263
|
},
|
|
242
264
|
{
|
|
@@ -274,7 +296,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
274
296
|
description: "Status of the list (uses folder default if not specified)"
|
|
275
297
|
}
|
|
276
298
|
},
|
|
277
|
-
required: []
|
|
299
|
+
required: ["name"],
|
|
300
|
+
oneOf: [
|
|
301
|
+
{ required: ["folderId"] },
|
|
302
|
+
{ required: ["folderName", "spaceId"] },
|
|
303
|
+
{ required: ["folderName", "spaceName"] }
|
|
304
|
+
]
|
|
278
305
|
}
|
|
279
306
|
},
|
|
280
307
|
{
|
|
@@ -304,7 +331,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
304
331
|
description: "Name of the destination list - will automatically find the list by name (optional if using listId instead). Only use this if you don't already have the list ID from previous responses."
|
|
305
332
|
}
|
|
306
333
|
},
|
|
307
|
-
|
|
334
|
+
allOf: [
|
|
335
|
+
{
|
|
336
|
+
oneOf: [
|
|
337
|
+
{ required: ["taskId"] },
|
|
338
|
+
{ required: ["taskName"] }
|
|
339
|
+
]
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
oneOf: [
|
|
343
|
+
{ required: ["listId"] },
|
|
344
|
+
{ required: ["listName"] }
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
]
|
|
308
348
|
}
|
|
309
349
|
},
|
|
310
350
|
{
|
|
@@ -334,7 +374,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
334
374
|
description: "Name of the list to create the duplicate in - will automatically find the list by name (optional if using listId instead). Only use this if you don't already have the list ID from previous responses."
|
|
335
375
|
}
|
|
336
376
|
},
|
|
337
|
-
|
|
377
|
+
allOf: [
|
|
378
|
+
{
|
|
379
|
+
oneOf: [
|
|
380
|
+
{ required: ["taskId"] },
|
|
381
|
+
{ required: ["taskName"] }
|
|
382
|
+
]
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
oneOf: [
|
|
386
|
+
{ required: ["listId"] },
|
|
387
|
+
{ required: ["listName"] }
|
|
388
|
+
]
|
|
389
|
+
}
|
|
390
|
+
]
|
|
338
391
|
}
|
|
339
392
|
},
|
|
340
393
|
{
|
|
@@ -378,7 +431,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
378
431
|
optional: true
|
|
379
432
|
}
|
|
380
433
|
},
|
|
381
|
-
|
|
434
|
+
oneOf: [
|
|
435
|
+
{ required: ["taskId"] },
|
|
436
|
+
{ required: ["taskName"] }
|
|
437
|
+
]
|
|
382
438
|
}
|
|
383
439
|
},
|
|
384
440
|
{
|
|
@@ -458,7 +514,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
458
514
|
description: "Object with custom field IDs as keys and desired values for filtering"
|
|
459
515
|
}
|
|
460
516
|
},
|
|
461
|
-
|
|
517
|
+
oneOf: [
|
|
518
|
+
{ required: ["listId"] },
|
|
519
|
+
{ required: ["listName"] }
|
|
520
|
+
]
|
|
462
521
|
}
|
|
463
522
|
},
|
|
464
523
|
{
|
|
@@ -480,7 +539,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
480
539
|
description: "Optional: Name of the list to narrow down task search when multiple tasks have the same name"
|
|
481
540
|
}
|
|
482
541
|
},
|
|
483
|
-
|
|
542
|
+
oneOf: [
|
|
543
|
+
{ required: ["taskId"] },
|
|
544
|
+
{ required: ["taskName"] }
|
|
545
|
+
]
|
|
484
546
|
}
|
|
485
547
|
},
|
|
486
548
|
{
|
|
@@ -502,7 +564,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
502
564
|
description: "Optional: Name of the list to narrow down task search when multiple tasks have the same name"
|
|
503
565
|
}
|
|
504
566
|
},
|
|
505
|
-
required: []
|
|
567
|
+
required: ["taskId"]
|
|
506
568
|
}
|
|
507
569
|
},
|
|
508
570
|
{
|
|
@@ -528,7 +590,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
528
590
|
description: "Name of the space containing the folder (optional if using spaceId instead, and only needed when using folderName). Only use this if you don't already have the space ID from previous responses."
|
|
529
591
|
}
|
|
530
592
|
},
|
|
531
|
-
|
|
593
|
+
oneOf: [
|
|
594
|
+
{ required: ["folderId"] },
|
|
595
|
+
{ required: ["folderName", "spaceId"] },
|
|
596
|
+
{ required: ["folderName", "spaceName"] }
|
|
597
|
+
]
|
|
532
598
|
}
|
|
533
599
|
},
|
|
534
600
|
{
|
|
@@ -562,7 +628,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
562
628
|
description: "Whether to override space statuses with folder-specific statuses"
|
|
563
629
|
}
|
|
564
630
|
},
|
|
565
|
-
|
|
631
|
+
oneOf: [
|
|
632
|
+
{ required: ["folderId"] },
|
|
633
|
+
{ required: ["folderName", "spaceId"] },
|
|
634
|
+
{ required: ["folderName", "spaceName"] }
|
|
635
|
+
]
|
|
566
636
|
}
|
|
567
637
|
},
|
|
568
638
|
{
|
|
@@ -588,7 +658,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
588
658
|
description: "Name of the space containing the folder (optional if using spaceId instead, and only needed when using folderName). Only use this if you don't already have the space ID from previous responses."
|
|
589
659
|
}
|
|
590
660
|
},
|
|
591
|
-
|
|
661
|
+
oneOf: [
|
|
662
|
+
{ required: ["folderId"] },
|
|
663
|
+
{ required: ["folderName", "spaceId"] },
|
|
664
|
+
{ required: ["folderName", "spaceName"] }
|
|
665
|
+
]
|
|
592
666
|
}
|
|
593
667
|
},
|
|
594
668
|
{
|
|
@@ -606,7 +680,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
606
680
|
description: "Name of the list to retrieve - will automatically find the list by name (optional if using listId instead). Only use this if you don't already have the list ID from previous responses."
|
|
607
681
|
}
|
|
608
682
|
},
|
|
609
|
-
|
|
683
|
+
oneOf: [
|
|
684
|
+
{ required: ["listId"] },
|
|
685
|
+
{ required: ["listName"] }
|
|
686
|
+
]
|
|
610
687
|
}
|
|
611
688
|
},
|
|
612
689
|
{
|
|
@@ -636,7 +713,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
636
713
|
description: "New status for the list"
|
|
637
714
|
}
|
|
638
715
|
},
|
|
639
|
-
|
|
716
|
+
oneOf: [
|
|
717
|
+
{ required: ["listId"] },
|
|
718
|
+
{ required: ["listName"] }
|
|
719
|
+
]
|
|
640
720
|
}
|
|
641
721
|
},
|
|
642
722
|
{
|
|
@@ -654,7 +734,10 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
654
734
|
description: "Name of the list to delete - will automatically find the list by name (optional if using listId instead). Only use this if you don't already have the list ID from previous responses."
|
|
655
735
|
}
|
|
656
736
|
},
|
|
657
|
-
|
|
737
|
+
oneOf: [
|
|
738
|
+
{ required: ["listId"] },
|
|
739
|
+
{ required: ["listName"] }
|
|
740
|
+
]
|
|
658
741
|
}
|
|
659
742
|
}
|
|
660
743
|
]
|
|
@@ -772,23 +855,54 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
772
855
|
};
|
|
773
856
|
}
|
|
774
857
|
case "create_list": {
|
|
775
|
-
const args = request.params.arguments;
|
|
858
|
+
const args = request.params.arguments ? request.params.arguments : { name: '' };
|
|
776
859
|
if (!args.name) {
|
|
777
|
-
throw new Error("name is required");
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
860
|
+
throw new Error("List name is required");
|
|
861
|
+
}
|
|
862
|
+
// Validate that we have either spaceId/spaceName OR folderId/folderName, but not both
|
|
863
|
+
const hasSpace = !!(args.spaceId || args.spaceName);
|
|
864
|
+
const hasFolder = !!(args.folderId || args.folderName);
|
|
865
|
+
if (!hasSpace && !hasFolder) {
|
|
866
|
+
throw new Error("Either spaceId/spaceName or folderId/folderName must be provided");
|
|
867
|
+
}
|
|
868
|
+
if (hasSpace && hasFolder) {
|
|
869
|
+
throw new Error("Cannot provide both space and folder identifiers. Use either spaceId/spaceName OR folderId/folderName");
|
|
870
|
+
}
|
|
871
|
+
// Prepare the list data
|
|
872
|
+
const listData = {
|
|
873
|
+
name: args.name,
|
|
874
|
+
content: args.content,
|
|
875
|
+
due_date: args.dueDate,
|
|
876
|
+
priority: args.priority,
|
|
877
|
+
assignee: args.assignee,
|
|
878
|
+
status: args.status
|
|
879
|
+
};
|
|
880
|
+
let list;
|
|
881
|
+
if (hasSpace) {
|
|
882
|
+
// Handle space-based creation
|
|
883
|
+
let spaceId = args.spaceId;
|
|
884
|
+
if (!spaceId && args.spaceName) {
|
|
885
|
+
const teamId = await clickup.getTeamId();
|
|
886
|
+
const space = await clickup.findSpaceByName(args.spaceName, teamId);
|
|
887
|
+
if (!space) {
|
|
888
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
889
|
+
}
|
|
890
|
+
spaceId = space.id;
|
|
784
891
|
}
|
|
785
|
-
|
|
892
|
+
list = await clickup.createList(spaceId, listData);
|
|
786
893
|
}
|
|
787
|
-
|
|
788
|
-
|
|
894
|
+
else {
|
|
895
|
+
// Handle folder-based creation
|
|
896
|
+
let folderId = args.folderId;
|
|
897
|
+
if (!folderId && args.folderName) {
|
|
898
|
+
const result = await clickup.findFolderIDByName(args.folderName);
|
|
899
|
+
if (!result) {
|
|
900
|
+
throw new Error(`Folder with name "${args.folderName}" not found`);
|
|
901
|
+
}
|
|
902
|
+
folderId = result.id;
|
|
903
|
+
}
|
|
904
|
+
list = await clickup.createListInFolder(folderId, listData);
|
|
789
905
|
}
|
|
790
|
-
const { spaceId: _, spaceName: __, ...listData } = args;
|
|
791
|
-
const list = await clickup.createList(spaceId, listData);
|
|
792
906
|
return {
|
|
793
907
|
content: [{
|
|
794
908
|
type: "text",
|
|
@@ -85,6 +85,13 @@ export class ClickUpService {
|
|
|
85
85
|
}
|
|
86
86
|
return ClickUpService.instance;
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Gets the team/workspace ID that was set during initialization.
|
|
90
|
+
* @returns The team/workspace ID
|
|
91
|
+
*/
|
|
92
|
+
getTeamId() {
|
|
93
|
+
return this.clickupTeamId;
|
|
94
|
+
}
|
|
88
95
|
// Tasks
|
|
89
96
|
/**
|
|
90
97
|
* Retrieves tasks from a specific list with optional filtering.
|
|
@@ -300,6 +307,9 @@ export class ClickUpService {
|
|
|
300
307
|
}
|
|
301
308
|
/**
|
|
302
309
|
* Creates a new list in a space.
|
|
310
|
+
* Note: ClickUp API requires lists to be in folders, so this will:
|
|
311
|
+
* 1. Create a default folder if none specified
|
|
312
|
+
* 2. Create the list within that folder
|
|
303
313
|
* @param spaceId - ID of the space to create the list in
|
|
304
314
|
* @param data - List creation data (name, content, due date, etc.)
|
|
305
315
|
* @returns Promise resolving to the created ClickUpList
|
|
@@ -307,7 +317,17 @@ export class ClickUpService {
|
|
|
307
317
|
*/
|
|
308
318
|
async createList(spaceId, data) {
|
|
309
319
|
return this.makeRequest(async () => {
|
|
310
|
-
|
|
320
|
+
// First, get or create a default folder
|
|
321
|
+
const folders = await this.getFolders(spaceId);
|
|
322
|
+
let defaultFolder = folders.find(f => f.name === 'Default Lists');
|
|
323
|
+
if (!defaultFolder) {
|
|
324
|
+
// Create a default folder if none exists
|
|
325
|
+
defaultFolder = await this.createFolder(spaceId, {
|
|
326
|
+
name: 'Default Lists'
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
// Create the list within the default folder
|
|
330
|
+
const response = await this.client.post(`/folder/${defaultFolder.id}/list`, data);
|
|
311
331
|
return response.data;
|
|
312
332
|
});
|
|
313
333
|
}
|
package/package.json
CHANGED