@taazkareem/clickup-mcp-server 0.4.72 → 0.4.73
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/config.js +1 -1
- package/build/server.js +3 -3
- package/build/server.log +34 -28
- package/build/services/clickup/task.js +122 -88
- package/build/services/clickup/types.js +16 -1
- package/build/services/shared.js +6 -6
- package/build/tools/folder.js +6 -9
- package/build/tools/index.js +1 -1
- package/build/tools/list.js +15 -11
- package/build/tools/task/bulk-operations.js +224 -0
- package/build/tools/task/handlers.js +213 -0
- package/build/tools/task/index.js +19 -0
- package/build/tools/task/main.js +89 -0
- package/build/tools/task/single-operations.js +331 -0
- package/build/tools/task/utilities.js +163 -0
- package/build/tools/task.js +369 -485
- package/build/tools/utils.js +0 -2
- package/build/tools/workspace.js +1 -1
- package/build/utils/sponsor-analytics.js +100 -0
- package/build/utils/sponsor-service.js +71 -0
- package/build/utils/sponsor-utils.js +12 -4
- package/package.json +1 -1
- package/build/tools/cache.js +0 -452
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickUp MCP Bulk Task Operations
|
|
3
|
+
*
|
|
4
|
+
* This module defines tools for bulk task operations including creating,
|
|
5
|
+
* updating, moving, and deleting multiple tasks at once.
|
|
6
|
+
*/
|
|
7
|
+
import { clickUpServices } from '../../services/shared.js';
|
|
8
|
+
import { BulkService } from '../../services/clickup/bulk.js';
|
|
9
|
+
// Initialize services
|
|
10
|
+
const { task: taskService } = clickUpServices;
|
|
11
|
+
const bulkService = new BulkService(taskService);
|
|
12
|
+
//=============================================================================
|
|
13
|
+
// COMMON SCHEMA DEFINITIONS
|
|
14
|
+
//=============================================================================
|
|
15
|
+
// Common schema definitions
|
|
16
|
+
const bulkOptionsSchema = {
|
|
17
|
+
oneOf: [
|
|
18
|
+
{
|
|
19
|
+
type: "object",
|
|
20
|
+
description: "Optional processing settings",
|
|
21
|
+
properties: {
|
|
22
|
+
batchSize: {
|
|
23
|
+
type: "number",
|
|
24
|
+
description: "Tasks per batch (default: 10)"
|
|
25
|
+
},
|
|
26
|
+
concurrency: {
|
|
27
|
+
type: "number",
|
|
28
|
+
description: "Parallel operations (default: 3)"
|
|
29
|
+
},
|
|
30
|
+
continueOnError: {
|
|
31
|
+
type: "boolean",
|
|
32
|
+
description: "Continue if some tasks fail"
|
|
33
|
+
},
|
|
34
|
+
retryCount: {
|
|
35
|
+
type: "number",
|
|
36
|
+
description: "Retry attempts for failures"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "JSON string representing options. Will be parsed automatically."
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
description: "Processing options (or JSON string representing options)"
|
|
46
|
+
};
|
|
47
|
+
const taskIdentifierSchema = {
|
|
48
|
+
taskId: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Task ID (preferred). Use instead of taskName if available."
|
|
51
|
+
},
|
|
52
|
+
taskName: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Task name. Requires listName when used."
|
|
55
|
+
},
|
|
56
|
+
listName: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "REQUIRED with taskName: List containing the task."
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
//=============================================================================
|
|
62
|
+
// BULK TASK OPERATION TOOLS
|
|
63
|
+
//=============================================================================
|
|
64
|
+
/**
|
|
65
|
+
* Tool definition for creating multiple tasks at once
|
|
66
|
+
*/
|
|
67
|
+
export const createBulkTasksTool = {
|
|
68
|
+
name: "create_bulk_tasks",
|
|
69
|
+
description: "Create multiple tasks in a list efficiently. You MUST provide:\n1. An array of tasks with required properties\n2. Either listId or listName to specify the target list\n\nOptional: Configure batch size and concurrency for performance.",
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
listId: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "ID of list for new tasks (preferred). Use this instead of listName if you have it."
|
|
76
|
+
},
|
|
77
|
+
listName: {
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Name of list for new tasks. Only use if you don't have listId."
|
|
80
|
+
},
|
|
81
|
+
tasks: {
|
|
82
|
+
type: "array",
|
|
83
|
+
description: "Array of tasks to create. Each task must have at least a name.",
|
|
84
|
+
items: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: {
|
|
87
|
+
name: {
|
|
88
|
+
type: "string",
|
|
89
|
+
description: "Task name with emoji prefix"
|
|
90
|
+
},
|
|
91
|
+
description: {
|
|
92
|
+
type: "string",
|
|
93
|
+
description: "Plain text description"
|
|
94
|
+
},
|
|
95
|
+
markdown_description: {
|
|
96
|
+
type: "string",
|
|
97
|
+
description: "Markdown description (overrides plain text)"
|
|
98
|
+
},
|
|
99
|
+
status: {
|
|
100
|
+
type: "string",
|
|
101
|
+
description: "Task status (uses list default if omitted)"
|
|
102
|
+
},
|
|
103
|
+
priority: {
|
|
104
|
+
type: "number",
|
|
105
|
+
description: "Priority 1-4 (1=urgent, 4=low)"
|
|
106
|
+
},
|
|
107
|
+
dueDate: {
|
|
108
|
+
type: "string",
|
|
109
|
+
description: "Due date. Supports Unix timestamps (in milliseconds) and natural language expressions like '1 hour from now', 'tomorrow', 'next week', etc."
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
required: ["name"]
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
options: bulkOptionsSchema
|
|
116
|
+
},
|
|
117
|
+
required: ["tasks"]
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Tool definition for updating multiple tasks at once
|
|
122
|
+
*/
|
|
123
|
+
export const updateBulkTasksTool = {
|
|
124
|
+
name: "update_bulk_tasks",
|
|
125
|
+
description: "Update multiple tasks efficiently. For each task, you MUST provide either:\n1. taskId alone (preferred)\n2. taskName + listName\n\nOnly specified fields will be updated for each task.",
|
|
126
|
+
inputSchema: {
|
|
127
|
+
type: "object",
|
|
128
|
+
properties: {
|
|
129
|
+
tasks: {
|
|
130
|
+
type: "array",
|
|
131
|
+
description: "Array of tasks to update",
|
|
132
|
+
items: {
|
|
133
|
+
type: "object",
|
|
134
|
+
properties: {
|
|
135
|
+
...taskIdentifierSchema,
|
|
136
|
+
name: {
|
|
137
|
+
type: "string",
|
|
138
|
+
description: "New name with emoji prefix"
|
|
139
|
+
},
|
|
140
|
+
description: {
|
|
141
|
+
type: "string",
|
|
142
|
+
description: "New plain text description"
|
|
143
|
+
},
|
|
144
|
+
markdown_description: {
|
|
145
|
+
type: "string",
|
|
146
|
+
description: "New markdown description"
|
|
147
|
+
},
|
|
148
|
+
status: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "New status"
|
|
151
|
+
},
|
|
152
|
+
priority: {
|
|
153
|
+
type: ["number", "null"],
|
|
154
|
+
enum: [1, 2, 3, 4, null],
|
|
155
|
+
description: "New priority (1-4 or null)"
|
|
156
|
+
},
|
|
157
|
+
dueDate: {
|
|
158
|
+
type: "string",
|
|
159
|
+
description: "New due date. Supports Unix timestamps (in milliseconds) and natural language expressions like '1 hour from now', 'tomorrow', etc."
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
options: bulkOptionsSchema
|
|
165
|
+
},
|
|
166
|
+
required: ["tasks"]
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Tool definition for moving multiple tasks at once
|
|
171
|
+
*/
|
|
172
|
+
export const moveBulkTasksTool = {
|
|
173
|
+
name: "move_bulk_tasks",
|
|
174
|
+
description: "Move multiple tasks to a different list efficiently. For each task, you MUST provide either:\n1. taskId alone (preferred)\n2. taskName + listName\n\nWARNING: Task statuses may reset if target list has different status options.",
|
|
175
|
+
inputSchema: {
|
|
176
|
+
type: "object",
|
|
177
|
+
properties: {
|
|
178
|
+
tasks: {
|
|
179
|
+
type: "array",
|
|
180
|
+
description: "Array of tasks to move",
|
|
181
|
+
items: {
|
|
182
|
+
type: "object",
|
|
183
|
+
properties: {
|
|
184
|
+
...taskIdentifierSchema
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
targetListId: {
|
|
189
|
+
type: "string",
|
|
190
|
+
description: "ID of destination list (preferred). Use instead of targetListName if available."
|
|
191
|
+
},
|
|
192
|
+
targetListName: {
|
|
193
|
+
type: "string",
|
|
194
|
+
description: "Name of destination list. Only use if you don't have targetListId."
|
|
195
|
+
},
|
|
196
|
+
options: bulkOptionsSchema
|
|
197
|
+
},
|
|
198
|
+
required: ["tasks"]
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Tool definition for deleting multiple tasks at once
|
|
203
|
+
*/
|
|
204
|
+
export const deleteBulkTasksTool = {
|
|
205
|
+
name: "delete_bulk_tasks",
|
|
206
|
+
description: "⚠️ PERMANENTLY DELETE multiple tasks. This action cannot be undone. For each task, you MUST provide either:\n1. taskId alone (preferred and safest)\n2. taskName + listName (use with caution).",
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: "object",
|
|
209
|
+
properties: {
|
|
210
|
+
tasks: {
|
|
211
|
+
type: "array",
|
|
212
|
+
description: "Array of tasks to delete",
|
|
213
|
+
items: {
|
|
214
|
+
type: "object",
|
|
215
|
+
properties: {
|
|
216
|
+
...taskIdentifierSchema
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
options: bulkOptionsSchema
|
|
221
|
+
},
|
|
222
|
+
required: ["tasks"]
|
|
223
|
+
}
|
|
224
|
+
};
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickUp MCP Task Operation Handlers
|
|
3
|
+
*
|
|
4
|
+
* This module implements the handlers for task operations, both for single task
|
|
5
|
+
* and bulk operations. These handlers are used by the tool definitions.
|
|
6
|
+
*/
|
|
7
|
+
import { toTaskPriority } from '../../services/clickup/types.js';
|
|
8
|
+
import { clickUpServices } from '../../services/shared.js';
|
|
9
|
+
import { BulkService } from '../../services/clickup/bulk.js';
|
|
10
|
+
import { parseDueDate } from '../utils.js';
|
|
11
|
+
import { validateTaskIdentification, validateListIdentification, validateTaskUpdateData, validateBulkTasks, parseBulkOptions, resolveTaskIdWithValidation, resolveListIdWithValidation } from './utilities.js';
|
|
12
|
+
// Use shared services instance
|
|
13
|
+
const { task: taskService, list: listService } = clickUpServices;
|
|
14
|
+
// Create a bulk service instance that uses the task service
|
|
15
|
+
const bulkService = new BulkService(taskService);
|
|
16
|
+
//=============================================================================
|
|
17
|
+
// SHARED UTILITY FUNCTIONS
|
|
18
|
+
//=============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Build task update data from parameters
|
|
21
|
+
*/
|
|
22
|
+
function buildUpdateData(params) {
|
|
23
|
+
const updateData = {};
|
|
24
|
+
if (params.name !== undefined)
|
|
25
|
+
updateData.name = params.name;
|
|
26
|
+
if (params.description !== undefined)
|
|
27
|
+
updateData.description = params.description;
|
|
28
|
+
if (params.markdown_description !== undefined)
|
|
29
|
+
updateData.markdown_description = params.markdown_description;
|
|
30
|
+
if (params.status !== undefined)
|
|
31
|
+
updateData.status = params.status;
|
|
32
|
+
if (params.priority !== undefined)
|
|
33
|
+
updateData.priority = toTaskPriority(params.priority);
|
|
34
|
+
if (params.dueDate !== undefined)
|
|
35
|
+
updateData.due_date = parseDueDate(params.dueDate);
|
|
36
|
+
return updateData;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Process a task identification validation, returning the task ID
|
|
40
|
+
*/
|
|
41
|
+
async function getTaskId(taskId, taskName, listName) {
|
|
42
|
+
validateTaskIdentification(taskId, taskName, listName);
|
|
43
|
+
return await resolveTaskIdWithValidation(taskId, taskName, listName);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Process a list identification validation, returning the list ID
|
|
47
|
+
*/
|
|
48
|
+
async function getListId(listId, listName) {
|
|
49
|
+
validateListIdentification(listId, listName);
|
|
50
|
+
return await resolveListIdWithValidation(listId, listName);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract and build task filters from parameters
|
|
54
|
+
*/
|
|
55
|
+
function buildTaskFilters(params) {
|
|
56
|
+
const { subtasks, statuses, page, order_by, reverse } = params;
|
|
57
|
+
const filters = {};
|
|
58
|
+
if (subtasks !== undefined)
|
|
59
|
+
filters.subtasks = subtasks;
|
|
60
|
+
if (statuses !== undefined)
|
|
61
|
+
filters.statuses = statuses;
|
|
62
|
+
if (page !== undefined)
|
|
63
|
+
filters.page = page;
|
|
64
|
+
if (order_by !== undefined)
|
|
65
|
+
filters.order_by = order_by;
|
|
66
|
+
if (reverse !== undefined)
|
|
67
|
+
filters.reverse = reverse;
|
|
68
|
+
return filters;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Map tasks for bulk operations, resolving task IDs
|
|
72
|
+
*/
|
|
73
|
+
async function mapTaskIds(tasks) {
|
|
74
|
+
return Promise.all(tasks.map(async (task) => {
|
|
75
|
+
validateTaskIdentification(task.taskId, task.taskName, task.listName);
|
|
76
|
+
return await resolveTaskIdWithValidation(task.taskId, task.taskName, task.listName);
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
//=============================================================================
|
|
80
|
+
// SINGLE TASK OPERATIONS
|
|
81
|
+
//=============================================================================
|
|
82
|
+
/**
|
|
83
|
+
* Handler for creating a task
|
|
84
|
+
*/
|
|
85
|
+
export async function createTaskHandler(params) {
|
|
86
|
+
const { name, description, markdown_description, status, dueDate } = params;
|
|
87
|
+
if (!name)
|
|
88
|
+
throw new Error("Task name is required");
|
|
89
|
+
// Use our helper function to validate and convert priority
|
|
90
|
+
const priority = toTaskPriority(params.priority);
|
|
91
|
+
const listId = await getListId(params.listId, params.listName);
|
|
92
|
+
return await taskService.createTask(listId, {
|
|
93
|
+
name,
|
|
94
|
+
description,
|
|
95
|
+
markdown_description,
|
|
96
|
+
status,
|
|
97
|
+
priority,
|
|
98
|
+
due_date: dueDate ? parseDueDate(dueDate) : undefined
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Handler for updating a task
|
|
103
|
+
*/
|
|
104
|
+
export async function updateTaskHandler(params) {
|
|
105
|
+
validateTaskUpdateData(params);
|
|
106
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
107
|
+
return await taskService.updateTask(taskId, buildUpdateData(params));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Handler for moving a task
|
|
111
|
+
*/
|
|
112
|
+
export async function moveTaskHandler(params) {
|
|
113
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
114
|
+
const listId = await getListId(params.listId, params.listName);
|
|
115
|
+
return await taskService.moveTask(taskId, listId);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Handler for duplicating a task
|
|
119
|
+
*/
|
|
120
|
+
export async function duplicateTaskHandler(params) {
|
|
121
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
122
|
+
let listId;
|
|
123
|
+
if (params.listId || params.listName) {
|
|
124
|
+
listId = await getListId(params.listId, params.listName);
|
|
125
|
+
}
|
|
126
|
+
return await taskService.duplicateTask(taskId, listId);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handler for getting a task
|
|
130
|
+
*/
|
|
131
|
+
export async function getTaskHandler(params) {
|
|
132
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
133
|
+
return await taskService.getTask(taskId);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Handler for getting tasks
|
|
137
|
+
*/
|
|
138
|
+
export async function getTasksHandler(params) {
|
|
139
|
+
const listId = await getListId(params.listId, params.listName);
|
|
140
|
+
return await taskService.getTasks(listId, buildTaskFilters(params));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Handler for deleting a task
|
|
144
|
+
*/
|
|
145
|
+
export async function deleteTaskHandler(params) {
|
|
146
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
147
|
+
await taskService.deleteTask(taskId);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Handler for getting task comments
|
|
152
|
+
*/
|
|
153
|
+
export async function getTaskCommentsHandler(params) {
|
|
154
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
155
|
+
const { start, startId } = params;
|
|
156
|
+
return await taskService.getTaskComments(taskId, start, startId);
|
|
157
|
+
}
|
|
158
|
+
//=============================================================================
|
|
159
|
+
// BULK TASK OPERATIONS
|
|
160
|
+
//=============================================================================
|
|
161
|
+
/**
|
|
162
|
+
* Handler for creating multiple tasks
|
|
163
|
+
*/
|
|
164
|
+
export async function createBulkTasksHandler(params) {
|
|
165
|
+
validateBulkTasks(params.tasks);
|
|
166
|
+
const listId = await getListId(params.listId, params.listName);
|
|
167
|
+
// Process tasks - prepare data for each task
|
|
168
|
+
const tasks = params.tasks.map(task => {
|
|
169
|
+
const processedTask = { ...task };
|
|
170
|
+
if (task.dueDate) {
|
|
171
|
+
processedTask.due_date = parseDueDate(task.dueDate);
|
|
172
|
+
delete processedTask.dueDate;
|
|
173
|
+
}
|
|
174
|
+
return processedTask;
|
|
175
|
+
});
|
|
176
|
+
const result = await bulkService.createTasks(listId, tasks, parseBulkOptions(params.options));
|
|
177
|
+
return result.successful;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Handler for updating multiple tasks
|
|
181
|
+
*/
|
|
182
|
+
export async function updateBulkTasksHandler(params) {
|
|
183
|
+
validateBulkTasks(params.tasks);
|
|
184
|
+
const updates = await Promise.all(params.tasks.map(async (task) => {
|
|
185
|
+
validateTaskUpdateData(task);
|
|
186
|
+
const taskId = await getTaskId(task.taskId, task.taskName, task.listName);
|
|
187
|
+
return { id: taskId, data: buildUpdateData(task) };
|
|
188
|
+
}));
|
|
189
|
+
const result = await bulkService.updateTasks(updates, parseBulkOptions(params.options));
|
|
190
|
+
return result.successful;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Handler for moving multiple tasks
|
|
194
|
+
*/
|
|
195
|
+
export async function moveBulkTasksHandler(params) {
|
|
196
|
+
validateBulkTasks(params.tasks);
|
|
197
|
+
if (!params.targetListId && !params.targetListName) {
|
|
198
|
+
throw new Error("Either targetListId or targetListName must be provided");
|
|
199
|
+
}
|
|
200
|
+
const targetListId = await getListId(params.targetListId, params.targetListName);
|
|
201
|
+
const taskIds = await mapTaskIds(params.tasks);
|
|
202
|
+
const result = await bulkService.moveTasks(taskIds, targetListId, parseBulkOptions(params.options));
|
|
203
|
+
return result.successful;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Handler for deleting multiple tasks
|
|
207
|
+
*/
|
|
208
|
+
export async function deleteBulkTasksHandler(params) {
|
|
209
|
+
validateBulkTasks(params.tasks);
|
|
210
|
+
const taskIds = await mapTaskIds(params.tasks);
|
|
211
|
+
await bulkService.deleteTasks(taskIds, parseBulkOptions(params.options));
|
|
212
|
+
return taskIds.map(() => true);
|
|
213
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickUp MCP Task Tools
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports all task-related tools and handlers.
|
|
5
|
+
*/
|
|
6
|
+
// Re-export from main module
|
|
7
|
+
export * from './main.js';
|
|
8
|
+
// Re-export single task operation tools
|
|
9
|
+
export { createTaskTool, getTaskTool, getTasksTool, updateTaskTool, moveTaskTool, duplicateTaskTool, deleteTaskTool, getTaskCommentsTool } from './single-operations.js';
|
|
10
|
+
// Re-export bulk task operation tools
|
|
11
|
+
export { createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool } from './bulk-operations.js';
|
|
12
|
+
// Re-export handlers
|
|
13
|
+
export {
|
|
14
|
+
// Single task operation handlers
|
|
15
|
+
createTaskHandler, getTaskHandler, getTasksHandler, updateTaskHandler, moveTaskHandler, duplicateTaskHandler, deleteTaskHandler, getTaskCommentsHandler,
|
|
16
|
+
// Bulk task operation handlers
|
|
17
|
+
createBulkTasksHandler, updateBulkTasksHandler, moveBulkTasksHandler, deleteBulkTasksHandler } from './handlers.js';
|
|
18
|
+
// Re-export utilities
|
|
19
|
+
export { formatTaskData, validateTaskIdentification, validateListIdentification, validateTaskUpdateData, validateBulkTasks, parseBulkOptions, resolveTaskIdWithValidation, resolveListIdWithValidation } from './utilities.js';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickUp MCP Task Tools
|
|
3
|
+
*
|
|
4
|
+
* This is the main task module that connects tool definitions to their handlers.
|
|
5
|
+
* The actual implementations are organized in sub-modules for better maintainability.
|
|
6
|
+
*/
|
|
7
|
+
import { sponsorService } from '../../utils/sponsor-service.js';
|
|
8
|
+
// Import tool definitions
|
|
9
|
+
import { createTaskTool, getTaskTool, getTasksTool, updateTaskTool, moveTaskTool, duplicateTaskTool, deleteTaskTool, getTaskCommentsTool } from './single-operations.js';
|
|
10
|
+
import { createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool } from './bulk-operations.js';
|
|
11
|
+
// Import handlers
|
|
12
|
+
import { createTaskHandler, getTaskHandler, getTasksHandler, updateTaskHandler, moveTaskHandler, duplicateTaskHandler, deleteTaskHandler, getTaskCommentsHandler, createBulkTasksHandler, updateBulkTasksHandler, moveBulkTasksHandler, deleteBulkTasksHandler } from './handlers.js';
|
|
13
|
+
//=============================================================================
|
|
14
|
+
// HANDLER WRAPPER UTILITY
|
|
15
|
+
//=============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Creates a wrapped handler function with standard error handling and response formatting
|
|
18
|
+
*/
|
|
19
|
+
function createHandlerWrapper(handler, formatResponse = (result) => result) {
|
|
20
|
+
return async (parameters) => {
|
|
21
|
+
try {
|
|
22
|
+
const result = await handler(parameters);
|
|
23
|
+
return sponsorService.createResponse(formatResponse(result), true);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return sponsorService.createErrorResponse(error, parameters);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//=============================================================================
|
|
31
|
+
// SINGLE TASK OPERATIONS - HANDLER IMPLEMENTATIONS
|
|
32
|
+
//=============================================================================
|
|
33
|
+
export const handleCreateTask = createHandlerWrapper(createTaskHandler);
|
|
34
|
+
export const handleGetTask = createHandlerWrapper(getTaskHandler);
|
|
35
|
+
export const handleGetTasks = createHandlerWrapper(getTasksHandler, (tasks) => ({
|
|
36
|
+
tasks,
|
|
37
|
+
count: tasks.length
|
|
38
|
+
}));
|
|
39
|
+
export const handleUpdateTask = createHandlerWrapper(updateTaskHandler);
|
|
40
|
+
export const handleMoveTask = createHandlerWrapper(moveTaskHandler);
|
|
41
|
+
export const handleDuplicateTask = createHandlerWrapper(duplicateTaskHandler);
|
|
42
|
+
export const handleDeleteTask = createHandlerWrapper(deleteTaskHandler, () => ({
|
|
43
|
+
success: true,
|
|
44
|
+
message: "Task deleted successfully"
|
|
45
|
+
}));
|
|
46
|
+
export const handleGetTaskComments = createHandlerWrapper(getTaskCommentsHandler, (comments) => ({
|
|
47
|
+
comments,
|
|
48
|
+
count: comments.length
|
|
49
|
+
}));
|
|
50
|
+
//=============================================================================
|
|
51
|
+
// BULK TASK OPERATIONS - HANDLER IMPLEMENTATIONS
|
|
52
|
+
//=============================================================================
|
|
53
|
+
export const handleCreateBulkTasks = createHandlerWrapper(createBulkTasksHandler, (tasks) => ({
|
|
54
|
+
tasks,
|
|
55
|
+
count: tasks.length
|
|
56
|
+
}));
|
|
57
|
+
export const handleUpdateBulkTasks = createHandlerWrapper(updateBulkTasksHandler, (tasks) => ({
|
|
58
|
+
tasks,
|
|
59
|
+
count: tasks.length
|
|
60
|
+
}));
|
|
61
|
+
export const handleMoveBulkTasks = createHandlerWrapper(moveBulkTasksHandler, (tasks) => ({
|
|
62
|
+
tasks,
|
|
63
|
+
count: tasks.length
|
|
64
|
+
}));
|
|
65
|
+
export const handleDeleteBulkTasks = createHandlerWrapper(deleteBulkTasksHandler, (results) => ({
|
|
66
|
+
success: true,
|
|
67
|
+
count: results.length,
|
|
68
|
+
results
|
|
69
|
+
}));
|
|
70
|
+
//=============================================================================
|
|
71
|
+
// TOOL DEFINITIONS AND HANDLERS EXPORT
|
|
72
|
+
//=============================================================================
|
|
73
|
+
// Tool definitions with their handler mappings
|
|
74
|
+
export const taskTools = [
|
|
75
|
+
// Single task operations
|
|
76
|
+
{ definition: createTaskTool, handler: handleCreateTask },
|
|
77
|
+
{ definition: getTaskTool, handler: handleGetTask },
|
|
78
|
+
{ definition: getTasksTool, handler: handleGetTasks },
|
|
79
|
+
{ definition: updateTaskTool, handler: handleUpdateTask },
|
|
80
|
+
{ definition: moveTaskTool, handler: handleMoveTask },
|
|
81
|
+
{ definition: duplicateTaskTool, handler: handleDuplicateTask },
|
|
82
|
+
{ definition: deleteTaskTool, handler: handleDeleteTask },
|
|
83
|
+
{ definition: getTaskCommentsTool, handler: handleGetTaskComments },
|
|
84
|
+
// Bulk task operations
|
|
85
|
+
{ definition: createBulkTasksTool, handler: handleCreateBulkTasks },
|
|
86
|
+
{ definition: updateBulkTasksTool, handler: handleUpdateBulkTasks },
|
|
87
|
+
{ definition: moveBulkTasksTool, handler: handleMoveBulkTasks },
|
|
88
|
+
{ definition: deleteBulkTasksTool, handler: handleDeleteBulkTasks }
|
|
89
|
+
];
|