@taazkareem/clickup-mcp-server 0.6.2 → 0.6.4
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 +6 -6
- package/build/logger.js +26 -1
- package/build/server.js +1 -1
- package/build/services/clickup/base.js +22 -1
- package/build/services/clickup/bulk.js +111 -69
- package/build/services/clickup/index.js +2 -2
- package/build/services/clickup/task/index.js +32 -0
- package/build/services/clickup/task/task-attachments.js +97 -0
- package/build/services/clickup/task/task-comments.js +104 -0
- package/build/services/clickup/task/task-core.js +439 -0
- package/build/services/clickup/task/task-custom-fields.js +97 -0
- package/build/services/clickup/task/task-search.js +462 -0
- package/build/services/clickup/task/task-service.js +25 -0
- package/build/services/clickup/task/task-tags.js +101 -0
- package/build/services/clickup/workspace.js +81 -36
- package/build/tools/folder.js +1 -1
- package/build/tools/list.js +2 -4
- package/build/tools/task/attachments.js +49 -20
- package/build/tools/task/attachments.types.js +9 -0
- package/build/tools/task/bulk-operations.js +102 -18
- package/build/tools/task/handlers.js +216 -53
- package/build/tools/task/index.js +1 -1
- package/build/tools/task/main.js +161 -32
- package/build/tools/task/single-operations.js +82 -17
- package/build/tools/task/utilities.js +47 -75
- package/build/tools/utils.js +2 -2
- package/build/utils/date-utils.js +149 -30
- package/build/utils/resolver-utils.js +33 -40
- package/build/utils/sponsor-service.js +1 -1
- package/package.json +1 -1
- package/build/mcp-tools.js +0 -64
- package/build/server-state.js +0 -93
- package/build/server.log +0 -0
- package/build/services/clickup/task.js +0 -701
- package/build/tools/bulk-tasks.js +0 -36
- package/build/tools/debug.js +0 -76
- package/build/tools/logs.js +0 -55
- package/build/tools/task.js +0 -1554
- package/build/utils/params-utils.js +0 -39
- package/build/utils/sponsor-analytics.js +0 -100
- package/build/utils/sponsor-utils.js +0 -57
|
@@ -104,8 +104,11 @@ export class WorkspaceService extends BaseClickUpService {
|
|
|
104
104
|
try {
|
|
105
105
|
// If we have the hierarchy in memory and not forcing refresh, return it
|
|
106
106
|
if (this.workspaceHierarchy && !forceRefresh) {
|
|
107
|
+
this.logger.debug('Returning cached workspace hierarchy');
|
|
107
108
|
return this.workspaceHierarchy;
|
|
108
109
|
}
|
|
110
|
+
const startTime = Date.now();
|
|
111
|
+
this.logger.info('Starting workspace hierarchy fetch');
|
|
109
112
|
// Start building the workspace tree
|
|
110
113
|
const workspaceTree = {
|
|
111
114
|
root: {
|
|
@@ -115,51 +118,93 @@ export class WorkspaceService extends BaseClickUpService {
|
|
|
115
118
|
}
|
|
116
119
|
};
|
|
117
120
|
// Get all spaces
|
|
121
|
+
const spacesStartTime = Date.now();
|
|
118
122
|
const spaces = await this.getSpaces();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
const spacesTime = Date.now() - spacesStartTime;
|
|
124
|
+
this.logger.info(`Fetched ${spaces.length} spaces in ${spacesTime}ms`);
|
|
125
|
+
// Process spaces in batches to respect rate limits
|
|
126
|
+
const batchSize = 3; // Process 3 spaces at a time
|
|
127
|
+
const spaceNodes = [];
|
|
128
|
+
let totalFolders = 0;
|
|
129
|
+
let totalLists = 0;
|
|
130
|
+
for (let i = 0; i < spaces.length; i += batchSize) {
|
|
131
|
+
const batchStartTime = Date.now();
|
|
132
|
+
const spaceBatch = spaces.slice(i, i + batchSize);
|
|
133
|
+
this.logger.debug(`Processing space batch ${i / batchSize + 1} of ${Math.ceil(spaces.length / batchSize)} (${spaceBatch.length} spaces)`);
|
|
134
|
+
const batchNodes = await Promise.all(spaceBatch.map(async (space) => {
|
|
135
|
+
const spaceStartTime = Date.now();
|
|
136
|
+
const spaceNode = {
|
|
137
|
+
id: space.id,
|
|
138
|
+
name: space.name,
|
|
139
|
+
type: 'space',
|
|
135
140
|
children: []
|
|
136
141
|
};
|
|
137
|
-
//
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
// Fetch initial space data
|
|
143
|
+
const [folders, listsInSpace] = await Promise.all([
|
|
144
|
+
this.getFoldersInSpace(space.id),
|
|
145
|
+
this.getListsInSpace(space.id)
|
|
146
|
+
]);
|
|
147
|
+
totalFolders += folders.length;
|
|
148
|
+
totalLists += listsInSpace.length;
|
|
149
|
+
// Process folders in smaller batches
|
|
150
|
+
const folderBatchSize = 5; // Process 5 folders at a time
|
|
151
|
+
const folderNodes = [];
|
|
152
|
+
for (let j = 0; j < folders.length; j += folderBatchSize) {
|
|
153
|
+
const folderBatchStartTime = Date.now();
|
|
154
|
+
const folderBatch = folders.slice(j, j + folderBatchSize);
|
|
155
|
+
const batchFolderNodes = await Promise.all(folderBatch.map(async (folder) => {
|
|
156
|
+
const folderNode = {
|
|
157
|
+
id: folder.id,
|
|
158
|
+
name: folder.name,
|
|
159
|
+
type: 'folder',
|
|
160
|
+
parentId: space.id,
|
|
161
|
+
children: []
|
|
162
|
+
};
|
|
163
|
+
// Get lists in the folder
|
|
164
|
+
const listsInFolder = await this.getListsInFolder(folder.id);
|
|
165
|
+
totalLists += listsInFolder.length;
|
|
166
|
+
folderNode.children = listsInFolder.map(list => ({
|
|
167
|
+
id: list.id,
|
|
168
|
+
name: list.name,
|
|
169
|
+
type: 'list',
|
|
170
|
+
parentId: folder.id
|
|
171
|
+
}));
|
|
172
|
+
return folderNode;
|
|
173
|
+
}));
|
|
174
|
+
folderNodes.push(...batchFolderNodes);
|
|
175
|
+
const folderBatchTime = Date.now() - folderBatchStartTime;
|
|
176
|
+
this.logger.debug(`Processed folder batch in space ${space.name} in ${folderBatchTime}ms (${folderBatch.length} folders)`);
|
|
146
177
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
for (const list of listsInSpace) {
|
|
153
|
-
this.logger.debug(`Adding list directly to space: ${list.name} (${list.id})`);
|
|
154
|
-
spaceNode.children?.push({
|
|
178
|
+
// Add folder nodes to space
|
|
179
|
+
spaceNode.children?.push(...folderNodes);
|
|
180
|
+
// Add folderless lists to space
|
|
181
|
+
this.logger.debug(`Adding ${listsInSpace.length} lists directly to space ${space.name}`);
|
|
182
|
+
const listNodes = listsInSpace.map(list => ({
|
|
155
183
|
id: list.id,
|
|
156
184
|
name: list.name,
|
|
157
185
|
type: 'list',
|
|
158
186
|
parentId: space.id
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
|
|
187
|
+
}));
|
|
188
|
+
spaceNode.children?.push(...listNodes);
|
|
189
|
+
const spaceTime = Date.now() - spaceStartTime;
|
|
190
|
+
this.logger.info(`Processed space ${space.name} in ${spaceTime}ms (${folders.length} folders, ${listsInSpace.length} lists)`);
|
|
191
|
+
return spaceNode;
|
|
192
|
+
}));
|
|
193
|
+
spaceNodes.push(...batchNodes);
|
|
194
|
+
const batchTime = Date.now() - batchStartTime;
|
|
195
|
+
this.logger.info(`Processed space batch in ${batchTime}ms (${spaceBatch.length} spaces)`);
|
|
162
196
|
}
|
|
197
|
+
// Add all space nodes to the workspace tree
|
|
198
|
+
workspaceTree.root.children.push(...spaceNodes);
|
|
199
|
+
const totalTime = Date.now() - startTime;
|
|
200
|
+
this.logger.info('Workspace hierarchy fetch completed', {
|
|
201
|
+
duration: totalTime,
|
|
202
|
+
spaces: spaces.length,
|
|
203
|
+
folders: totalFolders,
|
|
204
|
+
lists: totalLists,
|
|
205
|
+
averageTimePerSpace: totalTime / spaces.length,
|
|
206
|
+
averageTimePerNode: totalTime / (spaces.length + totalFolders + totalLists)
|
|
207
|
+
});
|
|
163
208
|
// Store the hierarchy for later use
|
|
164
209
|
this.workspaceHierarchy = workspaceTree;
|
|
165
210
|
return workspaceTree;
|
package/build/tools/folder.js
CHANGED
|
@@ -156,7 +156,7 @@ Requirements:
|
|
|
156
156
|
- EITHER folderId OR (folderName + space information) is REQUIRED
|
|
157
157
|
- When using folderName, you MUST provide EITHER spaceId OR spaceName
|
|
158
158
|
|
|
159
|
-
|
|
159
|
+
Warning:
|
|
160
160
|
- This action CANNOT be undone
|
|
161
161
|
- All lists and tasks within the folder will also be permanently deleted
|
|
162
162
|
- Using folderName is risky as names may not be unique across different spaces`,
|
package/build/tools/list.js
CHANGED
|
@@ -8,11 +8,9 @@
|
|
|
8
8
|
* retrieving, and deleting lists. It supports creating lists both in spaces
|
|
9
9
|
* and in folders.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { listService, workspaceService } from '../services/shared.js';
|
|
12
12
|
import config from '../config.js';
|
|
13
13
|
import { sponsorService } from '../utils/sponsor-service.js';
|
|
14
|
-
// Use shared services instance
|
|
15
|
-
const { list: listService, workspace: workspaceService } = clickUpServices;
|
|
16
14
|
/**
|
|
17
15
|
* Tool definition for creating a list directly in a space
|
|
18
16
|
*/
|
|
@@ -216,7 +214,7 @@ Valid Usage:
|
|
|
216
214
|
Requirements:
|
|
217
215
|
- EITHER listId OR listName: REQUIRED
|
|
218
216
|
|
|
219
|
-
|
|
217
|
+
Warning:
|
|
220
218
|
- This action CANNOT be undone
|
|
221
219
|
- All tasks within the list will also be permanently deleted
|
|
222
220
|
- Using listName is risky as names may not be unique`,
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
* This module implements a tool for attaching files to ClickUp tasks
|
|
8
8
|
* with automatic method selection based on file source and size.
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
import { validateTaskIdentification
|
|
10
|
+
import { clickUpServices } from '../../services/shared.js';
|
|
11
|
+
import { validateTaskIdentification } from './utilities.js';
|
|
12
12
|
import { sponsorService } from '../../utils/sponsor-service.js';
|
|
13
|
+
// Use shared services instance
|
|
14
|
+
const { task: taskService } = clickUpServices;
|
|
13
15
|
// Session storage for chunked uploads (in-memory for demonstration)
|
|
14
|
-
// In production, this should use a more persistent store
|
|
15
16
|
const chunkSessions = new Map();
|
|
16
17
|
// Clean up expired sessions periodically
|
|
17
18
|
setInterval(() => {
|
|
@@ -32,22 +33,39 @@ export const attachTaskFileTool = {
|
|
|
32
33
|
description: `Purpose: Attaches a file to a ClickUp task.
|
|
33
34
|
|
|
34
35
|
Valid Usage:
|
|
36
|
+
1. Use taskId alone (preferred) - works with both regular and custom IDs
|
|
37
|
+
2. Use taskName alone (will search across all lists)
|
|
38
|
+
3. Use taskName + listName (for faster, targeted search)
|
|
39
|
+
|
|
40
|
+
File Source Options:
|
|
35
41
|
1. Upload from base64: Provide file_data + file_name
|
|
36
|
-
2. Upload from URL
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
3. For large files, advanced options are available via chunk_* parameters
|
|
42
|
+
2. Upload from URL: Provide file_url starting with http:// or https://
|
|
43
|
+
3. Upload from local file: Provide file_url as absolute path (starting with / or drive letter)
|
|
44
|
+
4. For large files: Use chunk_* parameters for advanced chunked uploading
|
|
40
45
|
|
|
41
46
|
Requirements:
|
|
42
|
-
- EITHER taskId OR
|
|
43
|
-
-
|
|
47
|
+
- EITHER taskId OR taskName: REQUIRED
|
|
48
|
+
- listName: Optional, but recommended when using taskName
|
|
49
|
+
- File Source: ONE of the following is REQUIRED:
|
|
50
|
+
- file_data + file_name
|
|
51
|
+
- file_url (web URL or local path)
|
|
52
|
+
- chunk_session (for continuing chunked upload)
|
|
44
53
|
|
|
45
54
|
Notes:
|
|
46
|
-
- The
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
55
|
+
- The tool automatically searches for tasks using smart name matching
|
|
56
|
+
- When only taskName is provided, it searches across all lists
|
|
57
|
+
- Adding listName narrows the search to a specific list for better performance
|
|
58
|
+
- The system automatically selects the best upload method based on file size and source:
|
|
59
|
+
- Base64 method: Limited to 10MB due to encoding overhead
|
|
60
|
+
- URL method: Works for files hosted online
|
|
61
|
+
- Local file method: Works with absolute paths only
|
|
62
|
+
- Large files: Automatically uses chunked uploading
|
|
63
|
+
|
|
64
|
+
Warning:
|
|
65
|
+
- Using taskName without listName may match multiple tasks
|
|
66
|
+
- If multiple matches are found, the operation will fail with a disambiguation error
|
|
67
|
+
- For local files, relative paths are not supported
|
|
68
|
+
- Base64 uploads over 10MB will automatically switch to chunked upload mode`,
|
|
51
69
|
inputSchema: {
|
|
52
70
|
type: "object",
|
|
53
71
|
properties: {
|
|
@@ -57,11 +75,11 @@ Notes:
|
|
|
57
75
|
},
|
|
58
76
|
taskName: {
|
|
59
77
|
type: "string",
|
|
60
|
-
description: "Name of the task to attach the file to.
|
|
78
|
+
description: "Name of the task to attach the file to. The tool will search for tasks with this name across all lists unless listName is specified."
|
|
61
79
|
},
|
|
62
80
|
listName: {
|
|
63
81
|
type: "string",
|
|
64
|
-
description: "Name of
|
|
82
|
+
description: "Optional: Name of list containing the task. Providing this narrows the search to a specific list, improving performance and reducing ambiguity."
|
|
65
83
|
},
|
|
66
84
|
file_name: {
|
|
67
85
|
type: "string",
|
|
@@ -96,8 +114,7 @@ Notes:
|
|
|
96
114
|
type: "boolean",
|
|
97
115
|
description: "Optional: For advanced usage with large file chunking. Whether this is the final chunk."
|
|
98
116
|
}
|
|
99
|
-
}
|
|
100
|
-
required: [] // Will validate based on context in the handler
|
|
117
|
+
}
|
|
101
118
|
}
|
|
102
119
|
};
|
|
103
120
|
/**
|
|
@@ -113,7 +130,18 @@ async function attachTaskFileHandler(params) {
|
|
|
113
130
|
throw new Error("Either file_data, file_url, or session_id must be provided");
|
|
114
131
|
}
|
|
115
132
|
// Resolve task ID
|
|
116
|
-
const
|
|
133
|
+
const result = await taskService.findTasks({
|
|
134
|
+
taskId,
|
|
135
|
+
taskName,
|
|
136
|
+
listName,
|
|
137
|
+
allowMultipleMatches: false,
|
|
138
|
+
useSmartDisambiguation: true,
|
|
139
|
+
includeFullDetails: false
|
|
140
|
+
});
|
|
141
|
+
if (!result || Array.isArray(result)) {
|
|
142
|
+
throw new Error("Task not found");
|
|
143
|
+
}
|
|
144
|
+
const resolvedTaskId = result.id;
|
|
117
145
|
try {
|
|
118
146
|
// CASE 1: Chunked upload continuation
|
|
119
147
|
if (session_id) {
|
|
@@ -254,7 +282,8 @@ async function handleChunkUpload(taskId, sessionToken, chunkIndex, chunkData, is
|
|
|
254
282
|
// Sort chunks by index
|
|
255
283
|
const sortedChunks = Array.from(session.chunks.entries())
|
|
256
284
|
.sort((a, b) => a[0] - b[0]);
|
|
257
|
-
for (const
|
|
285
|
+
for (const entry of sortedChunks) {
|
|
286
|
+
const [index, chunk] = entry;
|
|
258
287
|
chunk.copy(fileData, offset);
|
|
259
288
|
offset += chunk.length;
|
|
260
289
|
}
|
|
@@ -76,28 +76,21 @@ export const createBulkTasksTool = {
|
|
|
76
76
|
description: `Purpose: Create multiple tasks in a list efficiently.
|
|
77
77
|
|
|
78
78
|
Valid Usage:
|
|
79
|
-
1.
|
|
80
|
-
2.
|
|
79
|
+
1. Provide listId + array of tasks (preferred)
|
|
80
|
+
2. Provide listName + array of tasks
|
|
81
81
|
|
|
82
82
|
Requirements:
|
|
83
83
|
- tasks: REQUIRED (array of tasks, each with at least a name)
|
|
84
84
|
- EITHER listId OR listName: REQUIRED
|
|
85
|
+
- All tasks will be created in the specified list
|
|
85
86
|
|
|
86
87
|
Notes:
|
|
87
88
|
- Configure batch size and concurrency via options for performance
|
|
88
89
|
- Each task should have a name with emoji prefix
|
|
89
|
-
-
|
|
90
|
+
- Custom fields can be set for each task using the custom_fields property (array of {id, value} objects)`,
|
|
90
91
|
inputSchema: {
|
|
91
92
|
type: "object",
|
|
92
93
|
properties: {
|
|
93
|
-
listId: {
|
|
94
|
-
type: "string",
|
|
95
|
-
description: "ID of list for new tasks (preferred). Use this instead of listName if you have it."
|
|
96
|
-
},
|
|
97
|
-
listName: {
|
|
98
|
-
type: "string",
|
|
99
|
-
description: "Name of list for new tasks. Only use if you don't have listId."
|
|
100
|
-
},
|
|
101
94
|
tasks: {
|
|
102
95
|
type: "array",
|
|
103
96
|
description: "Array of tasks to create. Each task must have at least a name.",
|
|
@@ -134,18 +127,43 @@ Notes:
|
|
|
134
127
|
type: "string"
|
|
135
128
|
},
|
|
136
129
|
description: "Optional array of tag names to assign to the task. The tags must already exist in the space."
|
|
130
|
+
},
|
|
131
|
+
custom_fields: {
|
|
132
|
+
type: "array",
|
|
133
|
+
items: {
|
|
134
|
+
type: "object",
|
|
135
|
+
properties: {
|
|
136
|
+
id: {
|
|
137
|
+
type: "string",
|
|
138
|
+
description: "ID of the custom field"
|
|
139
|
+
},
|
|
140
|
+
value: {
|
|
141
|
+
description: "Value for the custom field. Type depends on the field type."
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
required: ["id", "value"]
|
|
145
|
+
},
|
|
146
|
+
description: "Optional array of custom field values to set on the task."
|
|
137
147
|
}
|
|
138
148
|
},
|
|
139
149
|
required: ["name"]
|
|
140
150
|
}
|
|
141
151
|
},
|
|
152
|
+
listId: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "ID of list for new tasks (preferred). Use this instead of listName if you have it."
|
|
155
|
+
},
|
|
156
|
+
listName: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "Name of list for new tasks. Only use if you don't have listId."
|
|
159
|
+
},
|
|
142
160
|
options: bulkOptionsSchema
|
|
143
161
|
},
|
|
144
162
|
required: ["tasks"]
|
|
145
163
|
}
|
|
146
164
|
};
|
|
147
165
|
/**
|
|
148
|
-
* Tool definition for updating multiple tasks
|
|
166
|
+
* Tool definition for updating multiple tasks efficiently
|
|
149
167
|
*/
|
|
150
168
|
export const updateBulkTasksTool = {
|
|
151
169
|
name: "update_bulk_tasks",
|
|
@@ -163,7 +181,11 @@ Requirements:
|
|
|
163
181
|
Notes:
|
|
164
182
|
- Only specified fields will be updated for each task
|
|
165
183
|
- Configure batch size and concurrency via options for performance
|
|
166
|
-
- Each task can have different fields to update
|
|
184
|
+
- Each task can have different fields to update
|
|
185
|
+
- Custom fields can be updated using the custom_fields property (array of {id, value} objects)
|
|
186
|
+
|
|
187
|
+
Warning:
|
|
188
|
+
- Using taskName without listName will fail as tasks may have identical names across lists`,
|
|
167
189
|
inputSchema: {
|
|
168
190
|
type: "object",
|
|
169
191
|
properties: {
|
|
@@ -173,7 +195,22 @@ Notes:
|
|
|
173
195
|
items: {
|
|
174
196
|
type: "object",
|
|
175
197
|
properties: {
|
|
176
|
-
|
|
198
|
+
taskId: {
|
|
199
|
+
type: "string",
|
|
200
|
+
description: "Task ID (preferred). Works with both regular task IDs (9 characters) and custom IDs with uppercase prefixes (like 'DEV-1234')."
|
|
201
|
+
},
|
|
202
|
+
taskName: {
|
|
203
|
+
type: "string",
|
|
204
|
+
description: "Task name. Requires listName when used."
|
|
205
|
+
},
|
|
206
|
+
listName: {
|
|
207
|
+
type: "string",
|
|
208
|
+
description: "REQUIRED with taskName: List containing the task."
|
|
209
|
+
},
|
|
210
|
+
customTaskId: {
|
|
211
|
+
type: "string",
|
|
212
|
+
description: "Custom task ID (e.g., 'DEV-1234'). Only use if you want to explicitly force custom ID lookup. In most cases, use taskId which auto-detects ID format."
|
|
213
|
+
},
|
|
177
214
|
name: {
|
|
178
215
|
type: "string",
|
|
179
216
|
description: "New name with emoji prefix"
|
|
@@ -198,6 +235,23 @@ Notes:
|
|
|
198
235
|
dueDate: {
|
|
199
236
|
type: "string",
|
|
200
237
|
description: "New due date. Supports Unix timestamps (in milliseconds) and natural language expressions like '1 hour from now', 'tomorrow', etc."
|
|
238
|
+
},
|
|
239
|
+
custom_fields: {
|
|
240
|
+
type: "array",
|
|
241
|
+
items: {
|
|
242
|
+
type: "object",
|
|
243
|
+
properties: {
|
|
244
|
+
id: {
|
|
245
|
+
type: "string",
|
|
246
|
+
description: "ID of the custom field"
|
|
247
|
+
},
|
|
248
|
+
value: {
|
|
249
|
+
description: "Value for the custom field. Type depends on the field type."
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
required: ["id", "value"]
|
|
253
|
+
},
|
|
254
|
+
description: "Optional array of custom field values to set on the task."
|
|
201
255
|
}
|
|
202
256
|
}
|
|
203
257
|
}
|
|
@@ -227,7 +281,7 @@ Notes:
|
|
|
227
281
|
- Configure batch size and concurrency via options for performance
|
|
228
282
|
- All tasks will be moved to the same destination list
|
|
229
283
|
|
|
230
|
-
|
|
284
|
+
Warning:
|
|
231
285
|
- Task statuses may reset if destination list has different status options
|
|
232
286
|
- Using taskName without listName will fail as tasks may have identical names across lists`,
|
|
233
287
|
inputSchema: {
|
|
@@ -239,7 +293,22 @@ Notes:
|
|
|
239
293
|
items: {
|
|
240
294
|
type: "object",
|
|
241
295
|
properties: {
|
|
242
|
-
|
|
296
|
+
taskId: {
|
|
297
|
+
type: "string",
|
|
298
|
+
description: "Task ID (preferred). Works with both regular task IDs (9 characters) and custom IDs with uppercase prefixes (like 'DEV-1234')."
|
|
299
|
+
},
|
|
300
|
+
taskName: {
|
|
301
|
+
type: "string",
|
|
302
|
+
description: "Task name. Requires listName when used."
|
|
303
|
+
},
|
|
304
|
+
listName: {
|
|
305
|
+
type: "string",
|
|
306
|
+
description: "REQUIRED with taskName: List containing the task."
|
|
307
|
+
},
|
|
308
|
+
customTaskId: {
|
|
309
|
+
type: "string",
|
|
310
|
+
description: "Custom task ID (e.g., 'DEV-1234'). Only use if you want to explicitly force custom ID lookup. In most cases, use taskId which auto-detects ID format."
|
|
311
|
+
}
|
|
243
312
|
}
|
|
244
313
|
}
|
|
245
314
|
},
|
|
@@ -274,7 +343,7 @@ Requirements:
|
|
|
274
343
|
Notes:
|
|
275
344
|
- Configure batch size and concurrency via options for performance
|
|
276
345
|
|
|
277
|
-
|
|
346
|
+
Warning:
|
|
278
347
|
- This action CANNOT be undone for any of the tasks
|
|
279
348
|
- Using taskName without listName is dangerous as names may not be unique
|
|
280
349
|
- Always provide listName when using taskName for safer targeting`,
|
|
@@ -287,7 +356,22 @@ Notes:
|
|
|
287
356
|
items: {
|
|
288
357
|
type: "object",
|
|
289
358
|
properties: {
|
|
290
|
-
|
|
359
|
+
taskId: {
|
|
360
|
+
type: "string",
|
|
361
|
+
description: "Task ID (preferred). Works with both regular task IDs (9 characters) and custom IDs with uppercase prefixes (like 'DEV-1234')."
|
|
362
|
+
},
|
|
363
|
+
taskName: {
|
|
364
|
+
type: "string",
|
|
365
|
+
description: "Task name. Requires listName when used."
|
|
366
|
+
},
|
|
367
|
+
listName: {
|
|
368
|
+
type: "string",
|
|
369
|
+
description: "REQUIRED with taskName: List containing the task."
|
|
370
|
+
},
|
|
371
|
+
customTaskId: {
|
|
372
|
+
type: "string",
|
|
373
|
+
description: "Custom task ID (e.g., 'DEV-1234'). Only use if you want to explicitly force custom ID lookup. In most cases, use taskId which auto-detects ID format."
|
|
374
|
+
}
|
|
291
375
|
}
|
|
292
376
|
}
|
|
293
377
|
},
|