@taazkareem/clickup-mcp-server 0.4.25 → 0.4.27
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 +157 -476
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -7,15 +7,14 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module clickup-mcp-server
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
11
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
-
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
13
12
|
import { ClickUpService } from "./services/clickup.js";
|
|
14
13
|
import config from "./config.js";
|
|
15
|
-
import { handleWorkspaceHierarchy, handleCreateTask, handleCreateBulkTasks, handleCreateList, handleCreateFolder, handleCreateListInFolder
|
|
14
|
+
import { handleWorkspaceHierarchy, handleCreateTask, handleCreateBulkTasks, handleCreateList, handleCreateFolder, handleCreateListInFolder } from "./handlers/tools.js";
|
|
16
15
|
import { handleSummarizeTasks, handleAnalyzeTaskPriorities } from "./handlers/prompts.js";
|
|
17
|
-
import { getAllTasks } from "./utils/resolvers.js";
|
|
18
16
|
import { logError, logInfo, logDebug } from "./utils/logger.js";
|
|
17
|
+
import { z } from 'zod';
|
|
19
18
|
// Set up global error handlers
|
|
20
19
|
process.on('uncaughtException', (error) => {
|
|
21
20
|
logError('server.uncaught', error);
|
|
@@ -30,10 +29,7 @@ logInfo('config', {
|
|
|
30
29
|
clickupApiKey: config.clickupApiKey ? '***' : 'missing',
|
|
31
30
|
teamId: config.teamId || 'missing'
|
|
32
31
|
});
|
|
33
|
-
|
|
34
|
-
* Initialize ClickUp service singleton
|
|
35
|
-
* This must be done before any other ClickUp operations
|
|
36
|
-
*/
|
|
32
|
+
// Initialize ClickUp service singleton
|
|
37
33
|
let clickup;
|
|
38
34
|
try {
|
|
39
35
|
logDebug('clickup', { status: 'initializing' });
|
|
@@ -44,481 +40,169 @@ catch (error) {
|
|
|
44
40
|
logError('clickup.initialization', error);
|
|
45
41
|
process.exit(1);
|
|
46
42
|
}
|
|
47
|
-
|
|
48
|
-
* Create and configure the MCP server instance
|
|
49
|
-
* Sets up capabilities, tools, and error handling
|
|
50
|
-
*/
|
|
43
|
+
// Create and configure the MCP server instance
|
|
51
44
|
logDebug('mcp', { status: 'creating' });
|
|
52
|
-
|
|
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)"
|
|
71
|
-
},
|
|
72
|
-
listName: {
|
|
73
|
-
type: "string",
|
|
74
|
-
description: "Name of the list to create the task in (optional if listId is provided)"
|
|
75
|
-
},
|
|
76
|
-
name: {
|
|
77
|
-
type: "string",
|
|
78
|
-
description: "Name of the task"
|
|
79
|
-
},
|
|
80
|
-
description: {
|
|
81
|
-
type: "string",
|
|
82
|
-
description: "Description of the task"
|
|
83
|
-
},
|
|
84
|
-
status: {
|
|
85
|
-
type: "string",
|
|
86
|
-
description: "Status of the task"
|
|
87
|
-
},
|
|
88
|
-
priority: {
|
|
89
|
-
type: "number",
|
|
90
|
-
description: "Priority of the task (1-4)"
|
|
91
|
-
},
|
|
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)"
|
|
108
|
-
},
|
|
109
|
-
listName: {
|
|
110
|
-
type: "string",
|
|
111
|
-
description: "Name of the list to create tasks in (optional if listId is provided)"
|
|
112
|
-
},
|
|
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"]
|
|
145
|
-
}
|
|
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"]
|
|
170
|
-
}
|
|
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"]
|
|
195
|
-
}
|
|
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"]
|
|
228
|
-
}
|
|
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"]
|
|
249
|
-
}
|
|
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"]
|
|
270
|
-
}
|
|
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"]
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
},
|
|
306
|
-
prompts: {
|
|
307
|
-
summarize_tasks: {
|
|
308
|
-
description: "Summarize all ClickUp tasks"
|
|
309
|
-
},
|
|
310
|
-
analyze_task_priorities: {
|
|
311
|
-
description: "Analyze task priorities"
|
|
312
|
-
}
|
|
313
|
-
},
|
|
314
|
-
resources: {
|
|
315
|
-
list: true,
|
|
316
|
-
read: true
|
|
317
|
-
}
|
|
318
|
-
};
|
|
319
|
-
// Create server instance with capabilities
|
|
320
|
-
const server = new Server({
|
|
45
|
+
const mcpServer = new McpServer({
|
|
321
46
|
name: "clickup-mcp-server",
|
|
322
|
-
version: "0.4.
|
|
47
|
+
version: "0.4.25",
|
|
323
48
|
capabilities: {
|
|
324
|
-
tools:
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
list: true,
|
|
328
|
-
schemas: serverCapabilities.tools
|
|
329
|
-
},
|
|
330
|
-
prompts: {
|
|
331
|
-
enabled: true,
|
|
332
|
-
list: true,
|
|
333
|
-
get: true,
|
|
334
|
-
schemas: serverCapabilities.prompts
|
|
335
|
-
},
|
|
336
|
-
resources: {
|
|
337
|
-
enabled: true,
|
|
338
|
-
list: true,
|
|
339
|
-
read: true
|
|
340
|
-
}
|
|
341
|
-
},
|
|
342
|
-
errorHandler: (error) => {
|
|
343
|
-
logError('mcp', error);
|
|
49
|
+
tools: true,
|
|
50
|
+
prompts: true,
|
|
51
|
+
resources: true
|
|
344
52
|
}
|
|
345
53
|
});
|
|
346
|
-
//
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
54
|
+
// Tool schemas as raw shapes
|
|
55
|
+
const workspaceHierarchySchema = {
|
|
56
|
+
teamId: z.string().optional()
|
|
57
|
+
};
|
|
58
|
+
const taskSchema = {
|
|
59
|
+
name: z.string(),
|
|
60
|
+
description: z.string().optional(),
|
|
61
|
+
status: z.string().optional(),
|
|
62
|
+
priority: z.number().optional(),
|
|
63
|
+
dueDate: z.string().optional(),
|
|
64
|
+
listId: z.string().optional(),
|
|
65
|
+
listName: z.string().optional()
|
|
66
|
+
};
|
|
67
|
+
const bulkTasksSchema = {
|
|
68
|
+
tasks: z.array(z.object(taskSchema)),
|
|
69
|
+
listId: z.string().optional(),
|
|
70
|
+
listName: z.string().optional()
|
|
71
|
+
};
|
|
72
|
+
const listSchema = {
|
|
73
|
+
name: z.string(),
|
|
74
|
+
spaceId: z.string().optional(),
|
|
75
|
+
spaceName: z.string().optional(),
|
|
76
|
+
content: z.string().optional()
|
|
77
|
+
};
|
|
78
|
+
const folderSchema = {
|
|
79
|
+
name: z.string(),
|
|
80
|
+
spaceId: z.string().optional(),
|
|
81
|
+
spaceName: z.string().optional(),
|
|
82
|
+
override_statuses: z.boolean().optional()
|
|
83
|
+
};
|
|
84
|
+
const listInFolderSchema = {
|
|
85
|
+
name: z.string(),
|
|
86
|
+
folderId: z.string().optional(),
|
|
87
|
+
folderName: z.string().optional(),
|
|
88
|
+
spaceId: z.string().optional(),
|
|
89
|
+
spaceName: z.string().optional(),
|
|
90
|
+
content: z.string().optional()
|
|
91
|
+
};
|
|
92
|
+
// Register tools with proper schemas
|
|
93
|
+
mcpServer.tool('workspace_hierarchy', 'List complete hierarchy of the ClickUp workspace', workspaceHierarchySchema, async (args) => {
|
|
94
|
+
const result = await handleWorkspaceHierarchy(clickup, config.teamId);
|
|
95
|
+
return {
|
|
96
|
+
content: [{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: JSON.stringify(result, null, 2)
|
|
99
|
+
}]
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
mcpServer.tool('create_task', 'Create a new task in ClickUp', taskSchema, async (args) => {
|
|
103
|
+
const result = await handleCreateTask(clickup, config.teamId, args);
|
|
104
|
+
return {
|
|
105
|
+
content: [{
|
|
106
|
+
type: "text",
|
|
107
|
+
text: JSON.stringify(result, null, 2)
|
|
108
|
+
}]
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
mcpServer.tool('create_bulk_tasks', 'Create multiple tasks simultaneously in a list', bulkTasksSchema, async (args) => {
|
|
112
|
+
const result = await handleCreateBulkTasks(clickup, config.teamId, args);
|
|
113
|
+
return {
|
|
114
|
+
content: [{
|
|
115
|
+
type: "text",
|
|
116
|
+
text: JSON.stringify(result, null, 2)
|
|
117
|
+
}]
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
mcpServer.tool('create_list', 'Create a new list in a space', listSchema, async (args) => {
|
|
121
|
+
const result = await handleCreateList(clickup, config.teamId, args);
|
|
122
|
+
return {
|
|
123
|
+
content: [{
|
|
124
|
+
type: "text",
|
|
125
|
+
text: JSON.stringify(result, null, 2)
|
|
126
|
+
}]
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
mcpServer.tool('create_folder', 'Create a new folder in a space', folderSchema, async (args) => {
|
|
130
|
+
const result = await handleCreateFolder(clickup, config.teamId, args);
|
|
131
|
+
return {
|
|
132
|
+
content: [{
|
|
133
|
+
type: "text",
|
|
134
|
+
text: JSON.stringify(result, null, 2)
|
|
135
|
+
}]
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
mcpServer.tool('create_list_in_folder', 'Create a new list within a folder', listInFolderSchema, async (args) => {
|
|
139
|
+
const result = await handleCreateListInFolder(clickup, config.teamId, args);
|
|
140
|
+
return {
|
|
141
|
+
content: [{
|
|
142
|
+
type: "text",
|
|
143
|
+
text: JSON.stringify(result, null, 2)
|
|
144
|
+
}]
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
// Register prompts with descriptions
|
|
148
|
+
mcpServer.prompt('summarize_tasks', 'Provide a comprehensive summary of tasks', async () => {
|
|
149
|
+
const summary = await handleSummarizeTasks(clickup, config.teamId);
|
|
150
|
+
return {
|
|
151
|
+
messages: [{
|
|
152
|
+
role: 'assistant',
|
|
153
|
+
content: {
|
|
154
|
+
type: 'text',
|
|
155
|
+
text: summary
|
|
392
156
|
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
uri: `clickup://task/${task.id}`,
|
|
406
|
-
mimeType: "application/json",
|
|
407
|
-
name: task.name,
|
|
408
|
-
description: task.description || `Task in ${task.list.name} (${task.space.name})`,
|
|
409
|
-
tags: []
|
|
410
|
-
}))
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
catch (error) {
|
|
414
|
-
logError('resources.list', error);
|
|
415
|
-
throw error;
|
|
416
|
-
}
|
|
417
|
-
});
|
|
418
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
419
|
-
try {
|
|
420
|
-
const url = new URL(request.params.uri);
|
|
421
|
-
const taskId = url.pathname.replace(/^\/task\//, '');
|
|
422
|
-
logDebug('resources.read', { taskId });
|
|
423
|
-
const task = await clickup.getTask(taskId);
|
|
424
|
-
return {
|
|
425
|
-
contents: [{
|
|
426
|
-
uri: request.params.uri,
|
|
427
|
-
mimeType: "application/json",
|
|
428
|
-
text: JSON.stringify(task, null, 2),
|
|
429
|
-
tags: []
|
|
430
|
-
}]
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
catch (error) {
|
|
434
|
-
logError('resources.read', error);
|
|
435
|
-
throw error;
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
439
|
-
logDebug('tools', { action: 'listing' });
|
|
440
|
-
const toolCapabilities = server.capabilities?.tools || {};
|
|
441
|
-
const tools = Object.entries(toolCapabilities).map(([name, tool]) => ({
|
|
442
|
-
name,
|
|
443
|
-
description: tool.description,
|
|
444
|
-
inputSchema: tool.inputSchema
|
|
445
|
-
}));
|
|
446
|
-
logDebug('tools', { count: tools.length });
|
|
447
|
-
return { tools };
|
|
448
|
-
});
|
|
449
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
450
|
-
return {
|
|
451
|
-
prompts: [
|
|
452
|
-
{
|
|
453
|
-
name: "summarize_tasks",
|
|
454
|
-
description: "Summarize all ClickUp tasks"
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
name: "analyze_task_priorities",
|
|
458
|
-
description: "Analyze task priorities"
|
|
459
|
-
}
|
|
460
|
-
]
|
|
461
|
-
};
|
|
462
|
-
});
|
|
463
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
464
|
-
try {
|
|
465
|
-
switch (request.params.name) {
|
|
466
|
-
case "summarize_tasks": {
|
|
467
|
-
const output = await handleSummarizeTasks(clickup, config.teamId);
|
|
468
|
-
return {
|
|
469
|
-
content: [{
|
|
470
|
-
type: "text",
|
|
471
|
-
text: output
|
|
472
|
-
}]
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
case "analyze_task_priorities": {
|
|
476
|
-
const output = await handleAnalyzeTaskPriorities(clickup, config.teamId);
|
|
477
|
-
return {
|
|
478
|
-
content: [{
|
|
479
|
-
type: "text",
|
|
480
|
-
text: output
|
|
481
|
-
}]
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
default:
|
|
485
|
-
throw new Error("Prompt not found");
|
|
157
|
+
}],
|
|
158
|
+
description: 'Task Summary'
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
mcpServer.prompt('analyze_task_priorities', 'Analyze task priorities and provide recommendations', async () => {
|
|
162
|
+
const analysis = await handleAnalyzeTaskPriorities(clickup, config.teamId);
|
|
163
|
+
return {
|
|
164
|
+
messages: [{
|
|
165
|
+
role: 'assistant',
|
|
166
|
+
content: {
|
|
167
|
+
type: 'text',
|
|
168
|
+
text: analysis
|
|
486
169
|
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
170
|
+
}],
|
|
171
|
+
description: 'Priority Analysis'
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
// TODO: Implement resource handler properly after consulting MCP SDK documentation
|
|
175
|
+
// Resource handler temporarily disabled due to type issues
|
|
176
|
+
/*
|
|
177
|
+
mcpServer.resource(
|
|
178
|
+
'clickup',
|
|
179
|
+
'clickup://task/{id}',
|
|
180
|
+
async (uri: URL) => {
|
|
181
|
+
try {
|
|
182
|
+
const taskId = uri.pathname.split('/').pop() || '';
|
|
183
|
+
const task = await clickup.getTask(taskId);
|
|
184
|
+
return {
|
|
185
|
+
uri: uri.toString(),
|
|
186
|
+
mimeType: "application/json",
|
|
187
|
+
text: JSON.stringify(task, null, 2),
|
|
188
|
+
tags: []
|
|
189
|
+
};
|
|
190
|
+
} catch (error) {
|
|
191
|
+
logError('resources.read', error);
|
|
192
|
+
throw error;
|
|
498
193
|
}
|
|
499
|
-
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
*/
|
|
197
|
+
// Server startup logic
|
|
198
|
+
if (process.argv.includes('--stdio')) {
|
|
199
|
+
logInfo('server', { status: 'stdio.starting' });
|
|
200
|
+
// Create stdio transport
|
|
500
201
|
const transport = new StdioServerTransport();
|
|
501
202
|
// Connect server with better error handling
|
|
502
|
-
server.connect(transport)
|
|
503
|
-
.then(
|
|
203
|
+
mcpServer.server.connect(transport)
|
|
204
|
+
.then(() => {
|
|
504
205
|
logInfo('server', { status: 'connected' });
|
|
505
|
-
// Send initial handshake message with more details
|
|
506
|
-
const capabilities = {
|
|
507
|
-
tools: server.capabilities?.tools || {},
|
|
508
|
-
prompts: server.capabilities?.prompts || {},
|
|
509
|
-
resources: {
|
|
510
|
-
list: true,
|
|
511
|
-
read: true
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
logInfo('mcp', { status: 'handshake.preparing' });
|
|
515
|
-
logInfo('mcp', {
|
|
516
|
-
status: 'handshake',
|
|
517
|
-
name: "clickup-mcp-server",
|
|
518
|
-
version: "0.4.19",
|
|
519
|
-
hasTools: Object.keys(capabilities.tools).length > 0,
|
|
520
|
-
hasPrompts: Object.keys(capabilities.prompts).length > 0
|
|
521
|
-
});
|
|
522
206
|
logInfo('server', { status: 'ready' });
|
|
523
207
|
// Keep the process alive
|
|
524
208
|
process.stdin.resume();
|
|
@@ -539,10 +223,7 @@ if (process.argv.includes('--stdio')) {
|
|
|
539
223
|
process.exit(1);
|
|
540
224
|
});
|
|
541
225
|
}
|
|
542
|
-
|
|
543
|
-
logInfo('server', { status: 'standard.starting' });
|
|
544
|
-
// Add your non-stdio server initialization here if needed
|
|
545
|
-
}
|
|
226
|
+
// Note: Non-stdio initialization removed as it was unused
|
|
546
227
|
// Prevent unhandled promise rejections from crashing the server
|
|
547
228
|
process.on('unhandledRejection', (error) => {
|
|
548
229
|
logError('server.unhandled', error);
|
package/package.json
CHANGED