@taazkareem/clickup-mcp-server 0.4.18 → 0.4.20
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/build/index.js +402 -424
- package/package.json +2 -3
package/build/index.js
CHANGED
|
@@ -49,457 +49,435 @@ catch (error) {
|
|
|
49
49
|
* Sets up capabilities, tools, and error handling
|
|
50
50
|
*/
|
|
51
51
|
logDebug('mcp', { status: 'creating' });
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
listId: {
|
|
72
|
-
type: "string",
|
|
73
|
-
description: "ID of the list to create the task in (optional if listName is provided)"
|
|
74
|
-
},
|
|
75
|
-
listName: {
|
|
76
|
-
type: "string",
|
|
77
|
-
description: "Name of the list to create the task in (optional if listId is provided)"
|
|
78
|
-
},
|
|
79
|
-
name: {
|
|
80
|
-
type: "string",
|
|
81
|
-
description: "Name of the task"
|
|
82
|
-
},
|
|
83
|
-
description: {
|
|
84
|
-
type: "string",
|
|
85
|
-
description: "Description of the task"
|
|
86
|
-
},
|
|
87
|
-
status: {
|
|
88
|
-
type: "string",
|
|
89
|
-
description: "Status of the task"
|
|
90
|
-
},
|
|
91
|
-
priority: {
|
|
92
|
-
type: "number",
|
|
93
|
-
description: "Priority of the task (1-4)"
|
|
94
|
-
},
|
|
95
|
-
dueDate: {
|
|
96
|
-
type: "string",
|
|
97
|
-
description: "Due date of the task (ISO string)"
|
|
98
|
-
}
|
|
52
|
+
// Define server capabilities
|
|
53
|
+
const serverCapabilities = {
|
|
54
|
+
tools: {
|
|
55
|
+
workspace_hierarchy: {
|
|
56
|
+
description: "List complete hierarchy of the ClickUp workspace",
|
|
57
|
+
inputSchema: {
|
|
58
|
+
type: "object",
|
|
59
|
+
properties: {},
|
|
60
|
+
required: []
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
create_task: {
|
|
64
|
+
description: "Create a new task in ClickUp",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
properties: {
|
|
68
|
+
listId: {
|
|
69
|
+
type: "string",
|
|
70
|
+
description: "ID of the list to create the task in (optional if listName is provided)"
|
|
99
71
|
},
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
create_bulk_tasks: {
|
|
104
|
-
description: "Create multiple tasks simultaneously in a list",
|
|
105
|
-
inputSchema: {
|
|
106
|
-
type: "object",
|
|
107
|
-
properties: {
|
|
108
|
-
listId: {
|
|
109
|
-
type: "string",
|
|
110
|
-
description: "ID of the list to create tasks in (optional if listName is provided)"
|
|
111
|
-
},
|
|
112
|
-
listName: {
|
|
113
|
-
type: "string",
|
|
114
|
-
description: "Name of the list to create tasks in (optional if listId is provided)"
|
|
115
|
-
},
|
|
116
|
-
tasks: {
|
|
117
|
-
type: "array",
|
|
118
|
-
description: "Array of tasks to create",
|
|
119
|
-
items: {
|
|
120
|
-
type: "object",
|
|
121
|
-
properties: {
|
|
122
|
-
name: {
|
|
123
|
-
type: "string",
|
|
124
|
-
description: "Name of the task"
|
|
125
|
-
},
|
|
126
|
-
description: {
|
|
127
|
-
type: "string",
|
|
128
|
-
description: "Description of the task"
|
|
129
|
-
},
|
|
130
|
-
status: {
|
|
131
|
-
type: "string",
|
|
132
|
-
description: "Status of the task"
|
|
133
|
-
},
|
|
134
|
-
priority: {
|
|
135
|
-
type: "number",
|
|
136
|
-
description: "Priority of the task (1-4)"
|
|
137
|
-
},
|
|
138
|
-
dueDate: {
|
|
139
|
-
type: "string",
|
|
140
|
-
description: "Due date of the task (ISO string)"
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
required: ["name"]
|
|
144
|
-
}
|
|
145
|
-
}
|
|
72
|
+
listName: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Name of the list to create the task in (optional if listId is provided)"
|
|
146
75
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
create_list: {
|
|
151
|
-
description: "Create a new list in a space",
|
|
152
|
-
inputSchema: {
|
|
153
|
-
type: "object",
|
|
154
|
-
properties: {
|
|
155
|
-
spaceId: {
|
|
156
|
-
type: "string",
|
|
157
|
-
description: "ID of the space (optional if spaceName is provided)"
|
|
158
|
-
},
|
|
159
|
-
spaceName: {
|
|
160
|
-
type: "string",
|
|
161
|
-
description: "Name of the space (optional if spaceId is provided)"
|
|
162
|
-
},
|
|
163
|
-
name: {
|
|
164
|
-
type: "string",
|
|
165
|
-
description: "Name of the list"
|
|
166
|
-
},
|
|
167
|
-
content: {
|
|
168
|
-
type: "string",
|
|
169
|
-
description: "List description"
|
|
170
|
-
}
|
|
76
|
+
name: {
|
|
77
|
+
type: "string",
|
|
78
|
+
description: "Name of the task"
|
|
171
79
|
},
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
create_folder: {
|
|
176
|
-
description: "Create a new folder in a space",
|
|
177
|
-
inputSchema: {
|
|
178
|
-
type: "object",
|
|
179
|
-
properties: {
|
|
180
|
-
spaceId: {
|
|
181
|
-
type: "string",
|
|
182
|
-
description: "ID of the space (optional if spaceName is provided)"
|
|
183
|
-
},
|
|
184
|
-
spaceName: {
|
|
185
|
-
type: "string",
|
|
186
|
-
description: "Name of the space (optional if spaceId is provided)"
|
|
187
|
-
},
|
|
188
|
-
name: {
|
|
189
|
-
type: "string",
|
|
190
|
-
description: "Name of the folder"
|
|
191
|
-
},
|
|
192
|
-
override_statuses: {
|
|
193
|
-
type: "boolean",
|
|
194
|
-
description: "Whether to override space statuses"
|
|
195
|
-
}
|
|
80
|
+
description: {
|
|
81
|
+
type: "string",
|
|
82
|
+
description: "Description of the task"
|
|
196
83
|
},
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
create_list_in_folder: {
|
|
201
|
-
description: "Create a new list within a folder",
|
|
202
|
-
inputSchema: {
|
|
203
|
-
type: "object",
|
|
204
|
-
properties: {
|
|
205
|
-
folderId: {
|
|
206
|
-
type: "string",
|
|
207
|
-
description: "ID of the folder (optional if using folderName)"
|
|
208
|
-
},
|
|
209
|
-
folderName: {
|
|
210
|
-
type: "string",
|
|
211
|
-
description: "Name of the folder"
|
|
212
|
-
},
|
|
213
|
-
spaceId: {
|
|
214
|
-
type: "string",
|
|
215
|
-
description: "ID of the space (required if using folderName)"
|
|
216
|
-
},
|
|
217
|
-
spaceName: {
|
|
218
|
-
type: "string",
|
|
219
|
-
description: "Name of the space (alternative to spaceId)"
|
|
220
|
-
},
|
|
221
|
-
name: {
|
|
222
|
-
type: "string",
|
|
223
|
-
description: "Name of the list"
|
|
224
|
-
},
|
|
225
|
-
content: {
|
|
226
|
-
type: "string",
|
|
227
|
-
description: "List description"
|
|
228
|
-
}
|
|
84
|
+
status: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "Status of the task"
|
|
229
87
|
},
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
move_task: {
|
|
234
|
-
description: "Move a task to a different list",
|
|
235
|
-
inputSchema: {
|
|
236
|
-
type: "object",
|
|
237
|
-
properties: {
|
|
238
|
-
taskId: {
|
|
239
|
-
type: "string",
|
|
240
|
-
description: "ID of the task to move"
|
|
241
|
-
},
|
|
242
|
-
listId: {
|
|
243
|
-
type: "string",
|
|
244
|
-
description: "ID of destination list (optional if listName is provided)"
|
|
245
|
-
},
|
|
246
|
-
listName: {
|
|
247
|
-
type: "string",
|
|
248
|
-
description: "Name of destination list (optional if listId is provided)"
|
|
249
|
-
}
|
|
88
|
+
priority: {
|
|
89
|
+
type: "number",
|
|
90
|
+
description: "Priority of the task (1-4)"
|
|
250
91
|
},
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
listName: {
|
|
268
|
-
type: "string",
|
|
269
|
-
description: "Name of destination list (optional if listId is provided)"
|
|
270
|
-
}
|
|
92
|
+
dueDate: {
|
|
93
|
+
type: "string",
|
|
94
|
+
description: "Due date of the task (ISO string)"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
required: ["name"]
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
create_bulk_tasks: {
|
|
101
|
+
description: "Create multiple tasks simultaneously in a list",
|
|
102
|
+
inputSchema: {
|
|
103
|
+
type: "object",
|
|
104
|
+
properties: {
|
|
105
|
+
listId: {
|
|
106
|
+
type: "string",
|
|
107
|
+
description: "ID of the list to create tasks in (optional if listName is provided)"
|
|
271
108
|
},
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
update_task: {
|
|
276
|
-
description: "Update an existing task",
|
|
277
|
-
inputSchema: {
|
|
278
|
-
type: "object",
|
|
279
|
-
properties: {
|
|
280
|
-
taskId: {
|
|
281
|
-
type: "string",
|
|
282
|
-
description: "ID of the task to update"
|
|
283
|
-
},
|
|
284
|
-
name: {
|
|
285
|
-
type: "string",
|
|
286
|
-
description: "New task name"
|
|
287
|
-
},
|
|
288
|
-
description: {
|
|
289
|
-
type: "string",
|
|
290
|
-
description: "New description"
|
|
291
|
-
},
|
|
292
|
-
status: {
|
|
293
|
-
type: "string",
|
|
294
|
-
description: "New status"
|
|
295
|
-
},
|
|
296
|
-
priority: {
|
|
297
|
-
type: "number",
|
|
298
|
-
description: "New priority level (1-4)"
|
|
299
|
-
},
|
|
300
|
-
dueDate: {
|
|
301
|
-
type: "string",
|
|
302
|
-
description: "New due date (ISO string)"
|
|
303
|
-
}
|
|
109
|
+
listName: {
|
|
110
|
+
type: "string",
|
|
111
|
+
description: "Name of the list to create tasks in (optional if listId is provided)"
|
|
304
112
|
},
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
113
|
+
tasks: {
|
|
114
|
+
type: "array",
|
|
115
|
+
description: "Array of tasks to create",
|
|
116
|
+
items: {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {
|
|
119
|
+
name: {
|
|
120
|
+
type: "string",
|
|
121
|
+
description: "Name of the task"
|
|
122
|
+
},
|
|
123
|
+
description: {
|
|
124
|
+
type: "string",
|
|
125
|
+
description: "Description of the task"
|
|
126
|
+
},
|
|
127
|
+
status: {
|
|
128
|
+
type: "string",
|
|
129
|
+
description: "Status of the task"
|
|
130
|
+
},
|
|
131
|
+
priority: {
|
|
132
|
+
type: "number",
|
|
133
|
+
description: "Priority of the task (1-4)"
|
|
134
|
+
},
|
|
135
|
+
dueDate: {
|
|
136
|
+
type: "string",
|
|
137
|
+
description: "Due date of the task (ISO string)"
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
required: ["name"]
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
required: ["tasks"]
|
|
332
145
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
146
|
+
},
|
|
147
|
+
create_list: {
|
|
148
|
+
description: "Create a new list in a space",
|
|
149
|
+
inputSchema: {
|
|
150
|
+
type: "object",
|
|
151
|
+
properties: {
|
|
152
|
+
spaceId: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "ID of the space (optional if spaceName is provided)"
|
|
155
|
+
},
|
|
156
|
+
spaceName: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "Name of the space (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: "List description"
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
required: ["name"]
|
|
336
170
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
171
|
+
},
|
|
172
|
+
create_folder: {
|
|
173
|
+
description: "Create a new folder in a space",
|
|
174
|
+
inputSchema: {
|
|
175
|
+
type: "object",
|
|
176
|
+
properties: {
|
|
177
|
+
spaceId: {
|
|
178
|
+
type: "string",
|
|
179
|
+
description: "ID of the space (optional if spaceName is provided)"
|
|
180
|
+
},
|
|
181
|
+
spaceName: {
|
|
182
|
+
type: "string",
|
|
183
|
+
description: "Name of the space (optional if spaceId is provided)"
|
|
184
|
+
},
|
|
185
|
+
name: {
|
|
186
|
+
type: "string",
|
|
187
|
+
description: "Name of the folder"
|
|
188
|
+
},
|
|
189
|
+
override_statuses: {
|
|
190
|
+
type: "boolean",
|
|
191
|
+
description: "Whether to override space statuses"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
required: ["name"]
|
|
340
195
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
196
|
+
},
|
|
197
|
+
create_list_in_folder: {
|
|
198
|
+
description: "Create a new list within a folder",
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
folderId: {
|
|
203
|
+
type: "string",
|
|
204
|
+
description: "ID of the folder (optional if using folderName)"
|
|
205
|
+
},
|
|
206
|
+
folderName: {
|
|
207
|
+
type: "string",
|
|
208
|
+
description: "Name of the folder"
|
|
209
|
+
},
|
|
210
|
+
spaceId: {
|
|
211
|
+
type: "string",
|
|
212
|
+
description: "ID of the space (required if using folderName)"
|
|
213
|
+
},
|
|
214
|
+
spaceName: {
|
|
215
|
+
type: "string",
|
|
216
|
+
description: "Name of the space (alternative to spaceId)"
|
|
217
|
+
},
|
|
218
|
+
name: {
|
|
219
|
+
type: "string",
|
|
220
|
+
description: "Name of the list"
|
|
221
|
+
},
|
|
222
|
+
content: {
|
|
223
|
+
type: "string",
|
|
224
|
+
description: "List description"
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
required: ["name"]
|
|
344
228
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
229
|
+
},
|
|
230
|
+
move_task: {
|
|
231
|
+
description: "Move a task to a different list",
|
|
232
|
+
inputSchema: {
|
|
233
|
+
type: "object",
|
|
234
|
+
properties: {
|
|
235
|
+
taskId: {
|
|
236
|
+
type: "string",
|
|
237
|
+
description: "ID of the task to move"
|
|
238
|
+
},
|
|
239
|
+
listId: {
|
|
240
|
+
type: "string",
|
|
241
|
+
description: "ID of destination list (optional if listName is provided)"
|
|
242
|
+
},
|
|
243
|
+
listName: {
|
|
244
|
+
type: "string",
|
|
245
|
+
description: "Name of destination list (optional if listId is provided)"
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
required: ["taskId"]
|
|
348
249
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
250
|
+
},
|
|
251
|
+
duplicate_task: {
|
|
252
|
+
description: "Create a copy of a task in a specified list",
|
|
253
|
+
inputSchema: {
|
|
254
|
+
type: "object",
|
|
255
|
+
properties: {
|
|
256
|
+
taskId: {
|
|
257
|
+
type: "string",
|
|
258
|
+
description: "ID of the task to duplicate"
|
|
259
|
+
},
|
|
260
|
+
listId: {
|
|
261
|
+
type: "string",
|
|
262
|
+
description: "ID of destination list (optional if listName is provided)"
|
|
263
|
+
},
|
|
264
|
+
listName: {
|
|
265
|
+
type: "string",
|
|
266
|
+
description: "Name of destination list (optional if listId is provided)"
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
required: ["taskId"]
|
|
352
270
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
271
|
+
},
|
|
272
|
+
update_task: {
|
|
273
|
+
description: "Update an existing task",
|
|
274
|
+
inputSchema: {
|
|
275
|
+
type: "object",
|
|
276
|
+
properties: {
|
|
277
|
+
taskId: {
|
|
278
|
+
type: "string",
|
|
279
|
+
description: "ID of the task to update"
|
|
280
|
+
},
|
|
281
|
+
name: {
|
|
282
|
+
type: "string",
|
|
283
|
+
description: "New task name"
|
|
284
|
+
},
|
|
285
|
+
description: {
|
|
286
|
+
type: "string",
|
|
287
|
+
description: "New description"
|
|
288
|
+
},
|
|
289
|
+
status: {
|
|
290
|
+
type: "string",
|
|
291
|
+
description: "New status"
|
|
292
|
+
},
|
|
293
|
+
priority: {
|
|
294
|
+
type: "number",
|
|
295
|
+
description: "New priority level (1-4)"
|
|
296
|
+
},
|
|
297
|
+
dueDate: {
|
|
298
|
+
type: "string",
|
|
299
|
+
description: "New due date (ISO string)"
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
required: ["taskId"]
|
|
356
303
|
}
|
|
357
|
-
default:
|
|
358
|
-
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
359
304
|
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
* Initialize and start the server
|
|
368
|
-
* Connects to the transport and begins listening for requests
|
|
369
|
-
*/
|
|
370
|
-
try {
|
|
371
|
-
logInfo('mcp', { status: 'connecting' });
|
|
372
|
-
const transport = new StdioServerTransport();
|
|
373
|
-
await server.connect(transport);
|
|
374
|
-
logInfo('mcp', { status: 'connected' });
|
|
375
|
-
}
|
|
376
|
-
catch (error) {
|
|
377
|
-
logError('mcp.connection', error);
|
|
378
|
-
process.exit(1);
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* Handler for listing available ClickUp tasks as resources
|
|
382
|
-
* Returns a list of all tasks across all spaces with their metadata
|
|
383
|
-
*/
|
|
384
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
385
|
-
logDebug('resources', { action: 'listing' });
|
|
386
|
-
try {
|
|
387
|
-
const { tasks, spaces } = await getAllTasks(clickup, config.teamId);
|
|
388
|
-
return {
|
|
389
|
-
resources: tasks.map(task => ({
|
|
390
|
-
uri: `clickup://task/${task.id}`,
|
|
391
|
-
mimeType: "application/json",
|
|
392
|
-
name: task.name,
|
|
393
|
-
description: task.description || `Task in ${task.list.name} (${task.space.name})`,
|
|
394
|
-
tags: []
|
|
395
|
-
}))
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
catch (error) {
|
|
399
|
-
logError('resources.list', error);
|
|
400
|
-
throw error;
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
/**
|
|
404
|
-
* Handler for reading individual ClickUp task contents
|
|
405
|
-
* Returns detailed information about a specific task
|
|
406
|
-
*/
|
|
407
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
408
|
-
try {
|
|
409
|
-
const url = new URL(request.params.uri);
|
|
410
|
-
const taskId = url.pathname.replace(/^\/task\//, '');
|
|
411
|
-
logDebug('resources.read', { taskId });
|
|
412
|
-
const task = await clickup.getTask(taskId);
|
|
413
|
-
return {
|
|
414
|
-
contents: [{
|
|
415
|
-
uri: request.params.uri,
|
|
416
|
-
mimeType: "application/json",
|
|
417
|
-
text: JSON.stringify(task, null, 2),
|
|
418
|
-
tags: []
|
|
419
|
-
}]
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
catch (error) {
|
|
423
|
-
logError('resources.read', error);
|
|
424
|
-
throw error;
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
/**
|
|
428
|
-
* Handler for listing available tools
|
|
429
|
-
* Returns metadata about all registered tools
|
|
430
|
-
*/
|
|
431
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
432
|
-
logDebug('tools', { action: 'listing' });
|
|
433
|
-
const toolCapabilities = server.capabilities?.tools || {};
|
|
434
|
-
const tools = Object.entries(toolCapabilities).map(([name, tool]) => ({
|
|
435
|
-
name,
|
|
436
|
-
description: tool.description,
|
|
437
|
-
inputSchema: tool.inputSchema
|
|
438
|
-
}));
|
|
439
|
-
logDebug('tools', { count: tools.length });
|
|
440
|
-
return { tools };
|
|
441
|
-
});
|
|
442
|
-
/**
|
|
443
|
-
* Handler for listing available prompts
|
|
444
|
-
* Returns metadata about all registered prompts
|
|
445
|
-
*/
|
|
446
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
447
|
-
return {
|
|
448
|
-
prompts: [
|
|
449
|
-
{
|
|
450
|
-
name: "summarize_tasks",
|
|
451
|
-
description: "Summarize all ClickUp tasks"
|
|
452
|
-
},
|
|
453
|
-
{
|
|
454
|
-
name: "analyze_task_priorities",
|
|
455
|
-
description: "Analyze task priorities"
|
|
456
|
-
}
|
|
457
|
-
]
|
|
458
|
-
};
|
|
459
|
-
});
|
|
460
|
-
/**
|
|
461
|
-
* Handler for executing specific prompts
|
|
462
|
-
* Maps prompt names to their corresponding handler functions
|
|
463
|
-
*/
|
|
464
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
465
|
-
try {
|
|
466
|
-
switch (request.params.name) {
|
|
467
|
-
case "summarize_tasks": {
|
|
468
|
-
const output = await handleSummarizeTasks(clickup, config.teamId);
|
|
469
|
-
return {
|
|
470
|
-
content: [{
|
|
471
|
-
type: "text",
|
|
472
|
-
text: output
|
|
473
|
-
}]
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
case "analyze_task_priorities": {
|
|
477
|
-
const output = await handleAnalyzeTaskPriorities(clickup, config.teamId);
|
|
478
|
-
return {
|
|
479
|
-
content: [{
|
|
480
|
-
type: "text",
|
|
481
|
-
text: output
|
|
482
|
-
}]
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
default:
|
|
486
|
-
throw new Error("Prompt not found");
|
|
305
|
+
},
|
|
306
|
+
prompts: {
|
|
307
|
+
summarize_tasks: {
|
|
308
|
+
description: "Summarize all ClickUp tasks"
|
|
309
|
+
},
|
|
310
|
+
analyze_task_priorities: {
|
|
311
|
+
description: "Analyze task priorities"
|
|
487
312
|
}
|
|
313
|
+
},
|
|
314
|
+
resources: {
|
|
315
|
+
list: true,
|
|
316
|
+
read: true
|
|
488
317
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
318
|
+
};
|
|
319
|
+
// Create server instance with capabilities
|
|
320
|
+
const server = new Server({
|
|
321
|
+
name: "clickup-mcp-server",
|
|
322
|
+
version: "0.4.19",
|
|
323
|
+
transport: new StdioServerTransport(),
|
|
324
|
+
capabilities: serverCapabilities,
|
|
325
|
+
errorHandler: (error) => {
|
|
326
|
+
logError('mcp', error);
|
|
492
327
|
}
|
|
493
328
|
});
|
|
494
329
|
// Server startup logic
|
|
495
330
|
if (process.argv.includes('--stdio')) {
|
|
496
331
|
logInfo('server', { status: 'stdio.starting' });
|
|
497
|
-
// Set up stdio transport
|
|
332
|
+
// Set up stdio transport and connect first
|
|
498
333
|
const transport = new StdioServerTransport();
|
|
499
334
|
// Connect server with better error handling
|
|
500
335
|
server.connect(transport)
|
|
501
336
|
.then(() => {
|
|
502
337
|
logInfo('server', { status: 'connected' });
|
|
338
|
+
// Register handlers AFTER connection
|
|
339
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
340
|
+
try {
|
|
341
|
+
logDebug('tool.request', { name: request.params.name });
|
|
342
|
+
switch (request.params.name) {
|
|
343
|
+
case "workspace_hierarchy": {
|
|
344
|
+
return await handleWorkspaceHierarchy(clickup, config.teamId);
|
|
345
|
+
}
|
|
346
|
+
case "create_task": {
|
|
347
|
+
const args = request.params.arguments;
|
|
348
|
+
return await handleCreateTask(clickup, config.teamId, args);
|
|
349
|
+
}
|
|
350
|
+
case "create_bulk_tasks": {
|
|
351
|
+
const args = request.params.arguments;
|
|
352
|
+
return await handleCreateBulkTasks(clickup, config.teamId, args);
|
|
353
|
+
}
|
|
354
|
+
case "create_list": {
|
|
355
|
+
const args = request.params.arguments;
|
|
356
|
+
return await handleCreateList(clickup, config.teamId, args);
|
|
357
|
+
}
|
|
358
|
+
case "create_folder": {
|
|
359
|
+
const args = request.params.arguments;
|
|
360
|
+
return await handleCreateFolder(clickup, config.teamId, args);
|
|
361
|
+
}
|
|
362
|
+
case "create_list_in_folder": {
|
|
363
|
+
const args = request.params.arguments;
|
|
364
|
+
return await handleCreateListInFolder(clickup, config.teamId, args);
|
|
365
|
+
}
|
|
366
|
+
case "move_task": {
|
|
367
|
+
const args = request.params.arguments;
|
|
368
|
+
return await handleMoveTask(clickup, config.teamId, args);
|
|
369
|
+
}
|
|
370
|
+
case "duplicate_task": {
|
|
371
|
+
const args = request.params.arguments;
|
|
372
|
+
return await handleDuplicateTask(clickup, config.teamId, args);
|
|
373
|
+
}
|
|
374
|
+
case "update_task": {
|
|
375
|
+
const args = request.params.arguments;
|
|
376
|
+
return await handleUpdateTask(clickup, config.teamId, args);
|
|
377
|
+
}
|
|
378
|
+
default:
|
|
379
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
logError(`tool.${request.params.name}`, error);
|
|
384
|
+
throw error;
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
388
|
+
logDebug('resources', { action: 'listing' });
|
|
389
|
+
try {
|
|
390
|
+
const { tasks, spaces } = await getAllTasks(clickup, config.teamId);
|
|
391
|
+
return {
|
|
392
|
+
resources: tasks.map(task => ({
|
|
393
|
+
uri: `clickup://task/${task.id}`,
|
|
394
|
+
mimeType: "application/json",
|
|
395
|
+
name: task.name,
|
|
396
|
+
description: task.description || `Task in ${task.list.name} (${task.space.name})`,
|
|
397
|
+
tags: []
|
|
398
|
+
}))
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
logError('resources.list', error);
|
|
403
|
+
throw error;
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
407
|
+
try {
|
|
408
|
+
const url = new URL(request.params.uri);
|
|
409
|
+
const taskId = url.pathname.replace(/^\/task\//, '');
|
|
410
|
+
logDebug('resources.read', { taskId });
|
|
411
|
+
const task = await clickup.getTask(taskId);
|
|
412
|
+
return {
|
|
413
|
+
contents: [{
|
|
414
|
+
uri: request.params.uri,
|
|
415
|
+
mimeType: "application/json",
|
|
416
|
+
text: JSON.stringify(task, null, 2),
|
|
417
|
+
tags: []
|
|
418
|
+
}]
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
logError('resources.read', error);
|
|
423
|
+
throw error;
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
427
|
+
logDebug('tools', { action: 'listing' });
|
|
428
|
+
const toolCapabilities = server.capabilities?.tools || {};
|
|
429
|
+
const tools = Object.entries(toolCapabilities).map(([name, tool]) => ({
|
|
430
|
+
name,
|
|
431
|
+
description: tool.description,
|
|
432
|
+
inputSchema: tool.inputSchema
|
|
433
|
+
}));
|
|
434
|
+
logDebug('tools', { count: tools.length });
|
|
435
|
+
return { tools };
|
|
436
|
+
});
|
|
437
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
438
|
+
return {
|
|
439
|
+
prompts: [
|
|
440
|
+
{
|
|
441
|
+
name: "summarize_tasks",
|
|
442
|
+
description: "Summarize all ClickUp tasks"
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
name: "analyze_task_priorities",
|
|
446
|
+
description: "Analyze task priorities"
|
|
447
|
+
}
|
|
448
|
+
]
|
|
449
|
+
};
|
|
450
|
+
});
|
|
451
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
452
|
+
try {
|
|
453
|
+
switch (request.params.name) {
|
|
454
|
+
case "summarize_tasks": {
|
|
455
|
+
const output = await handleSummarizeTasks(clickup, config.teamId);
|
|
456
|
+
return {
|
|
457
|
+
content: [{
|
|
458
|
+
type: "text",
|
|
459
|
+
text: output
|
|
460
|
+
}]
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
case "analyze_task_priorities": {
|
|
464
|
+
const output = await handleAnalyzeTaskPriorities(clickup, config.teamId);
|
|
465
|
+
return {
|
|
466
|
+
content: [{
|
|
467
|
+
type: "text",
|
|
468
|
+
text: output
|
|
469
|
+
}]
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
default:
|
|
473
|
+
throw new Error("Prompt not found");
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
logError('prompt', error);
|
|
478
|
+
throw error;
|
|
479
|
+
}
|
|
480
|
+
});
|
|
503
481
|
// Send initial handshake message with more details
|
|
504
482
|
const capabilities = {
|
|
505
483
|
tools: server.capabilities?.tools || {},
|
|
@@ -513,7 +491,7 @@ if (process.argv.includes('--stdio')) {
|
|
|
513
491
|
logInfo('mcp', {
|
|
514
492
|
status: 'handshake',
|
|
515
493
|
name: "clickup-mcp-server",
|
|
516
|
-
version: "0.4.
|
|
494
|
+
version: "0.4.19",
|
|
517
495
|
hasTools: Object.keys(capabilities.tools).length > 0,
|
|
518
496
|
hasPrompts: Object.keys(capabilities.prompts).length > 0
|
|
519
497
|
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taazkareem/clickup-mcp-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.20",
|
|
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",
|
|
7
7
|
"bin": {
|
|
8
|
-
"clickup-mcp-server": "build/index.js"
|
|
9
|
-
"@taazkareem/clickup-mcp-server": "build/index.js"
|
|
8
|
+
"clickup-mcp-server": "build/index.js"
|
|
10
9
|
},
|
|
11
10
|
"files": [
|
|
12
11
|
"build",
|