@taazkareem/clickup-mcp-server 0.1.7 → 0.2.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.
- package/README.md +126 -19
- package/build/index.js +254 -0
- package/build/services/clickup.js +56 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,41 @@
|
|
|
1
1
|
# ClickUp MCP Server
|
|
2
2
|
|
|
3
|
-
A Model Context Protocol (MCP) server for integrating ClickUp tasks with AI applications. This server allows AI agents to interact with ClickUp tasks, spaces, and
|
|
3
|
+
A Model Context Protocol (MCP) server for integrating ClickUp tasks with AI applications. This server allows AI agents to interact with ClickUp tasks, spaces, lists, and folders through a standardized protocol.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- 🔄
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
-
|
|
7
|
+
- 🔄 **Resource Management**
|
|
8
|
+
- List and read ClickUp tasks as resources
|
|
9
|
+
- View task details, status, and assignments
|
|
10
|
+
- Access task history and relationships
|
|
11
|
+
|
|
12
|
+
- 📂 **Workspace Organization**
|
|
13
|
+
- Create and manage spaces
|
|
14
|
+
- Create, update, and delete folders
|
|
15
|
+
- Create and manage lists (in spaces or folders)
|
|
16
|
+
- Flexible identification using IDs or names
|
|
17
|
+
|
|
18
|
+
- ✨ **Task Operations**
|
|
19
|
+
- Create and update tasks
|
|
20
|
+
- Move tasks between lists
|
|
21
|
+
- Duplicate tasks
|
|
22
|
+
- Set priorities and due dates
|
|
23
|
+
- Assign team members
|
|
24
|
+
|
|
25
|
+
- 📊 **Information Retrieval**
|
|
26
|
+
- Get spaces and lists with their IDs
|
|
27
|
+
- List available statuses
|
|
28
|
+
- Find items by name (case-insensitive)
|
|
29
|
+
- View task relationships
|
|
30
|
+
|
|
31
|
+
- 📝 **AI Integration**
|
|
32
|
+
- Generate task descriptions with AI
|
|
33
|
+
- Summarize tasks and analyze priorities
|
|
34
|
+
- Get AI-powered task recommendations
|
|
35
|
+
|
|
36
|
+
- 🔒 **Security**
|
|
37
|
+
- Secure API key management
|
|
38
|
+
- Environment-based configuration
|
|
13
39
|
|
|
14
40
|
## Installation
|
|
15
41
|
|
|
@@ -43,6 +69,7 @@ clickup-mcp-server
|
|
|
43
69
|
|
|
44
70
|
1. **list_spaces**
|
|
45
71
|
- Lists all spaces and their lists with IDs
|
|
72
|
+
- Shows available statuses for each list
|
|
46
73
|
- No parameters required
|
|
47
74
|
|
|
48
75
|
2. **create_task**
|
|
@@ -55,51 +82,131 @@ clickup-mcp-server
|
|
|
55
82
|
- `status`: Task status
|
|
56
83
|
- `priority`: Priority level (1-4)
|
|
57
84
|
- `dueDate`: Due date (ISO string)
|
|
85
|
+
- `assignees`: Array of user IDs
|
|
58
86
|
|
|
59
|
-
3. **
|
|
87
|
+
3. **create_list**
|
|
88
|
+
- Creates a new list in a space
|
|
89
|
+
- Required parameters:
|
|
90
|
+
- `name`: Name of the list
|
|
91
|
+
- Optional parameters:
|
|
92
|
+
- `spaceId`: ID of the space (optional if spaceName provided)
|
|
93
|
+
- `spaceName`: Name of the space (optional if spaceId provided)
|
|
94
|
+
- `content`: List description
|
|
95
|
+
- `status`: List status
|
|
96
|
+
- `priority`: Priority level (1-4)
|
|
97
|
+
- `dueDate`: Due date (ISO string)
|
|
98
|
+
|
|
99
|
+
4. **create_folder**
|
|
100
|
+
- Creates a new folder in a space
|
|
101
|
+
- Required parameters:
|
|
102
|
+
- `name`: Name of the folder
|
|
103
|
+
- Optional parameters:
|
|
104
|
+
- `spaceId`: ID of the space (optional if spaceName provided)
|
|
105
|
+
- `spaceName`: Name of the space (optional if spaceId provided)
|
|
106
|
+
- `override_statuses`: Whether to override space statuses
|
|
107
|
+
|
|
108
|
+
5. **create_list_in_folder**
|
|
109
|
+
- Creates a new list within a folder
|
|
110
|
+
- Required parameters:
|
|
111
|
+
- `name`: Name of the list
|
|
112
|
+
- Optional parameters:
|
|
113
|
+
- `folderId`: ID of the folder (optional if using folderName)
|
|
114
|
+
- `folderName`: Name of the folder
|
|
115
|
+
- `spaceId`: ID of the space (required if using folderName)
|
|
116
|
+
- `spaceName`: Name of the space (alternative to spaceId)
|
|
117
|
+
- `content`: List description
|
|
118
|
+
- `status`: List status
|
|
119
|
+
|
|
120
|
+
6. **move_task**
|
|
121
|
+
- Moves a task to a different list
|
|
122
|
+
- Required parameters:
|
|
123
|
+
- `taskId`: ID of the task to move
|
|
124
|
+
- `listId`: ID of the destination list
|
|
125
|
+
|
|
126
|
+
7. **duplicate_task**
|
|
127
|
+
- Creates a copy of a task in a specified list
|
|
128
|
+
- Required parameters:
|
|
129
|
+
- `taskId`: ID of the task to duplicate
|
|
130
|
+
- `listId`: ID of the destination list
|
|
131
|
+
|
|
132
|
+
8. **update_task**
|
|
60
133
|
- Updates an existing task
|
|
61
134
|
- Required parameters:
|
|
62
135
|
- `taskId`: ID of the task to update
|
|
63
136
|
- Optional parameters:
|
|
64
|
-
-
|
|
137
|
+
- `name`: New task name
|
|
138
|
+
- `description`: New description
|
|
139
|
+
- `status`: New status
|
|
140
|
+
- `priority`: New priority level (1-4)
|
|
141
|
+
- `dueDate`: New due date (ISO string)
|
|
65
142
|
|
|
66
143
|
### Available Prompts
|
|
67
144
|
|
|
68
145
|
1. **summarize_tasks**
|
|
69
|
-
- Provides a summary of
|
|
70
|
-
- Groups by status
|
|
146
|
+
- Provides a comprehensive summary of tasks
|
|
147
|
+
- Groups tasks by status
|
|
148
|
+
- Highlights priorities and deadlines
|
|
149
|
+
- Suggests task relationships
|
|
71
150
|
|
|
72
151
|
2. **analyze_priorities**
|
|
73
|
-
- Analyzes task
|
|
74
|
-
-
|
|
152
|
+
- Analyzes task priority distribution
|
|
153
|
+
- Identifies misaligned priorities
|
|
154
|
+
- Suggests priority adjustments
|
|
155
|
+
- Recommends task sequencing
|
|
75
156
|
|
|
76
157
|
3. **generate_description**
|
|
77
158
|
- Helps generate detailed task descriptions
|
|
78
|
-
- Includes
|
|
159
|
+
- Includes:
|
|
160
|
+
- Clear objectives
|
|
161
|
+
- Success criteria
|
|
162
|
+
- Required resources
|
|
163
|
+
- Dependencies
|
|
164
|
+
- Potential risks
|
|
165
|
+
|
|
166
|
+
## Name Resolution
|
|
167
|
+
|
|
168
|
+
Most tools support finding items by either ID or name:
|
|
169
|
+
- Spaces can be referenced by `spaceId` or `spaceName`
|
|
170
|
+
- Folders can be referenced by `folderId` or `folderName` (with space information)
|
|
171
|
+
- Lists can be referenced by `listId` or found within spaces/folders
|
|
172
|
+
|
|
173
|
+
Name matching is case-insensitive for convenience.
|
|
174
|
+
|
|
175
|
+
## Error Handling
|
|
176
|
+
|
|
177
|
+
The server provides clear error messages for common scenarios:
|
|
178
|
+
- Missing required parameters
|
|
179
|
+
- Invalid IDs or names
|
|
180
|
+
- Items not found
|
|
181
|
+
- Permission issues
|
|
182
|
+
- API errors
|
|
79
183
|
|
|
80
184
|
## Using with Cursor AI Composer
|
|
81
185
|
|
|
82
|
-
To add this server to Cursor AI Composer:
|
|
186
|
+
To add this server to Cursor AI Composer, follow these steps:
|
|
187
|
+
|
|
188
|
+
1. Go to the Features section in the settings.
|
|
189
|
+
2. Add the following command under MCP Servers:
|
|
83
190
|
|
|
84
191
|
```bash
|
|
85
192
|
npx -y @taazkareem/clickup-mcp-server \
|
|
86
193
|
--env CLICKUP_API_KEY=your_api_key_here \
|
|
87
194
|
--env TEAM_ID=your_team_id_here
|
|
88
195
|
```
|
|
196
|
+
3. Replace `your_api_key_here` and `your_team_id_here` with your actual ClickUp credentials.
|
|
197
|
+
4. Click on 'Save' to add the server.
|
|
89
198
|
|
|
90
199
|
You can get these values from:
|
|
91
200
|
- `CLICKUP_API_KEY`: Get from [ClickUp Settings > Apps](https://app.clickup.com/settings/apps)
|
|
92
201
|
- `TEAM_ID`: Your ClickUp Team ID (found in the URL when viewing your workspace or via API)
|
|
93
202
|
|
|
94
|
-
> ⚠️ **Important**: Make sure to replace `your_api_key_here` and `your_team_id_here` with your actual ClickUp credentials.
|
|
95
|
-
|
|
96
203
|
> **Security Note**: Your API key will be stored securely and will not be exposed to AI models.
|
|
97
204
|
|
|
98
205
|
## Development
|
|
99
206
|
|
|
100
207
|
1. Clone the repository:
|
|
101
208
|
```bash
|
|
102
|
-
git clone https://github.com/
|
|
209
|
+
git clone https://github.com/taazkareem/clickup-mcp-server.git
|
|
103
210
|
cd clickup-mcp-server
|
|
104
211
|
```
|
|
105
212
|
|
|
@@ -119,4 +226,4 @@ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md)
|
|
|
119
226
|
|
|
120
227
|
## License
|
|
121
228
|
|
|
122
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
229
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
package/build/index.js
CHANGED
|
@@ -143,6 +143,148 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
143
143
|
required: ["listId", "name"]
|
|
144
144
|
}
|
|
145
145
|
},
|
|
146
|
+
{
|
|
147
|
+
name: "create_list",
|
|
148
|
+
description: "Create a new list in a ClickUp space",
|
|
149
|
+
inputSchema: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {
|
|
152
|
+
spaceId: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "ID of the space to create the list in (optional if spaceName is provided)"
|
|
155
|
+
},
|
|
156
|
+
spaceName: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "Name of the space to create the list in (optional if spaceId is provided)"
|
|
159
|
+
},
|
|
160
|
+
name: {
|
|
161
|
+
type: "string",
|
|
162
|
+
description: "Name of the list"
|
|
163
|
+
},
|
|
164
|
+
content: {
|
|
165
|
+
type: "string",
|
|
166
|
+
description: "Description or content of the list"
|
|
167
|
+
},
|
|
168
|
+
dueDate: {
|
|
169
|
+
type: "string",
|
|
170
|
+
description: "Due date for the list (ISO string)"
|
|
171
|
+
},
|
|
172
|
+
priority: {
|
|
173
|
+
type: "number",
|
|
174
|
+
description: "Priority of the list (1-4)"
|
|
175
|
+
},
|
|
176
|
+
assignee: {
|
|
177
|
+
type: "number",
|
|
178
|
+
description: "User ID to assign the list to"
|
|
179
|
+
},
|
|
180
|
+
status: {
|
|
181
|
+
type: "string",
|
|
182
|
+
description: "Status of the list"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
required: ["name"]
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "create_folder",
|
|
190
|
+
description: "Create a new folder in a ClickUp space",
|
|
191
|
+
inputSchema: {
|
|
192
|
+
type: "object",
|
|
193
|
+
properties: {
|
|
194
|
+
spaceId: {
|
|
195
|
+
type: "string",
|
|
196
|
+
description: "ID of the space to create the folder in (optional if spaceName is provided)"
|
|
197
|
+
},
|
|
198
|
+
spaceName: {
|
|
199
|
+
type: "string",
|
|
200
|
+
description: "Name of the space to create the folder in (optional if spaceId is provided)"
|
|
201
|
+
},
|
|
202
|
+
name: {
|
|
203
|
+
type: "string",
|
|
204
|
+
description: "Name of the folder"
|
|
205
|
+
},
|
|
206
|
+
override_statuses: {
|
|
207
|
+
type: "boolean",
|
|
208
|
+
description: "Whether to override space statuses"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
required: ["name"]
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "create_list_in_folder",
|
|
216
|
+
description: "Create a new list in a ClickUp folder",
|
|
217
|
+
inputSchema: {
|
|
218
|
+
type: "object",
|
|
219
|
+
properties: {
|
|
220
|
+
folderId: {
|
|
221
|
+
type: "string",
|
|
222
|
+
description: "ID of the folder to create the list in (optional if folderName and spaceId/spaceName are provided)"
|
|
223
|
+
},
|
|
224
|
+
folderName: {
|
|
225
|
+
type: "string",
|
|
226
|
+
description: "Name of the folder to create the list in"
|
|
227
|
+
},
|
|
228
|
+
spaceId: {
|
|
229
|
+
type: "string",
|
|
230
|
+
description: "ID of the space containing the folder (required if using folderName)"
|
|
231
|
+
},
|
|
232
|
+
spaceName: {
|
|
233
|
+
type: "string",
|
|
234
|
+
description: "Name of the space containing the folder (alternative to spaceId)"
|
|
235
|
+
},
|
|
236
|
+
name: {
|
|
237
|
+
type: "string",
|
|
238
|
+
description: "Name of the list"
|
|
239
|
+
},
|
|
240
|
+
content: {
|
|
241
|
+
type: "string",
|
|
242
|
+
description: "Description or content of the list"
|
|
243
|
+
},
|
|
244
|
+
status: {
|
|
245
|
+
type: "string",
|
|
246
|
+
description: "Status of the list"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
required: ["name"]
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "move_task",
|
|
254
|
+
description: "Move a task to a different list",
|
|
255
|
+
inputSchema: {
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
taskId: {
|
|
259
|
+
type: "string",
|
|
260
|
+
description: "ID of the task to move"
|
|
261
|
+
},
|
|
262
|
+
listId: {
|
|
263
|
+
type: "string",
|
|
264
|
+
description: "ID of the destination list"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
required: ["taskId", "listId"]
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "duplicate_task",
|
|
272
|
+
description: "Duplicate a task to a list",
|
|
273
|
+
inputSchema: {
|
|
274
|
+
type: "object",
|
|
275
|
+
properties: {
|
|
276
|
+
taskId: {
|
|
277
|
+
type: "string",
|
|
278
|
+
description: "ID of the task to duplicate"
|
|
279
|
+
},
|
|
280
|
+
listId: {
|
|
281
|
+
type: "string",
|
|
282
|
+
description: "ID of the list to create the duplicate in"
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
required: ["taskId", "listId"]
|
|
286
|
+
}
|
|
287
|
+
},
|
|
146
288
|
{
|
|
147
289
|
name: "update_task",
|
|
148
290
|
description: "Update an existing task in ClickUp",
|
|
@@ -232,6 +374,118 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
232
374
|
}]
|
|
233
375
|
};
|
|
234
376
|
}
|
|
377
|
+
case "create_list": {
|
|
378
|
+
const args = request.params.arguments;
|
|
379
|
+
if (!args.name) {
|
|
380
|
+
throw new Error("name is required");
|
|
381
|
+
}
|
|
382
|
+
let spaceId = args.spaceId;
|
|
383
|
+
if (!spaceId && args.spaceName) {
|
|
384
|
+
const space = await clickup.findSpaceByName(config.teamId, args.spaceName);
|
|
385
|
+
if (!space) {
|
|
386
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
387
|
+
}
|
|
388
|
+
spaceId = space.id;
|
|
389
|
+
}
|
|
390
|
+
if (!spaceId) {
|
|
391
|
+
throw new Error("Either spaceId or spaceName must be provided");
|
|
392
|
+
}
|
|
393
|
+
const { spaceId: _, spaceName: __, ...listData } = args;
|
|
394
|
+
const list = await clickup.createList(spaceId, listData);
|
|
395
|
+
return {
|
|
396
|
+
content: [{
|
|
397
|
+
type: "text",
|
|
398
|
+
text: `Created list ${list.id}: ${list.name}`
|
|
399
|
+
}]
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
case "create_folder": {
|
|
403
|
+
const args = request.params.arguments;
|
|
404
|
+
if (!args.name) {
|
|
405
|
+
throw new Error("name is required");
|
|
406
|
+
}
|
|
407
|
+
let spaceId = args.spaceId;
|
|
408
|
+
if (!spaceId && args.spaceName) {
|
|
409
|
+
const space = await clickup.findSpaceByName(config.teamId, args.spaceName);
|
|
410
|
+
if (!space) {
|
|
411
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
412
|
+
}
|
|
413
|
+
spaceId = space.id;
|
|
414
|
+
}
|
|
415
|
+
if (!spaceId) {
|
|
416
|
+
throw new Error("Either spaceId or spaceName must be provided");
|
|
417
|
+
}
|
|
418
|
+
const { spaceId: _, spaceName: __, ...folderData } = args;
|
|
419
|
+
const folder = await clickup.createFolder(spaceId, folderData);
|
|
420
|
+
return {
|
|
421
|
+
content: [{
|
|
422
|
+
type: "text",
|
|
423
|
+
text: `Created folder ${folder.id}: ${folder.name}`
|
|
424
|
+
}]
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
case "create_list_in_folder": {
|
|
428
|
+
const args = request.params.arguments;
|
|
429
|
+
if (!args.name) {
|
|
430
|
+
throw new Error("name is required");
|
|
431
|
+
}
|
|
432
|
+
let folderId = args.folderId;
|
|
433
|
+
if (!folderId && args.folderName) {
|
|
434
|
+
let spaceId = args.spaceId;
|
|
435
|
+
if (!spaceId && args.spaceName) {
|
|
436
|
+
const space = await clickup.findSpaceByName(config.teamId, args.spaceName);
|
|
437
|
+
if (!space) {
|
|
438
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
439
|
+
}
|
|
440
|
+
spaceId = space.id;
|
|
441
|
+
}
|
|
442
|
+
if (!spaceId) {
|
|
443
|
+
throw new Error("Either spaceId or spaceName must be provided when using folderName");
|
|
444
|
+
}
|
|
445
|
+
const folder = await clickup.findFolderByName(spaceId, args.folderName);
|
|
446
|
+
if (!folder) {
|
|
447
|
+
throw new Error(`Folder with name "${args.folderName}" not found`);
|
|
448
|
+
}
|
|
449
|
+
folderId = folder.id;
|
|
450
|
+
}
|
|
451
|
+
if (!folderId) {
|
|
452
|
+
throw new Error("Either folderId or folderName (with space information) must be provided");
|
|
453
|
+
}
|
|
454
|
+
const { folderId: _, folderName: __, spaceId: ___, spaceName: ____, ...listData } = args;
|
|
455
|
+
const list = await clickup.createListInFolder(folderId, listData);
|
|
456
|
+
return {
|
|
457
|
+
content: [{
|
|
458
|
+
type: "text",
|
|
459
|
+
text: `Created list ${list.id}: ${list.name} in folder`
|
|
460
|
+
}]
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
case "move_task": {
|
|
464
|
+
const args = request.params.arguments;
|
|
465
|
+
if (!args.taskId || !args.listId) {
|
|
466
|
+
throw new Error("taskId and listId are required");
|
|
467
|
+
}
|
|
468
|
+
const task = await clickup.moveTask(args.taskId, args.listId);
|
|
469
|
+
return {
|
|
470
|
+
content: [{
|
|
471
|
+
type: "text",
|
|
472
|
+
text: `Moved task ${task.id} to list ${args.listId}`
|
|
473
|
+
}]
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
case "duplicate_task": {
|
|
477
|
+
const args = request.params.arguments;
|
|
478
|
+
if (!args.taskId || !args.listId) {
|
|
479
|
+
throw new Error("taskId and listId are required");
|
|
480
|
+
}
|
|
481
|
+
const task = await clickup.duplicateTask(args.taskId, args.listId);
|
|
482
|
+
return {
|
|
483
|
+
content: [{
|
|
484
|
+
type: "text",
|
|
485
|
+
text: `Duplicated task ${args.taskId} to new task ${task.id} in list ${args.listId}`
|
|
486
|
+
}]
|
|
487
|
+
};
|
|
488
|
+
}
|
|
235
489
|
case "update_task": {
|
|
236
490
|
const args = request.params.arguments;
|
|
237
491
|
if (!args.taskId) {
|
|
@@ -67,4 +67,60 @@ export class ClickUpService {
|
|
|
67
67
|
const response = await this.client.get(`/space/${spaceId}`);
|
|
68
68
|
return response.data;
|
|
69
69
|
}
|
|
70
|
+
async findSpaceByName(teamId, spaceName) {
|
|
71
|
+
const spaces = await this.getSpaces(teamId);
|
|
72
|
+
return spaces.find(space => space.name.toLowerCase() === spaceName.toLowerCase()) || null;
|
|
73
|
+
}
|
|
74
|
+
async createList(spaceId, data) {
|
|
75
|
+
const response = await this.client.post(`/space/${spaceId}/list`, data);
|
|
76
|
+
return response.data;
|
|
77
|
+
}
|
|
78
|
+
// Folders
|
|
79
|
+
async getFolders(spaceId) {
|
|
80
|
+
const response = await this.client.get(`/space/${spaceId}/folder`);
|
|
81
|
+
return response.data.folders;
|
|
82
|
+
}
|
|
83
|
+
async getFolder(folderId) {
|
|
84
|
+
const response = await this.client.get(`/folder/${folderId}`);
|
|
85
|
+
return response.data;
|
|
86
|
+
}
|
|
87
|
+
async createFolder(spaceId, data) {
|
|
88
|
+
const response = await this.client.post(`/space/${spaceId}/folder`, data);
|
|
89
|
+
return response.data;
|
|
90
|
+
}
|
|
91
|
+
async deleteFolder(folderId) {
|
|
92
|
+
await this.client.delete(`/folder/${folderId}`);
|
|
93
|
+
}
|
|
94
|
+
async createListInFolder(folderId, data) {
|
|
95
|
+
const response = await this.client.post(`/folder/${folderId}/list`, data);
|
|
96
|
+
return response.data;
|
|
97
|
+
}
|
|
98
|
+
async findFolderByName(spaceId, folderName) {
|
|
99
|
+
const folders = await this.getFolders(spaceId);
|
|
100
|
+
return folders.find(folder => folder.name.toLowerCase() === folderName.toLowerCase()) || null;
|
|
101
|
+
}
|
|
102
|
+
// Additional helper methods
|
|
103
|
+
async moveTask(taskId, listId) {
|
|
104
|
+
const response = await this.client.post(`/task/${taskId}`, {
|
|
105
|
+
list: listId
|
|
106
|
+
});
|
|
107
|
+
return response.data;
|
|
108
|
+
}
|
|
109
|
+
async duplicateTask(taskId, listId) {
|
|
110
|
+
const response = await this.client.post(`/task/${taskId}/duplicate`, {
|
|
111
|
+
list: listId
|
|
112
|
+
});
|
|
113
|
+
return response.data;
|
|
114
|
+
}
|
|
115
|
+
async deleteList(listId) {
|
|
116
|
+
await this.client.delete(`/list/${listId}`);
|
|
117
|
+
}
|
|
118
|
+
async updateList(listId, data) {
|
|
119
|
+
const response = await this.client.put(`/list/${listId}`, data);
|
|
120
|
+
return response.data;
|
|
121
|
+
}
|
|
122
|
+
async findListByName(spaceId, listName) {
|
|
123
|
+
const lists = await this.getLists(spaceId);
|
|
124
|
+
return lists.find(list => list.name.toLowerCase() === listName.toLowerCase()) || null;
|
|
125
|
+
}
|
|
70
126
|
}
|
package/package.json
CHANGED