@taazkareem/clickup-mcp-server 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -23
- package/build/config.js +34 -2
- package/build/index.js +3 -1
- package/build/logger.js +8 -38
- package/build/server.js +33 -8
- package/build/services/clickup/base.js +3 -0
- package/build/services/clickup/bulk.js +3 -0
- package/build/services/clickup/folder.js +3 -0
- package/build/services/clickup/index.js +9 -1
- package/build/services/clickup/list.js +3 -0
- package/build/services/clickup/tag.js +190 -0
- package/build/services/clickup/task.js +138 -0
- package/build/services/clickup/types.js +3 -0
- package/build/services/clickup/workspace.js +3 -0
- package/build/services/shared.js +3 -0
- package/build/tools/folder.js +3 -0
- package/build/tools/index.js +4 -0
- package/build/tools/list.js +3 -0
- package/build/tools/tag.js +824 -0
- package/build/tools/task/attachments.js +3 -0
- package/build/tools/task/bulk-operations.js +10 -0
- package/build/tools/task/handlers.js +61 -2
- package/build/tools/task/index.js +8 -1
- package/build/tools/task/main.js +18 -2
- package/build/tools/task/single-operations.js +10 -0
- package/build/tools/task/utilities.js +40 -3
- package/build/tools/task/workspace-operations.js +222 -0
- package/build/tools/utils.js +3 -0
- package/build/tools/workspace.js +3 -0
- package/build/utils/color-processor.js +183 -0
- package/build/utils/concurrency-utils.js +3 -0
- package/build/utils/date-utils.js +3 -0
- package/build/utils/resolver-utils.js +3 -0
- package/build/utils/sponsor-service.js +3 -0
- package/build/utils/token-utils.js +49 -0
- package/package.json +1 -1
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
2
5
|
* ClickUp Task Service
|
|
3
6
|
*
|
|
4
7
|
* Handles all operations related to tasks in ClickUp, including:
|
|
@@ -10,6 +13,7 @@
|
|
|
10
13
|
*/
|
|
11
14
|
import { BaseClickUpService, ErrorCode, ClickUpServiceError } from './base.js';
|
|
12
15
|
import { ListService } from './list.js';
|
|
16
|
+
import { estimateTokensFromObject, wouldExceedTokenLimit } from '../../utils/token-utils.js';
|
|
13
17
|
export class TaskService extends BaseClickUpService {
|
|
14
18
|
constructor(apiKey, teamId, baseUrl, workspaceService) {
|
|
15
19
|
super(apiKey, teamId, baseUrl);
|
|
@@ -59,6 +63,27 @@ export class TaskService extends BaseClickUpService {
|
|
|
59
63
|
if (filters.assignees && filters.assignees.length > 0) {
|
|
60
64
|
filters.assignees.forEach(assignee => params.append('assignees[]', assignee));
|
|
61
65
|
}
|
|
66
|
+
// Team tasks endpoint specific parameters
|
|
67
|
+
if (filters.tags && filters.tags.length > 0) {
|
|
68
|
+
filters.tags.forEach(tag => params.append('tags[]', tag));
|
|
69
|
+
}
|
|
70
|
+
if (filters.list_ids && filters.list_ids.length > 0) {
|
|
71
|
+
filters.list_ids.forEach(id => params.append('list_ids[]', id));
|
|
72
|
+
}
|
|
73
|
+
if (filters.folder_ids && filters.folder_ids.length > 0) {
|
|
74
|
+
filters.folder_ids.forEach(id => params.append('folder_ids[]', id));
|
|
75
|
+
}
|
|
76
|
+
if (filters.space_ids && filters.space_ids.length > 0) {
|
|
77
|
+
filters.space_ids.forEach(id => params.append('space_ids[]', id));
|
|
78
|
+
}
|
|
79
|
+
if (filters.archived !== undefined)
|
|
80
|
+
params.append('archived', String(filters.archived));
|
|
81
|
+
if (filters.include_closed_lists !== undefined)
|
|
82
|
+
params.append('include_closed_lists', String(filters.include_closed_lists));
|
|
83
|
+
if (filters.include_archived_lists !== undefined)
|
|
84
|
+
params.append('include_archived_lists', String(filters.include_archived_lists));
|
|
85
|
+
if (filters.include_compact_time_entries !== undefined)
|
|
86
|
+
params.append('include_compact_time_entries', String(filters.include_compact_time_entries));
|
|
62
87
|
// Date filters
|
|
63
88
|
if (filters.due_date_gt)
|
|
64
89
|
params.append('due_date_gt', String(filters.due_date_gt));
|
|
@@ -560,4 +585,117 @@ export class TaskService extends BaseClickUpService {
|
|
|
560
585
|
throw this.handleError(error, `Failed to upload attachment from URL to task ${taskId}`);
|
|
561
586
|
}
|
|
562
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* Format task data for summary view
|
|
590
|
+
* @param task The task to format
|
|
591
|
+
* @returns TaskSummary object
|
|
592
|
+
*/
|
|
593
|
+
formatTaskSummary(task) {
|
|
594
|
+
return {
|
|
595
|
+
id: task.id,
|
|
596
|
+
name: task.name,
|
|
597
|
+
status: task.status.status,
|
|
598
|
+
list: {
|
|
599
|
+
id: task.list.id,
|
|
600
|
+
name: task.list.name
|
|
601
|
+
},
|
|
602
|
+
due_date: task.due_date,
|
|
603
|
+
url: task.url,
|
|
604
|
+
priority: this.extractPriorityValue(task),
|
|
605
|
+
tags: task.tags.map(tag => ({
|
|
606
|
+
name: tag.name,
|
|
607
|
+
tag_bg: tag.tag_bg,
|
|
608
|
+
tag_fg: tag.tag_fg
|
|
609
|
+
}))
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Estimates token count for a task in JSON format
|
|
614
|
+
* @param task ClickUp task
|
|
615
|
+
* @returns Estimated token count
|
|
616
|
+
*/
|
|
617
|
+
estimateTaskTokens(task) {
|
|
618
|
+
return estimateTokensFromObject(task);
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Get filtered tasks across the entire team/workspace using tags and other filters
|
|
622
|
+
* @param filters Task filters to apply including tags, list/folder/space filtering
|
|
623
|
+
* @returns Either a DetailedTaskResponse or WorkspaceTasksResponse depending on detail_level
|
|
624
|
+
*/
|
|
625
|
+
async getWorkspaceTasks(filters = {}) {
|
|
626
|
+
try {
|
|
627
|
+
this.logOperation('getWorkspaceTasks', { filters });
|
|
628
|
+
const params = this.buildTaskFilterParams(filters);
|
|
629
|
+
const response = await this.client.get(`/team/${this.teamId}/task`, {
|
|
630
|
+
params
|
|
631
|
+
});
|
|
632
|
+
const tasks = response.data.tasks;
|
|
633
|
+
const totalCount = tasks.length; // Note: This is just the current page count
|
|
634
|
+
const hasMore = totalCount === 100; // ClickUp returns max 100 tasks per page
|
|
635
|
+
const nextPage = (filters.page || 0) + 1;
|
|
636
|
+
// If the estimated token count exceeds 50,000 or detail_level is 'summary',
|
|
637
|
+
// return summary format for efficiency and to avoid hitting token limits
|
|
638
|
+
const TOKEN_LIMIT = 50000;
|
|
639
|
+
// Estimate tokens for the full response
|
|
640
|
+
let tokensExceedLimit = false;
|
|
641
|
+
if (filters.detail_level !== 'summary' && tasks.length > 0) {
|
|
642
|
+
// We only need to check token count if detailed was requested
|
|
643
|
+
// For summary requests, we always return summary format
|
|
644
|
+
// First check with a sample task - if one task exceeds the limit, we definitely need summary
|
|
645
|
+
const sampleTask = tasks[0];
|
|
646
|
+
// Check if all tasks would exceed the token limit
|
|
647
|
+
const estimatedTokensPerTask = this.estimateTaskTokens(sampleTask);
|
|
648
|
+
const estimatedTotalTokens = estimatedTokensPerTask * tasks.length;
|
|
649
|
+
// Add 10% overhead for the response wrapper
|
|
650
|
+
tokensExceedLimit = estimatedTotalTokens * 1.1 > TOKEN_LIMIT;
|
|
651
|
+
// Double-check with more precise estimation if we're close to the limit
|
|
652
|
+
if (!tokensExceedLimit && estimatedTotalTokens * 1.1 > TOKEN_LIMIT * 0.8) {
|
|
653
|
+
// More precise check - build a representative sample and extrapolate
|
|
654
|
+
tokensExceedLimit = wouldExceedTokenLimit({ tasks, total_count: totalCount, has_more: hasMore, next_page: nextPage }, TOKEN_LIMIT);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
// Determine if we should return summary or detailed based on request and token limit
|
|
658
|
+
const shouldUseSummary = filters.detail_level === 'summary' || tokensExceedLimit;
|
|
659
|
+
this.logOperation('getWorkspaceTasks', {
|
|
660
|
+
totalTasks: tasks.length,
|
|
661
|
+
estimatedTokens: tasks.reduce((count, task) => count + this.estimateTaskTokens(task), 0),
|
|
662
|
+
usingDetailedFormat: !shouldUseSummary,
|
|
663
|
+
requestedFormat: filters.detail_level || 'auto'
|
|
664
|
+
});
|
|
665
|
+
if (shouldUseSummary) {
|
|
666
|
+
return {
|
|
667
|
+
summaries: tasks.map(task => this.formatTaskSummary(task)),
|
|
668
|
+
total_count: totalCount,
|
|
669
|
+
has_more: hasMore,
|
|
670
|
+
next_page: nextPage
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
return {
|
|
674
|
+
tasks,
|
|
675
|
+
total_count: totalCount,
|
|
676
|
+
has_more: hasMore,
|
|
677
|
+
next_page: nextPage
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
catch (error) {
|
|
681
|
+
this.logOperation('getWorkspaceTasks', { error: error.message, status: error.response?.status });
|
|
682
|
+
throw this.handleError(error, 'Failed to get workspace tasks');
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Get task summaries for lightweight retrieval
|
|
687
|
+
* @param filters Task filters to apply
|
|
688
|
+
* @returns WorkspaceTasksResponse with task summaries
|
|
689
|
+
*/
|
|
690
|
+
async getTaskSummaries(filters = {}) {
|
|
691
|
+
return this.getWorkspaceTasks({ ...filters, detail_level: 'summary' });
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Get detailed task data
|
|
695
|
+
* @param filters Task filters to apply
|
|
696
|
+
* @returns DetailedTaskResponse with full task data
|
|
697
|
+
*/
|
|
698
|
+
async getTaskDetails(filters = {}) {
|
|
699
|
+
return this.getWorkspaceTasks({ ...filters, detail_level: 'detailed' });
|
|
700
|
+
}
|
|
563
701
|
}
|
package/build/services/shared.js
CHANGED
package/build/tools/folder.js
CHANGED
package/build/tools/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*
|
|
2
5
|
* Tools Index
|
|
3
6
|
*
|
|
4
7
|
* This file exports all tool definitions and handlers for the ClickUp MCP server.
|
|
@@ -9,3 +12,4 @@ export * from './workspace.js';
|
|
|
9
12
|
export * from './task/index.js';
|
|
10
13
|
export * from './list.js';
|
|
11
14
|
export * from './folder.js';
|
|
15
|
+
export * from './tag.js';
|