@taazkareem/clickup-mcp-server 0.4.19 → 0.4.21
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 +164 -185
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -319,202 +319,181 @@ const serverCapabilities = {
|
|
|
319
319
|
// Create server instance with capabilities
|
|
320
320
|
const server = new Server({
|
|
321
321
|
name: "clickup-mcp-server",
|
|
322
|
-
version: "0.4.
|
|
322
|
+
version: "0.4.20",
|
|
323
323
|
transport: new StdioServerTransport(),
|
|
324
|
-
capabilities:
|
|
324
|
+
capabilities: {
|
|
325
|
+
tools: {
|
|
326
|
+
enabled: true,
|
|
327
|
+
tools: serverCapabilities.tools
|
|
328
|
+
},
|
|
329
|
+
prompts: serverCapabilities.prompts,
|
|
330
|
+
resources: serverCapabilities.resources
|
|
331
|
+
},
|
|
325
332
|
errorHandler: (error) => {
|
|
326
333
|
logError('mcp', error);
|
|
327
334
|
}
|
|
328
335
|
});
|
|
329
|
-
/**
|
|
330
|
-
* Register handlers for MCP tool requests
|
|
331
|
-
* Each tool is mapped to its corresponding handler function
|
|
332
|
-
*/
|
|
333
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
334
|
-
try {
|
|
335
|
-
logDebug('tool.request', { name: request.params.name });
|
|
336
|
-
switch (request.params.name) {
|
|
337
|
-
case "workspace_hierarchy": {
|
|
338
|
-
return await handleWorkspaceHierarchy(clickup, config.teamId);
|
|
339
|
-
}
|
|
340
|
-
case "create_task": {
|
|
341
|
-
const args = request.params.arguments;
|
|
342
|
-
return await handleCreateTask(clickup, config.teamId, args);
|
|
343
|
-
}
|
|
344
|
-
case "create_bulk_tasks": {
|
|
345
|
-
const args = request.params.arguments;
|
|
346
|
-
return await handleCreateBulkTasks(clickup, config.teamId, args);
|
|
347
|
-
}
|
|
348
|
-
case "create_list": {
|
|
349
|
-
const args = request.params.arguments;
|
|
350
|
-
return await handleCreateList(clickup, config.teamId, args);
|
|
351
|
-
}
|
|
352
|
-
case "create_folder": {
|
|
353
|
-
const args = request.params.arguments;
|
|
354
|
-
return await handleCreateFolder(clickup, config.teamId, args);
|
|
355
|
-
}
|
|
356
|
-
case "create_list_in_folder": {
|
|
357
|
-
const args = request.params.arguments;
|
|
358
|
-
return await handleCreateListInFolder(clickup, config.teamId, args);
|
|
359
|
-
}
|
|
360
|
-
case "move_task": {
|
|
361
|
-
const args = request.params.arguments;
|
|
362
|
-
return await handleMoveTask(clickup, config.teamId, args);
|
|
363
|
-
}
|
|
364
|
-
case "duplicate_task": {
|
|
365
|
-
const args = request.params.arguments;
|
|
366
|
-
return await handleDuplicateTask(clickup, config.teamId, args);
|
|
367
|
-
}
|
|
368
|
-
case "update_task": {
|
|
369
|
-
const args = request.params.arguments;
|
|
370
|
-
return await handleUpdateTask(clickup, config.teamId, args);
|
|
371
|
-
}
|
|
372
|
-
default:
|
|
373
|
-
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
catch (error) {
|
|
377
|
-
logError(`tool.${request.params.name}`, error);
|
|
378
|
-
throw error;
|
|
379
|
-
}
|
|
380
|
-
});
|
|
381
|
-
/**
|
|
382
|
-
* Initialize and start the server
|
|
383
|
-
* Connects to the transport and begins listening for requests
|
|
384
|
-
*/
|
|
385
|
-
try {
|
|
386
|
-
logInfo('mcp', { status: 'connecting' });
|
|
387
|
-
const transport = new StdioServerTransport();
|
|
388
|
-
await server.connect(transport);
|
|
389
|
-
logInfo('mcp', { status: 'connected' });
|
|
390
|
-
}
|
|
391
|
-
catch (error) {
|
|
392
|
-
logError('mcp.connection', error);
|
|
393
|
-
process.exit(1);
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Handler for listing available ClickUp tasks as resources
|
|
397
|
-
* Returns a list of all tasks across all spaces with their metadata
|
|
398
|
-
*/
|
|
399
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
400
|
-
logDebug('resources', { action: 'listing' });
|
|
401
|
-
try {
|
|
402
|
-
const { tasks, spaces } = await getAllTasks(clickup, config.teamId);
|
|
403
|
-
return {
|
|
404
|
-
resources: tasks.map(task => ({
|
|
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
|
-
/**
|
|
419
|
-
* Handler for reading individual ClickUp task contents
|
|
420
|
-
* Returns detailed information about a specific task
|
|
421
|
-
*/
|
|
422
|
-
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
423
|
-
try {
|
|
424
|
-
const url = new URL(request.params.uri);
|
|
425
|
-
const taskId = url.pathname.replace(/^\/task\//, '');
|
|
426
|
-
logDebug('resources.read', { taskId });
|
|
427
|
-
const task = await clickup.getTask(taskId);
|
|
428
|
-
return {
|
|
429
|
-
contents: [{
|
|
430
|
-
uri: request.params.uri,
|
|
431
|
-
mimeType: "application/json",
|
|
432
|
-
text: JSON.stringify(task, null, 2),
|
|
433
|
-
tags: []
|
|
434
|
-
}]
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
catch (error) {
|
|
438
|
-
logError('resources.read', error);
|
|
439
|
-
throw error;
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
/**
|
|
443
|
-
* Handler for listing available tools
|
|
444
|
-
* Returns metadata about all registered tools
|
|
445
|
-
*/
|
|
446
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
447
|
-
logDebug('tools', { action: 'listing' });
|
|
448
|
-
const toolCapabilities = server.capabilities?.tools || {};
|
|
449
|
-
const tools = Object.entries(toolCapabilities).map(([name, tool]) => ({
|
|
450
|
-
name,
|
|
451
|
-
description: tool.description,
|
|
452
|
-
inputSchema: tool.inputSchema
|
|
453
|
-
}));
|
|
454
|
-
logDebug('tools', { count: tools.length });
|
|
455
|
-
return { tools };
|
|
456
|
-
});
|
|
457
|
-
/**
|
|
458
|
-
* Handler for listing available prompts
|
|
459
|
-
* Returns metadata about all registered prompts
|
|
460
|
-
*/
|
|
461
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
462
|
-
return {
|
|
463
|
-
prompts: [
|
|
464
|
-
{
|
|
465
|
-
name: "summarize_tasks",
|
|
466
|
-
description: "Summarize all ClickUp tasks"
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
name: "analyze_task_priorities",
|
|
470
|
-
description: "Analyze task priorities"
|
|
471
|
-
}
|
|
472
|
-
]
|
|
473
|
-
};
|
|
474
|
-
});
|
|
475
|
-
/**
|
|
476
|
-
* Handler for executing specific prompts
|
|
477
|
-
* Maps prompt names to their corresponding handler functions
|
|
478
|
-
*/
|
|
479
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
480
|
-
try {
|
|
481
|
-
switch (request.params.name) {
|
|
482
|
-
case "summarize_tasks": {
|
|
483
|
-
const output = await handleSummarizeTasks(clickup, config.teamId);
|
|
484
|
-
return {
|
|
485
|
-
content: [{
|
|
486
|
-
type: "text",
|
|
487
|
-
text: output
|
|
488
|
-
}]
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
case "analyze_task_priorities": {
|
|
492
|
-
const output = await handleAnalyzeTaskPriorities(clickup, config.teamId);
|
|
493
|
-
return {
|
|
494
|
-
content: [{
|
|
495
|
-
type: "text",
|
|
496
|
-
text: output
|
|
497
|
-
}]
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
default:
|
|
501
|
-
throw new Error("Prompt not found");
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
catch (error) {
|
|
505
|
-
logError('prompt', error);
|
|
506
|
-
throw error;
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
336
|
// Server startup logic
|
|
510
337
|
if (process.argv.includes('--stdio')) {
|
|
511
338
|
logInfo('server', { status: 'stdio.starting' });
|
|
512
|
-
// Set up stdio transport
|
|
339
|
+
// Set up stdio transport and connect first
|
|
513
340
|
const transport = new StdioServerTransport();
|
|
514
341
|
// Connect server with better error handling
|
|
515
342
|
server.connect(transport)
|
|
516
|
-
.then(() => {
|
|
343
|
+
.then(async () => {
|
|
517
344
|
logInfo('server', { status: 'connected' });
|
|
345
|
+
// Wait for capabilities to be registered
|
|
346
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
347
|
+
// Register handlers AFTER connection and capability registration
|
|
348
|
+
try {
|
|
349
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
350
|
+
try {
|
|
351
|
+
logDebug('tool.request', { name: request.params.name });
|
|
352
|
+
switch (request.params.name) {
|
|
353
|
+
case "workspace_hierarchy": {
|
|
354
|
+
return await handleWorkspaceHierarchy(clickup, config.teamId);
|
|
355
|
+
}
|
|
356
|
+
case "create_task": {
|
|
357
|
+
const args = request.params.arguments;
|
|
358
|
+
return await handleCreateTask(clickup, config.teamId, args);
|
|
359
|
+
}
|
|
360
|
+
case "create_bulk_tasks": {
|
|
361
|
+
const args = request.params.arguments;
|
|
362
|
+
return await handleCreateBulkTasks(clickup, config.teamId, args);
|
|
363
|
+
}
|
|
364
|
+
case "create_list": {
|
|
365
|
+
const args = request.params.arguments;
|
|
366
|
+
return await handleCreateList(clickup, config.teamId, args);
|
|
367
|
+
}
|
|
368
|
+
case "create_folder": {
|
|
369
|
+
const args = request.params.arguments;
|
|
370
|
+
return await handleCreateFolder(clickup, config.teamId, args);
|
|
371
|
+
}
|
|
372
|
+
case "create_list_in_folder": {
|
|
373
|
+
const args = request.params.arguments;
|
|
374
|
+
return await handleCreateListInFolder(clickup, config.teamId, args);
|
|
375
|
+
}
|
|
376
|
+
case "move_task": {
|
|
377
|
+
const args = request.params.arguments;
|
|
378
|
+
return await handleMoveTask(clickup, config.teamId, args);
|
|
379
|
+
}
|
|
380
|
+
case "duplicate_task": {
|
|
381
|
+
const args = request.params.arguments;
|
|
382
|
+
return await handleDuplicateTask(clickup, config.teamId, args);
|
|
383
|
+
}
|
|
384
|
+
case "update_task": {
|
|
385
|
+
const args = request.params.arguments;
|
|
386
|
+
return await handleUpdateTask(clickup, config.teamId, args);
|
|
387
|
+
}
|
|
388
|
+
default:
|
|
389
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch (error) {
|
|
393
|
+
logError(`tool.${request.params.name}`, error);
|
|
394
|
+
throw error;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
398
|
+
logDebug('resources', { action: 'listing' });
|
|
399
|
+
try {
|
|
400
|
+
const { tasks, spaces } = await getAllTasks(clickup, config.teamId);
|
|
401
|
+
return {
|
|
402
|
+
resources: tasks.map(task => ({
|
|
403
|
+
uri: `clickup://task/${task.id}`,
|
|
404
|
+
mimeType: "application/json",
|
|
405
|
+
name: task.name,
|
|
406
|
+
description: task.description || `Task in ${task.list.name} (${task.space.name})`,
|
|
407
|
+
tags: []
|
|
408
|
+
}))
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
logError('resources.list', error);
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
417
|
+
try {
|
|
418
|
+
const url = new URL(request.params.uri);
|
|
419
|
+
const taskId = url.pathname.replace(/^\/task\//, '');
|
|
420
|
+
logDebug('resources.read', { taskId });
|
|
421
|
+
const task = await clickup.getTask(taskId);
|
|
422
|
+
return {
|
|
423
|
+
contents: [{
|
|
424
|
+
uri: request.params.uri,
|
|
425
|
+
mimeType: "application/json",
|
|
426
|
+
text: JSON.stringify(task, null, 2),
|
|
427
|
+
tags: []
|
|
428
|
+
}]
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
logError('resources.read', error);
|
|
433
|
+
throw error;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
437
|
+
logDebug('tools', { action: 'listing' });
|
|
438
|
+
const toolCapabilities = server.capabilities?.tools || {};
|
|
439
|
+
const tools = Object.entries(toolCapabilities).map(([name, tool]) => ({
|
|
440
|
+
name,
|
|
441
|
+
description: tool.description,
|
|
442
|
+
inputSchema: tool.inputSchema
|
|
443
|
+
}));
|
|
444
|
+
logDebug('tools', { count: tools.length });
|
|
445
|
+
return { tools };
|
|
446
|
+
});
|
|
447
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
448
|
+
return {
|
|
449
|
+
prompts: [
|
|
450
|
+
{
|
|
451
|
+
name: "summarize_tasks",
|
|
452
|
+
description: "Summarize all ClickUp tasks"
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: "analyze_task_priorities",
|
|
456
|
+
description: "Analyze task priorities"
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
};
|
|
460
|
+
});
|
|
461
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
462
|
+
try {
|
|
463
|
+
switch (request.params.name) {
|
|
464
|
+
case "summarize_tasks": {
|
|
465
|
+
const output = await handleSummarizeTasks(clickup, config.teamId);
|
|
466
|
+
return {
|
|
467
|
+
content: [{
|
|
468
|
+
type: "text",
|
|
469
|
+
text: output
|
|
470
|
+
}]
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
case "analyze_task_priorities": {
|
|
474
|
+
const output = await handleAnalyzeTaskPriorities(clickup, config.teamId);
|
|
475
|
+
return {
|
|
476
|
+
content: [{
|
|
477
|
+
type: "text",
|
|
478
|
+
text: output
|
|
479
|
+
}]
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
default:
|
|
483
|
+
throw new Error("Prompt not found");
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
logError('prompt', error);
|
|
488
|
+
throw error;
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
logInfo('server', { status: 'handlers.registered' });
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
logError('server.handlers', error);
|
|
495
|
+
process.exit(1);
|
|
496
|
+
}
|
|
518
497
|
// Send initial handshake message with more details
|
|
519
498
|
const capabilities = {
|
|
520
499
|
tools: server.capabilities?.tools || {},
|
|
@@ -528,7 +507,7 @@ if (process.argv.includes('--stdio')) {
|
|
|
528
507
|
logInfo('mcp', {
|
|
529
508
|
status: 'handshake',
|
|
530
509
|
name: "clickup-mcp-server",
|
|
531
|
-
version: "0.4.
|
|
510
|
+
version: "0.4.19",
|
|
532
511
|
hasTools: Object.keys(capabilities.tools).length > 0,
|
|
533
512
|
hasPrompts: Object.keys(capabilities.prompts).length > 0
|
|
534
513
|
});
|
package/package.json
CHANGED