@taazkareem/clickup-mcp-server 0.4.53 → 0.4.56
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/Dockerfile +38 -0
- package/README.md +11 -1
- package/build/index.js +428 -39
- package/build/services/clickup.js +22 -2
- package/package.json +3 -3
- package/smithery.yaml +1 -1
package/Dockerfile
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
|
|
2
|
+
# Use a Node.js base image
|
|
3
|
+
FROM node:18-alpine AS builder
|
|
4
|
+
|
|
5
|
+
# Set the working directory
|
|
6
|
+
WORKDIR /app
|
|
7
|
+
|
|
8
|
+
# Copy package files
|
|
9
|
+
COPY package.json package-lock.json ./
|
|
10
|
+
|
|
11
|
+
# Copy the source files and tsconfig BEFORE npm install
|
|
12
|
+
COPY src ./src
|
|
13
|
+
COPY tsconfig.json ./
|
|
14
|
+
|
|
15
|
+
# Install dependencies
|
|
16
|
+
RUN npm install
|
|
17
|
+
|
|
18
|
+
# Compile TypeScript to JavaScript
|
|
19
|
+
RUN npm run build
|
|
20
|
+
|
|
21
|
+
# Use a smaller image for the runtime
|
|
22
|
+
FROM node:18-alpine AS runtime
|
|
23
|
+
|
|
24
|
+
# Set the working directory
|
|
25
|
+
WORKDIR /app
|
|
26
|
+
|
|
27
|
+
# Copy the build output and node_modules from the builder stage
|
|
28
|
+
COPY --from=builder /app/build ./build
|
|
29
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
30
|
+
|
|
31
|
+
# Copy the entrypoint script if necessary
|
|
32
|
+
COPY --from=builder /app/package.json ./
|
|
33
|
+
|
|
34
|
+
# Expose the desired port (if the server binds to a port)
|
|
35
|
+
EXPOSE 8080
|
|
36
|
+
|
|
37
|
+
# Define the command to run the application
|
|
38
|
+
CMD ["node", "build/index.js"]
|
package/README.md
CHANGED
|
@@ -21,6 +21,9 @@ npx -y @taazkareem/clickup-mcp-server \
|
|
|
21
21
|
4. Replace the credentials and click Save
|
|
22
22
|
5. Use Natural Language to interact with your ClickUp Workspace!
|
|
23
23
|
|
|
24
|
+
## Smithery
|
|
25
|
+
[](https://smithery.ai/server/@TaazKareem/clickup-mcp-server)
|
|
26
|
+
|
|
24
27
|
## Features
|
|
25
28
|
|
|
26
29
|
- 🎯 **Task Management**
|
|
@@ -32,9 +35,10 @@ npx -y @taazkareem/clickup-mcp-server \
|
|
|
32
35
|
- 📂 **Workspace Organization**
|
|
33
36
|
- Complete workspace hierarchy (spaces, folders, lists)
|
|
34
37
|
- Tree structure with clear relationships
|
|
35
|
-
-
|
|
38
|
+
- Full CRUD operations for workspace components
|
|
36
39
|
- Efficient path-based navigation
|
|
37
40
|
|
|
41
|
+
|
|
38
42
|
- 🔄 **Integration Features**
|
|
39
43
|
- Name or ID-based item lookup
|
|
40
44
|
- Case-insensitive name matching
|
|
@@ -63,6 +67,12 @@ npx -y @taazkareem/clickup-mcp-server \
|
|
|
63
67
|
| [create_list](docs/api-reference.md#list-management) | Create list in space | `name`, `spaceId`/`spaceName` |
|
|
64
68
|
| [create_folder](docs/api-reference.md#folder-management) | Create folder | `name`, `spaceId`/`spaceName` |
|
|
65
69
|
| [create_list_in_folder](docs/api-reference.md#list-management) | Create list in folder | `name`, `folderId`/`folderName` |
|
|
70
|
+
| [get_folder](docs/api-reference.md#folder-management) | Get folder details | `folderId`/`folderName` |
|
|
71
|
+
| [update_folder](docs/api-reference.md#folder-management) | Update folder properties | `folderId`/`folderName` |
|
|
72
|
+
| [delete_folder](docs/api-reference.md#folder-management) | Delete folder | `folderId`/`folderName` |
|
|
73
|
+
| [get_list](docs/api-reference.md#list-management) | Get list details | `listId`/`listName` |
|
|
74
|
+
| [update_list](docs/api-reference.md#list-management) | Update list properties | `listId`/`listName` |
|
|
75
|
+
| [delete_list](docs/api-reference.md#list-management) | Delete list | `listId`/`listName` |
|
|
66
76
|
|
|
67
77
|
See [full documentation](docs/api-reference.md) for optional parameters and advanced usage.
|
|
68
78
|
|
package/build/index.js
CHANGED
|
@@ -72,17 +72,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
74
|
name: "create_task",
|
|
75
|
-
description: "Create a single task in a ClickUp list. Use this tool for individual task creation only. For multiple tasks, use create_bulk_tasks instead.
|
|
75
|
+
description: "Create a single task in a ClickUp list. Use this tool for individual task creation only. For multiple tasks, use create_bulk_tasks instead. Before calling this tool, check if you already have the necessary list ID from previous responses in the conversation history, as this avoids redundant lookups. When creating a task, you must provide either a listId or listName.",
|
|
76
76
|
inputSchema: {
|
|
77
77
|
type: "object",
|
|
78
78
|
properties: {
|
|
79
79
|
listId: {
|
|
80
80
|
type: "string",
|
|
81
|
-
description: "ID of the list to create the task in (optional if using listName instead)"
|
|
81
|
+
description: "ID of the list to create the task in (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
82
82
|
},
|
|
83
83
|
listName: {
|
|
84
84
|
type: "string",
|
|
85
|
-
description: "Name of the list to create the task in - will automatically find the list by name (optional if using listId instead)"
|
|
85
|
+
description: "Name of the list to create the task 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."
|
|
86
86
|
},
|
|
87
87
|
name: {
|
|
88
88
|
type: "string",
|
|
@@ -114,17 +114,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
116
|
name: "create_bulk_tasks",
|
|
117
|
-
description: "Create multiple tasks in a ClickUp list simultaneously. Use this tool when you need to add several related tasks in one operation.
|
|
117
|
+
description: "Create multiple tasks in a ClickUp list simultaneously. Use this tool when you need to add several related tasks in one operation. Before calling, check if you already have the necessary list ID from previous responses in the conversation, as this avoids redundant lookups. More efficient than creating tasks one by one for batch operations.",
|
|
118
118
|
inputSchema: {
|
|
119
119
|
type: "object",
|
|
120
120
|
properties: {
|
|
121
121
|
listId: {
|
|
122
122
|
type: "string",
|
|
123
|
-
description: "ID of the list to create the tasks in (optional if using listName instead)"
|
|
123
|
+
description: "ID of the list to create the tasks in (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
124
124
|
},
|
|
125
125
|
listName: {
|
|
126
126
|
type: "string",
|
|
127
|
-
description: "Name of the list to create the tasks in - will automatically find the list by name (optional if using listId instead)"
|
|
127
|
+
description: "Name of the list to create the tasks 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."
|
|
128
128
|
},
|
|
129
129
|
tasks: {
|
|
130
130
|
type: "array",
|
|
@@ -173,17 +173,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
173
173
|
},
|
|
174
174
|
{
|
|
175
175
|
name: "create_list",
|
|
176
|
-
description: "Create a new list directly in a ClickUp space. Use this tool when you need a top-level list not nested inside a folder.
|
|
176
|
+
description: "Create a new list directly in a ClickUp space. Use this tool when you need a top-level list not nested inside a folder. Before calling, check if you already have the necessary space ID from previous responses in the conversation, as this avoids redundant lookups. For creating lists inside folders, use create_list_in_folder instead.",
|
|
177
177
|
inputSchema: {
|
|
178
178
|
type: "object",
|
|
179
179
|
properties: {
|
|
180
180
|
spaceId: {
|
|
181
181
|
type: "string",
|
|
182
|
-
description: "ID of the space to create the list in (optional if using spaceName instead)"
|
|
182
|
+
description: "ID of the space to create the list in (optional if using spaceName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
183
183
|
},
|
|
184
184
|
spaceName: {
|
|
185
185
|
type: "string",
|
|
186
|
-
description: "Name of the space to create the list in - will automatically find the space by name (optional if using spaceId instead)"
|
|
186
|
+
description: "Name of the space to create the list in - will automatically find the space by name (optional if using spaceId instead). Only use this if you don't already have the space ID from previous responses."
|
|
187
187
|
},
|
|
188
188
|
name: {
|
|
189
189
|
type: "string",
|
|
@@ -215,17 +215,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
215
215
|
},
|
|
216
216
|
{
|
|
217
217
|
name: "create_folder",
|
|
218
|
-
description: "Create a new folder in a ClickUp space for organizing related lists. Use this tool when you need to group multiple lists together.
|
|
218
|
+
description: "Create a new folder in a ClickUp space for organizing related lists. Use this tool when you need to group multiple lists together. Before calling, check if you already have the necessary space ID from previous responses in the conversation, as this avoids redundant lookups. After creating a folder, you can add lists to it using create_list_in_folder.",
|
|
219
219
|
inputSchema: {
|
|
220
220
|
type: "object",
|
|
221
221
|
properties: {
|
|
222
222
|
spaceId: {
|
|
223
223
|
type: "string",
|
|
224
|
-
description: "ID of the space to create the folder in (optional if using spaceName instead)"
|
|
224
|
+
description: "ID of the space to create the folder in (optional if using spaceName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
225
225
|
},
|
|
226
226
|
spaceName: {
|
|
227
227
|
type: "string",
|
|
228
|
-
description: "Name of the space to create the folder in - will automatically find the space by name (optional if using spaceId instead)"
|
|
228
|
+
description: "Name of the space to create the folder in - will automatically find the space by name (optional if using spaceId instead). Only use this if you don't already have the space ID from previous responses."
|
|
229
229
|
},
|
|
230
230
|
name: {
|
|
231
231
|
type: "string",
|
|
@@ -241,25 +241,25 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
241
241
|
},
|
|
242
242
|
{
|
|
243
243
|
name: "create_list_in_folder",
|
|
244
|
-
description: "Create a new list within a ClickUp folder. Use this tool when you need to add a list to an existing folder structure.
|
|
244
|
+
description: "Create a new list within a ClickUp folder. Use this tool when you need to add a list to an existing folder structure. Before calling, check if you already have the necessary folder ID and space ID from previous responses in the conversation, as this avoids redundant lookups. For top-level lists not in folders, use create_list instead.",
|
|
245
245
|
inputSchema: {
|
|
246
246
|
type: "object",
|
|
247
247
|
properties: {
|
|
248
248
|
folderId: {
|
|
249
249
|
type: "string",
|
|
250
|
-
description: "ID of the folder to create the list in (optional if using folderName instead)"
|
|
250
|
+
description: "ID of the folder to create the list in (optional if using folderName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
251
251
|
},
|
|
252
252
|
folderName: {
|
|
253
253
|
type: "string",
|
|
254
|
-
description: "Name of the folder to create the list in - will automatically find the folder by name (optional if using folderId instead)"
|
|
254
|
+
description: "Name of the folder to create the list in - will automatically find the folder by name (optional if using folderId instead). Only use this if you don't already have the folder ID from previous responses."
|
|
255
255
|
},
|
|
256
256
|
spaceId: {
|
|
257
257
|
type: "string",
|
|
258
|
-
description: "ID of the space containing the folder (optional if using spaceName instead)"
|
|
258
|
+
description: "ID of the space containing the folder (optional if using spaceName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
259
259
|
},
|
|
260
260
|
spaceName: {
|
|
261
261
|
type: "string",
|
|
262
|
-
description: "Name of the space containing the folder - will automatically find the space by name (optional if using spaceId instead)"
|
|
262
|
+
description: "Name of the space containing the folder - will automatically find the space by name (optional if using spaceId instead). Only use this if you don't already have the space ID from previous responses."
|
|
263
263
|
},
|
|
264
264
|
name: {
|
|
265
265
|
type: "string",
|
|
@@ -279,17 +279,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
279
279
|
},
|
|
280
280
|
{
|
|
281
281
|
name: "move_task",
|
|
282
|
-
description: "Move an existing task from its current list to a different list. Use this tool when you need to relocate a task within your workspace hierarchy.
|
|
282
|
+
description: "Move an existing task from its current list to a different list. Use this tool when you need to relocate a task within your workspace hierarchy. Before calling, check if you already have the necessary task ID and list ID from previous responses in the conversation, as this avoids redundant lookups. Task statuses may be reset if the destination list uses different status options.",
|
|
283
283
|
inputSchema: {
|
|
284
284
|
type: "object",
|
|
285
285
|
properties: {
|
|
286
286
|
taskId: {
|
|
287
287
|
type: "string",
|
|
288
|
-
description: "ID of the task to move (optional if using taskName instead)"
|
|
288
|
+
description: "ID of the task to move (optional if using taskName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
289
289
|
},
|
|
290
290
|
taskName: {
|
|
291
291
|
type: "string",
|
|
292
|
-
description: "Name of the task to move - will automatically find the task by name (optional if using taskId instead)"
|
|
292
|
+
description: "Name of the task to move - will automatically find the task by name (optional if using taskId instead). Only use this if you don't already have the task ID from previous responses."
|
|
293
293
|
},
|
|
294
294
|
sourceListName: {
|
|
295
295
|
type: "string",
|
|
@@ -297,11 +297,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
297
297
|
},
|
|
298
298
|
listId: {
|
|
299
299
|
type: "string",
|
|
300
|
-
description: "ID of the destination list (optional if using listName instead)"
|
|
300
|
+
description: "ID of the destination list (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
301
301
|
},
|
|
302
302
|
listName: {
|
|
303
303
|
type: "string",
|
|
304
|
-
description: "Name of the destination list - will automatically find the list by name (optional if using listId instead)"
|
|
304
|
+
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
305
|
}
|
|
306
306
|
},
|
|
307
307
|
required: ["taskName", "listName"]
|
|
@@ -309,17 +309,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
309
309
|
},
|
|
310
310
|
{
|
|
311
311
|
name: "duplicate_task",
|
|
312
|
-
description: "Create a copy of an existing task in the same or different list. Use this tool when you need to replicate a task's content and properties.
|
|
312
|
+
description: "Create a copy of an existing task in the same or different list. Use this tool when you need to replicate a task's content and properties. Before calling, check if you already have the necessary task ID and list ID from previous responses in the conversation, as this avoids redundant lookups. The duplicate will preserve name, description, priority, and other attributes from the original task.",
|
|
313
313
|
inputSchema: {
|
|
314
314
|
type: "object",
|
|
315
315
|
properties: {
|
|
316
316
|
taskId: {
|
|
317
317
|
type: "string",
|
|
318
|
-
description: "ID of the task to duplicate (optional if using taskName instead)"
|
|
318
|
+
description: "ID of the task to duplicate (optional if using taskName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
319
319
|
},
|
|
320
320
|
taskName: {
|
|
321
321
|
type: "string",
|
|
322
|
-
description: "Name of the task to duplicate - will automatically find the task by name (optional if using taskId instead)"
|
|
322
|
+
description: "Name of the task to duplicate - will automatically find the task by name (optional if using taskId instead). Only use this if you don't already have the task ID from previous responses."
|
|
323
323
|
},
|
|
324
324
|
sourceListName: {
|
|
325
325
|
type: "string",
|
|
@@ -327,11 +327,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
327
327
|
},
|
|
328
328
|
listId: {
|
|
329
329
|
type: "string",
|
|
330
|
-
description: "ID of the list to create the duplicate in (optional if using listName instead)"
|
|
330
|
+
description: "ID of the list to create the duplicate in (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
331
331
|
},
|
|
332
332
|
listName: {
|
|
333
333
|
type: "string",
|
|
334
|
-
description: "Name of the list to create the duplicate in - will automatically find the list by name (optional if using listId instead)"
|
|
334
|
+
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
335
|
}
|
|
336
336
|
},
|
|
337
337
|
required: ["taskName", "listName"]
|
|
@@ -339,17 +339,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
339
339
|
},
|
|
340
340
|
{
|
|
341
341
|
name: "update_task",
|
|
342
|
-
description: "Modify the properties of an existing task. Use this tool when you need to change a task's name, description, status, priority, or due date.
|
|
342
|
+
description: "Modify the properties of an existing task. Use this tool when you need to change a task's name, description, status, priority, or due date. Before calling, check if you already have the necessary task ID from previous responses in the conversation, as this avoids redundant lookups. Only the fields you specify will be updated; other fields will remain unchanged.",
|
|
343
343
|
inputSchema: {
|
|
344
344
|
type: "object",
|
|
345
345
|
properties: {
|
|
346
346
|
taskId: {
|
|
347
347
|
type: "string",
|
|
348
|
-
description: "ID of the task to update (optional if using taskName instead)"
|
|
348
|
+
description: "ID of the task to update (optional if using taskName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
349
349
|
},
|
|
350
350
|
taskName: {
|
|
351
351
|
type: "string",
|
|
352
|
-
description: "Name of the task to update - will automatically find the task by name (optional if using taskId instead)"
|
|
352
|
+
description: "Name of the task to update - will automatically find the task by name (optional if using taskId instead). Only use this if you don't already have the task ID from previous responses."
|
|
353
353
|
},
|
|
354
354
|
listName: {
|
|
355
355
|
type: "string",
|
|
@@ -381,17 +381,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
381
381
|
},
|
|
382
382
|
{
|
|
383
383
|
name: "get_tasks",
|
|
384
|
-
description: "Retrieve tasks from a ClickUp list with optional filtering capabilities. Use this tool when you need to see existing tasks or analyze your current workload.
|
|
384
|
+
description: "Retrieve tasks from a ClickUp list with optional filtering capabilities. Use this tool when you need to see existing tasks or analyze your current workload. Before calling, check if you already have the necessary list ID from previous responses in the conversation, as this avoids redundant lookups. Results can be filtered by status, assignees, dates, and more.",
|
|
385
385
|
inputSchema: {
|
|
386
386
|
type: "object",
|
|
387
387
|
properties: {
|
|
388
388
|
listId: {
|
|
389
389
|
type: "string",
|
|
390
|
-
description: "ID of the list to get tasks from (optional if using listName instead)"
|
|
390
|
+
description: "ID of the list to get tasks from (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
391
391
|
},
|
|
392
392
|
listName: {
|
|
393
393
|
type: "string",
|
|
394
|
-
description: "Name of the list to get tasks from - will automatically find the list by name (optional if using listId instead)"
|
|
394
|
+
description: "Name of the list to get tasks from - 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."
|
|
395
395
|
},
|
|
396
396
|
archived: {
|
|
397
397
|
type: "boolean",
|
|
@@ -461,17 +461,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
461
461
|
},
|
|
462
462
|
{
|
|
463
463
|
name: "get_task",
|
|
464
|
-
description: "Retrieve comprehensive details about a specific ClickUp task. Use this tool when you need in-depth information about a particular task, including its description, custom fields, attachments, and other metadata.
|
|
464
|
+
description: "Retrieve comprehensive details about a specific ClickUp task. Use this tool when you need in-depth information about a particular task, including its description, custom fields, attachments, and other metadata. Before calling, check if you already have the necessary task ID from previous responses in the conversation, as this avoids redundant lookups.",
|
|
465
465
|
inputSchema: {
|
|
466
466
|
type: "object",
|
|
467
467
|
properties: {
|
|
468
468
|
taskId: {
|
|
469
469
|
type: "string",
|
|
470
|
-
description: "ID of the task to retrieve (optional if using taskName instead)"
|
|
470
|
+
description: "ID of the task to retrieve (optional if using taskName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
471
471
|
},
|
|
472
472
|
taskName: {
|
|
473
473
|
type: "string",
|
|
474
|
-
description: "Name of the task to retrieve - will automatically find the task by name (optional if using taskId instead)"
|
|
474
|
+
description: "Name of the task to retrieve - will automatically find the task by name (optional if using taskId instead). Only use this if you don't already have the task ID from previous responses."
|
|
475
475
|
},
|
|
476
476
|
listName: {
|
|
477
477
|
type: "string",
|
|
@@ -483,17 +483,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
483
483
|
},
|
|
484
484
|
{
|
|
485
485
|
name: "delete_task",
|
|
486
|
-
description: "Permanently remove a task from your ClickUp workspace. Use this tool with caution as deletion cannot be undone.
|
|
486
|
+
description: "Permanently remove a task from your ClickUp workspace. Use this tool with caution as deletion cannot be undone. Before calling, check if you already have the necessary task ID from previous responses in the conversation, as this avoids redundant lookups. For safety, the task ID is required.",
|
|
487
487
|
inputSchema: {
|
|
488
488
|
type: "object",
|
|
489
489
|
properties: {
|
|
490
490
|
taskId: {
|
|
491
491
|
type: "string",
|
|
492
|
-
description: "ID of the task to delete - this is required for safety to prevent accidental deletions"
|
|
492
|
+
description: "ID of the task to delete - this is required for safety to prevent accidental deletions. If you have this ID from a previous response, use it directly."
|
|
493
493
|
},
|
|
494
494
|
taskName: {
|
|
495
495
|
type: "string",
|
|
496
|
-
description: "Name of the task to delete - will automatically find the task by name (optional if using taskId instead)"
|
|
496
|
+
description: "Name of the task to delete - will automatically find the task by name (optional if using taskId instead). Only use this if you don't already have the task ID from previous responses."
|
|
497
497
|
},
|
|
498
498
|
listName: {
|
|
499
499
|
type: "string",
|
|
@@ -502,6 +502,158 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
502
502
|
},
|
|
503
503
|
required: ["taskId"]
|
|
504
504
|
}
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
name: "get_folder",
|
|
508
|
+
description: "Retrieve details about a specific ClickUp folder including its name, status, and other metadata. Before calling, check if you already have the necessary folder ID from previous responses in the conversation history, as this avoids redundant lookups. Helps you understand folder structure before creating or updating lists.",
|
|
509
|
+
inputSchema: {
|
|
510
|
+
type: "object",
|
|
511
|
+
properties: {
|
|
512
|
+
folderId: {
|
|
513
|
+
type: "string",
|
|
514
|
+
description: "ID of the folder to retrieve (optional if using folderName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
515
|
+
},
|
|
516
|
+
folderName: {
|
|
517
|
+
type: "string",
|
|
518
|
+
description: "Name of the folder to retrieve - will automatically find the folder by name (optional if using folderId instead). Only use this if you don't already have the folder ID from previous responses."
|
|
519
|
+
},
|
|
520
|
+
spaceId: {
|
|
521
|
+
type: "string",
|
|
522
|
+
description: "ID of the space containing the folder (optional if using spaceName instead, and only needed when using folderName). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
523
|
+
},
|
|
524
|
+
spaceName: {
|
|
525
|
+
type: "string",
|
|
526
|
+
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."
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
required: []
|
|
530
|
+
}
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
name: "update_folder",
|
|
534
|
+
description: "Modify an existing ClickUp folder's properties, such as name or status settings. Before calling, check if you already have the necessary folder ID from previous responses in the conversation history, as this avoids redundant lookups. Use when reorganizing or renaming workspace elements.",
|
|
535
|
+
inputSchema: {
|
|
536
|
+
type: "object",
|
|
537
|
+
properties: {
|
|
538
|
+
folderId: {
|
|
539
|
+
type: "string",
|
|
540
|
+
description: "ID of the folder to update (optional if using folderName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
541
|
+
},
|
|
542
|
+
folderName: {
|
|
543
|
+
type: "string",
|
|
544
|
+
description: "Name of the folder to update - will automatically find the folder by name (optional if using folderId instead). Only use this if you don't already have the folder ID from previous responses."
|
|
545
|
+
},
|
|
546
|
+
spaceId: {
|
|
547
|
+
type: "string",
|
|
548
|
+
description: "ID of the space containing the folder (optional if using spaceName instead, and only needed when using folderName). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
549
|
+
},
|
|
550
|
+
spaceName: {
|
|
551
|
+
type: "string",
|
|
552
|
+
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."
|
|
553
|
+
},
|
|
554
|
+
name: {
|
|
555
|
+
type: "string",
|
|
556
|
+
description: "New name for the folder"
|
|
557
|
+
},
|
|
558
|
+
override_statuses: {
|
|
559
|
+
type: "boolean",
|
|
560
|
+
description: "Whether to override space statuses with folder-specific statuses"
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
required: []
|
|
564
|
+
}
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
name: "delete_folder",
|
|
568
|
+
description: "Permanently remove a folder from your ClickUp workspace. Use with caution as deletion cannot be undone and will remove all lists and tasks within the folder. Before calling, check if you already have the necessary folder ID from previous responses in the conversation history, as this avoids redundant lookups.",
|
|
569
|
+
inputSchema: {
|
|
570
|
+
type: "object",
|
|
571
|
+
properties: {
|
|
572
|
+
folderId: {
|
|
573
|
+
type: "string",
|
|
574
|
+
description: "ID of the folder to delete (optional if using folderName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
575
|
+
},
|
|
576
|
+
folderName: {
|
|
577
|
+
type: "string",
|
|
578
|
+
description: "Name of the folder to delete - will automatically find the folder by name (optional if using folderId instead). Only use this if you don't already have the folder ID from previous responses."
|
|
579
|
+
},
|
|
580
|
+
spaceId: {
|
|
581
|
+
type: "string",
|
|
582
|
+
description: "ID of the space containing the folder (optional if using spaceName instead, and only needed when using folderName). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
583
|
+
},
|
|
584
|
+
spaceName: {
|
|
585
|
+
type: "string",
|
|
586
|
+
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."
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
required: []
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
name: "get_list",
|
|
594
|
+
description: "Retrieve details about a specific ClickUp list including its name, content, status options, and other metadata. Before calling, check if you already have the necessary list ID from previous responses in the conversation history, as this avoids redundant lookups. Useful to understand list structure before creating or updating tasks.",
|
|
595
|
+
inputSchema: {
|
|
596
|
+
type: "object",
|
|
597
|
+
properties: {
|
|
598
|
+
listId: {
|
|
599
|
+
type: "string",
|
|
600
|
+
description: "ID of the list to retrieve (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
601
|
+
},
|
|
602
|
+
listName: {
|
|
603
|
+
type: "string",
|
|
604
|
+
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."
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
required: []
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
name: "update_list",
|
|
612
|
+
description: "Modify an existing ClickUp list's properties, such as name, content, or status options. Before calling, check if you already have the necessary list ID from previous responses in the conversation history, as this avoids redundant lookups. Use when reorganizing or renaming workspace elements.",
|
|
613
|
+
inputSchema: {
|
|
614
|
+
type: "object",
|
|
615
|
+
properties: {
|
|
616
|
+
listId: {
|
|
617
|
+
type: "string",
|
|
618
|
+
description: "ID of the list to update (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
619
|
+
},
|
|
620
|
+
listName: {
|
|
621
|
+
type: "string",
|
|
622
|
+
description: "Name of the list to update - 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."
|
|
623
|
+
},
|
|
624
|
+
name: {
|
|
625
|
+
type: "string",
|
|
626
|
+
description: "New name for the list"
|
|
627
|
+
},
|
|
628
|
+
content: {
|
|
629
|
+
type: "string",
|
|
630
|
+
description: "New description or content for the list"
|
|
631
|
+
},
|
|
632
|
+
status: {
|
|
633
|
+
type: "string",
|
|
634
|
+
description: "New status for the list"
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
required: []
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
name: "delete_list",
|
|
642
|
+
description: "Permanently remove a list from your ClickUp workspace. Use with caution as deletion cannot be undone and will remove all tasks within the list. Before calling, check if you already have the necessary list ID from previous responses in the conversation history, as this avoids redundant lookups.",
|
|
643
|
+
inputSchema: {
|
|
644
|
+
type: "object",
|
|
645
|
+
properties: {
|
|
646
|
+
listId: {
|
|
647
|
+
type: "string",
|
|
648
|
+
description: "ID of the list to delete (optional if using listName instead). If you have this ID from a previous response, use it directly rather than looking up by name."
|
|
649
|
+
},
|
|
650
|
+
listName: {
|
|
651
|
+
type: "string",
|
|
652
|
+
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."
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
required: []
|
|
656
|
+
}
|
|
505
657
|
}
|
|
506
658
|
]
|
|
507
659
|
};
|
|
@@ -841,6 +993,243 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
841
993
|
}]
|
|
842
994
|
};
|
|
843
995
|
}
|
|
996
|
+
case "get_folder": {
|
|
997
|
+
const args = request.params.arguments;
|
|
998
|
+
if (!args.folderId && !args.folderName) {
|
|
999
|
+
throw new Error("Either folderId or folderName is required");
|
|
1000
|
+
}
|
|
1001
|
+
let folderId = args.folderId;
|
|
1002
|
+
if (!folderId && args.folderName) {
|
|
1003
|
+
// If we need to look up by name, we might need the space
|
|
1004
|
+
let spaceId = args.spaceId;
|
|
1005
|
+
if (!spaceId && args.spaceName) {
|
|
1006
|
+
const foundId = await clickup.findSpaceIDByName(args.spaceName);
|
|
1007
|
+
if (!foundId) {
|
|
1008
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
1009
|
+
}
|
|
1010
|
+
spaceId = foundId;
|
|
1011
|
+
}
|
|
1012
|
+
if (!spaceId) {
|
|
1013
|
+
// Try to find folder directly by name (will search across all spaces)
|
|
1014
|
+
const result = await clickup.findFolderIDByName(args.folderName);
|
|
1015
|
+
if (!result) {
|
|
1016
|
+
throw new Error(`Folder with name "${args.folderName}" not found`);
|
|
1017
|
+
}
|
|
1018
|
+
folderId = result.id;
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
// Look in a specific space
|
|
1022
|
+
const folder = await clickup.findFolderByName(spaceId, args.folderName);
|
|
1023
|
+
if (!folder) {
|
|
1024
|
+
throw new Error(`Folder with name "${args.folderName}" not found in specified space`);
|
|
1025
|
+
}
|
|
1026
|
+
folderId = folder.id;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
// Ensure folderId is defined at this point
|
|
1030
|
+
if (!folderId) {
|
|
1031
|
+
throw new Error("Failed to determine folder ID");
|
|
1032
|
+
}
|
|
1033
|
+
const folder = await clickup.getFolder(folderId);
|
|
1034
|
+
return {
|
|
1035
|
+
content: [{
|
|
1036
|
+
type: "text",
|
|
1037
|
+
text: JSON.stringify(folder, null, 2)
|
|
1038
|
+
}]
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
case "update_folder": {
|
|
1042
|
+
const args = request.params.arguments;
|
|
1043
|
+
if (!args.folderId && !args.folderName) {
|
|
1044
|
+
throw new Error("Either folderId or folderName is required");
|
|
1045
|
+
}
|
|
1046
|
+
let folderId = args.folderId;
|
|
1047
|
+
if (!folderId && args.folderName) {
|
|
1048
|
+
// If we need to look up by name, we might need the space
|
|
1049
|
+
let spaceId = args.spaceId;
|
|
1050
|
+
if (!spaceId && args.spaceName) {
|
|
1051
|
+
const foundId = await clickup.findSpaceIDByName(args.spaceName);
|
|
1052
|
+
if (!foundId) {
|
|
1053
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
1054
|
+
}
|
|
1055
|
+
spaceId = foundId;
|
|
1056
|
+
}
|
|
1057
|
+
if (!spaceId) {
|
|
1058
|
+
// Try to find folder directly by name (will search across all spaces)
|
|
1059
|
+
const result = await clickup.findFolderIDByName(args.folderName);
|
|
1060
|
+
if (!result) {
|
|
1061
|
+
throw new Error(`Folder with name "${args.folderName}" not found`);
|
|
1062
|
+
}
|
|
1063
|
+
folderId = result.id;
|
|
1064
|
+
}
|
|
1065
|
+
else {
|
|
1066
|
+
// Look in a specific space
|
|
1067
|
+
const folder = await clickup.findFolderByName(spaceId, args.folderName);
|
|
1068
|
+
if (!folder) {
|
|
1069
|
+
throw new Error(`Folder with name "${args.folderName}" not found in specified space`);
|
|
1070
|
+
}
|
|
1071
|
+
folderId = folder.id;
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
// Ensure folderId is defined at this point
|
|
1075
|
+
if (!folderId) {
|
|
1076
|
+
throw new Error("Failed to determine folder ID");
|
|
1077
|
+
}
|
|
1078
|
+
// Extract update data
|
|
1079
|
+
const { folderId: _, folderName: __, spaceId: ___, spaceName: ____, ...updateData } = args;
|
|
1080
|
+
// Call the updateFolder method
|
|
1081
|
+
const updatedFolder = await clickup.updateFolder(folderId, updateData);
|
|
1082
|
+
return {
|
|
1083
|
+
content: [{
|
|
1084
|
+
type: "text",
|
|
1085
|
+
text: `Updated folder ${updatedFolder.id}: ${updatedFolder.name}`
|
|
1086
|
+
}]
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
case "delete_folder": {
|
|
1090
|
+
const args = request.params.arguments;
|
|
1091
|
+
if (!args.folderId && !args.folderName) {
|
|
1092
|
+
throw new Error("Either folderId or folderName is required");
|
|
1093
|
+
}
|
|
1094
|
+
let folderId = args.folderId;
|
|
1095
|
+
if (!folderId && args.folderName) {
|
|
1096
|
+
// If we need to look up by name, we might need the space
|
|
1097
|
+
let spaceId = args.spaceId;
|
|
1098
|
+
if (!spaceId && args.spaceName) {
|
|
1099
|
+
const foundId = await clickup.findSpaceIDByName(args.spaceName);
|
|
1100
|
+
if (!foundId) {
|
|
1101
|
+
throw new Error(`Space with name "${args.spaceName}" not found`);
|
|
1102
|
+
}
|
|
1103
|
+
spaceId = foundId;
|
|
1104
|
+
}
|
|
1105
|
+
if (!spaceId) {
|
|
1106
|
+
// Try to find folder directly by name (will search across all spaces)
|
|
1107
|
+
const result = await clickup.findFolderIDByName(args.folderName);
|
|
1108
|
+
if (!result) {
|
|
1109
|
+
throw new Error(`Folder with name "${args.folderName}" not found`);
|
|
1110
|
+
}
|
|
1111
|
+
folderId = result.id;
|
|
1112
|
+
}
|
|
1113
|
+
else {
|
|
1114
|
+
// Look in a specific space
|
|
1115
|
+
const folder = await clickup.findFolderByName(spaceId, args.folderName);
|
|
1116
|
+
if (!folder) {
|
|
1117
|
+
throw new Error(`Folder with name "${args.folderName}" not found in specified space`);
|
|
1118
|
+
}
|
|
1119
|
+
folderId = folder.id;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
// Ensure folderId is defined at this point
|
|
1123
|
+
if (!folderId) {
|
|
1124
|
+
throw new Error("Failed to determine folder ID");
|
|
1125
|
+
}
|
|
1126
|
+
// Store the folder name before deletion for the response message
|
|
1127
|
+
let folderName = args.folderName;
|
|
1128
|
+
if (!folderName) {
|
|
1129
|
+
try {
|
|
1130
|
+
const folderDetails = await clickup.getFolder(folderId);
|
|
1131
|
+
folderName = folderDetails.name;
|
|
1132
|
+
}
|
|
1133
|
+
catch (error) {
|
|
1134
|
+
// If we can't get the folder details, just use the ID in the response
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
await clickup.deleteFolder(folderId);
|
|
1138
|
+
return {
|
|
1139
|
+
content: [{
|
|
1140
|
+
type: "text",
|
|
1141
|
+
text: `Successfully deleted folder ${folderName || folderId}`
|
|
1142
|
+
}]
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
case "get_list": {
|
|
1146
|
+
const args = request.params.arguments;
|
|
1147
|
+
if (!args.listId && !args.listName) {
|
|
1148
|
+
throw new Error("Either listId or listName is required");
|
|
1149
|
+
}
|
|
1150
|
+
let listId = args.listId;
|
|
1151
|
+
if (!listId && args.listName) {
|
|
1152
|
+
const result = await clickup.findListIDByName(args.listName);
|
|
1153
|
+
if (!result) {
|
|
1154
|
+
throw new Error(`List with name "${args.listName}" not found`);
|
|
1155
|
+
}
|
|
1156
|
+
listId = result.id;
|
|
1157
|
+
}
|
|
1158
|
+
// Ensure listId is defined at this point
|
|
1159
|
+
if (!listId) {
|
|
1160
|
+
throw new Error("Failed to determine list ID");
|
|
1161
|
+
}
|
|
1162
|
+
const listDetails = await clickup.getList(listId);
|
|
1163
|
+
return {
|
|
1164
|
+
content: [{
|
|
1165
|
+
type: "text",
|
|
1166
|
+
text: JSON.stringify(listDetails, null, 2)
|
|
1167
|
+
}]
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
case "update_list": {
|
|
1171
|
+
const args = request.params.arguments;
|
|
1172
|
+
if (!args.listId && !args.listName) {
|
|
1173
|
+
throw new Error("Either listId or listName is required");
|
|
1174
|
+
}
|
|
1175
|
+
let listId = args.listId;
|
|
1176
|
+
if (!listId && args.listName) {
|
|
1177
|
+
const result = await clickup.findListIDByName(args.listName);
|
|
1178
|
+
if (!result) {
|
|
1179
|
+
throw new Error(`List with name "${args.listName}" not found`);
|
|
1180
|
+
}
|
|
1181
|
+
listId = result.id;
|
|
1182
|
+
}
|
|
1183
|
+
// Ensure listId is defined at this point
|
|
1184
|
+
if (!listId) {
|
|
1185
|
+
throw new Error("Failed to determine list ID");
|
|
1186
|
+
}
|
|
1187
|
+
// Extract update data
|
|
1188
|
+
const { listId: _, listName: __, ...updateData } = args;
|
|
1189
|
+
const updatedList = await clickup.updateList(listId, updateData);
|
|
1190
|
+
return {
|
|
1191
|
+
content: [{
|
|
1192
|
+
type: "text",
|
|
1193
|
+
text: `Updated list ${updatedList.id}: ${updatedList.name}`
|
|
1194
|
+
}]
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
case "delete_list": {
|
|
1198
|
+
const args = request.params.arguments;
|
|
1199
|
+
if (!args.listId && !args.listName) {
|
|
1200
|
+
throw new Error("Either listId or listName is required");
|
|
1201
|
+
}
|
|
1202
|
+
let listId = args.listId;
|
|
1203
|
+
if (!listId && args.listName) {
|
|
1204
|
+
const result = await clickup.findListIDByName(args.listName);
|
|
1205
|
+
if (!result) {
|
|
1206
|
+
throw new Error(`List with name "${args.listName}" not found`);
|
|
1207
|
+
}
|
|
1208
|
+
listId = result.id;
|
|
1209
|
+
}
|
|
1210
|
+
// Ensure listId is defined at this point
|
|
1211
|
+
if (!listId) {
|
|
1212
|
+
throw new Error("Failed to determine list ID");
|
|
1213
|
+
}
|
|
1214
|
+
// Store the list name before deletion for the response message
|
|
1215
|
+
let listName = args.listName;
|
|
1216
|
+
if (!listName) {
|
|
1217
|
+
try {
|
|
1218
|
+
const listDetails = await clickup.getList(listId);
|
|
1219
|
+
listName = listDetails.name;
|
|
1220
|
+
}
|
|
1221
|
+
catch (error) {
|
|
1222
|
+
// If we can't get the list details, just use the ID in the response
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
await clickup.deleteList(listId);
|
|
1226
|
+
return {
|
|
1227
|
+
content: [{
|
|
1228
|
+
type: "text",
|
|
1229
|
+
text: `Successfully deleted list ${listName || listId}`
|
|
1230
|
+
}]
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
844
1233
|
default:
|
|
845
1234
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
846
1235
|
}
|
|
@@ -309,9 +309,16 @@ export class ClickUpService {
|
|
|
309
309
|
return response.data;
|
|
310
310
|
});
|
|
311
311
|
}
|
|
312
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Updates an existing folder with new data.
|
|
314
|
+
* @param folderId - ID of the folder to update
|
|
315
|
+
* @param data - Data to update the folder with (name, override_statuses)
|
|
316
|
+
* @returns Promise resolving to the updated ClickUpFolder
|
|
317
|
+
* @throws Error if the API request fails
|
|
318
|
+
*/
|
|
319
|
+
async updateFolder(folderId, data) {
|
|
313
320
|
return this.makeRequest(async () => {
|
|
314
|
-
const response = await this.client.
|
|
321
|
+
const response = await this.client.put(`/folder/${folderId}`, data);
|
|
315
322
|
return response.data;
|
|
316
323
|
});
|
|
317
324
|
}
|
|
@@ -337,6 +344,19 @@ export class ClickUpService {
|
|
|
337
344
|
const folders = await this.getFolders(spaceId);
|
|
338
345
|
return folders.find(folder => folder.name.toLowerCase() === folderName.toLowerCase()) || null;
|
|
339
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Creates a new folder in a space.
|
|
349
|
+
* @param spaceId - ID of the space to create the folder in
|
|
350
|
+
* @param data - Folder creation data (name, override_statuses)
|
|
351
|
+
* @returns Promise resolving to the created ClickUpFolder
|
|
352
|
+
* @throws Error if the API request fails
|
|
353
|
+
*/
|
|
354
|
+
async createFolder(spaceId, data) {
|
|
355
|
+
return this.makeRequest(async () => {
|
|
356
|
+
const response = await this.client.post(`/space/${spaceId}/folder`, data);
|
|
357
|
+
return response.data;
|
|
358
|
+
});
|
|
359
|
+
}
|
|
340
360
|
// Additional helper methods
|
|
341
361
|
/**
|
|
342
362
|
* Moves a task to a different list.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taazkareem/clickup-mcp-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.56",
|
|
4
4
|
"description": "ClickUp MCP Server - Integrate ClickUp tasks with AI through Model Context Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"build",
|
|
12
12
|
"README.md",
|
|
13
13
|
"LICENSE",
|
|
14
|
-
"Dockerfile
|
|
14
|
+
"Dockerfile",
|
|
15
15
|
"smithery.yaml"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "https://github.com/taazkareem/clickup-mcp-server.git"
|
|
39
|
+
"url": "git+https://github.com/taazkareem/clickup-mcp-server.git"
|
|
40
40
|
},
|
|
41
41
|
"bugs": {
|
|
42
42
|
"url": "https://github.com/taazkareem/clickup-mcp-server/issues"
|