@taazkareem/clickup-mcp-server 0.4.75 → 0.5.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 +25 -7
- package/build/index.js +0 -6
- package/build/server.js +9 -3
- package/build/services/clickup/task.js +141 -0
- package/build/tools/task/attachments.js +354 -0
- package/build/tools/task/handlers.js +30 -0
- package/build/tools/task/index.js +4 -2
- package/build/tools/task/main.js +11 -2
- package/build/tools/task/single-operations.js +50 -0
- package/build/utils/date-utils.js +18 -7
- package/package.json +4 -4
- package/build/mcp-tools.js +0 -64
- package/build/server-state.js +0 -93
- package/build/server.log +0 -164
- 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
|
@@ -156,6 +156,36 @@ export async function getTaskCommentsHandler(params) {
|
|
|
156
156
|
const { start, startId } = params;
|
|
157
157
|
return await taskService.getTaskComments(taskId, start, startId);
|
|
158
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Handler for creating a task comment
|
|
161
|
+
*/
|
|
162
|
+
export async function createTaskCommentHandler(params) {
|
|
163
|
+
// Validate required parameters
|
|
164
|
+
if (!params.commentText) {
|
|
165
|
+
throw new Error('Comment text is required');
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
// Resolve the task ID
|
|
169
|
+
const taskId = await getTaskId(params.taskId, params.taskName, params.listName);
|
|
170
|
+
// Extract other parameters with defaults
|
|
171
|
+
const { commentText, notifyAll = false, assignee = null } = params;
|
|
172
|
+
// Create the comment
|
|
173
|
+
return await taskService.createTaskComment(taskId, commentText, notifyAll, assignee);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
// If this is a task lookup error, provide more helpful message
|
|
177
|
+
if (error.message?.includes('not found') || error.message?.includes('identify task')) {
|
|
178
|
+
if (params.taskName) {
|
|
179
|
+
throw new Error(`Could not find task "${params.taskName}" in list "${params.listName}"`);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
throw new Error(`Task with ID "${params.taskId}" not found`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Otherwise, rethrow the original error
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
159
189
|
//=============================================================================
|
|
160
190
|
// BULK TASK OPERATIONS
|
|
161
191
|
//=============================================================================
|
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
// Re-export from main module
|
|
7
7
|
export * from './main.js';
|
|
8
8
|
// Re-export single task operation tools
|
|
9
|
-
export { createTaskTool, getTaskTool, getTasksTool, updateTaskTool, moveTaskTool, duplicateTaskTool, deleteTaskTool, getTaskCommentsTool } from './single-operations.js';
|
|
9
|
+
export { createTaskTool, getTaskTool, getTasksTool, updateTaskTool, moveTaskTool, duplicateTaskTool, deleteTaskTool, getTaskCommentsTool, createTaskCommentTool } from './single-operations.js';
|
|
10
10
|
// Re-export bulk task operation tools
|
|
11
11
|
export { createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool } from './bulk-operations.js';
|
|
12
|
+
// Re-export attachment tool
|
|
13
|
+
export { attachTaskFileTool, handleAttachTaskFile } from './attachments.js';
|
|
12
14
|
// Re-export handlers
|
|
13
15
|
export {
|
|
14
16
|
// Single task operation handlers
|
|
15
|
-
createTaskHandler, getTaskHandler, getTasksHandler, updateTaskHandler, moveTaskHandler, duplicateTaskHandler, deleteTaskHandler, getTaskCommentsHandler,
|
|
17
|
+
createTaskHandler, getTaskHandler, getTasksHandler, updateTaskHandler, moveTaskHandler, duplicateTaskHandler, deleteTaskHandler, getTaskCommentsHandler, createTaskCommentHandler,
|
|
16
18
|
// Bulk task operation handlers
|
|
17
19
|
createBulkTasksHandler, updateBulkTasksHandler, moveBulkTasksHandler, deleteBulkTasksHandler } from './handlers.js';
|
|
18
20
|
// Re-export utilities
|
package/build/tools/task/main.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { sponsorService } from '../../utils/sponsor-service.js';
|
|
8
8
|
// Import tool definitions
|
|
9
|
-
import { createTaskTool, getTaskTool, getTasksTool, updateTaskTool, moveTaskTool, duplicateTaskTool, deleteTaskTool, getTaskCommentsTool } from './single-operations.js';
|
|
9
|
+
import { createTaskTool, getTaskTool, getTasksTool, updateTaskTool, moveTaskTool, duplicateTaskTool, deleteTaskTool, getTaskCommentsTool, createTaskCommentTool } from './single-operations.js';
|
|
10
10
|
import { createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool } from './bulk-operations.js';
|
|
11
11
|
// Import handlers
|
|
12
|
-
import { createTaskHandler, getTaskHandler, getTasksHandler, updateTaskHandler, moveTaskHandler, duplicateTaskHandler, deleteTaskHandler, getTaskCommentsHandler, createBulkTasksHandler, updateBulkTasksHandler, moveBulkTasksHandler, deleteBulkTasksHandler } from './handlers.js';
|
|
12
|
+
import { createTaskHandler, getTaskHandler, getTasksHandler, updateTaskHandler, moveTaskHandler, duplicateTaskHandler, deleteTaskHandler, getTaskCommentsHandler, createTaskCommentHandler, createBulkTasksHandler, updateBulkTasksHandler, moveBulkTasksHandler, deleteBulkTasksHandler } from './handlers.js';
|
|
13
13
|
//=============================================================================
|
|
14
14
|
// HANDLER WRAPPER UTILITY
|
|
15
15
|
//=============================================================================
|
|
@@ -47,6 +47,14 @@ export const handleGetTaskComments = createHandlerWrapper(getTaskCommentsHandler
|
|
|
47
47
|
comments,
|
|
48
48
|
count: comments.length
|
|
49
49
|
}));
|
|
50
|
+
export const handleCreateTaskComment = createHandlerWrapper(createTaskCommentHandler, (comment) => ({
|
|
51
|
+
success: true,
|
|
52
|
+
message: "Comment added successfully",
|
|
53
|
+
comment: comment && typeof comment === 'object' ? comment : {
|
|
54
|
+
id: `generated-${Date.now()}`,
|
|
55
|
+
comment_text: typeof comment === 'string' ? comment : "Comment text unavailable"
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
50
58
|
//=============================================================================
|
|
51
59
|
// BULK TASK OPERATIONS - HANDLER IMPLEMENTATIONS
|
|
52
60
|
//=============================================================================
|
|
@@ -81,6 +89,7 @@ export const taskTools = [
|
|
|
81
89
|
{ definition: duplicateTaskTool, handler: handleDuplicateTask },
|
|
82
90
|
{ definition: deleteTaskTool, handler: handleDeleteTask },
|
|
83
91
|
{ definition: getTaskCommentsTool, handler: handleGetTaskComments },
|
|
92
|
+
{ definition: createTaskCommentTool, handler: handleCreateTaskComment },
|
|
84
93
|
// Bulk task operations
|
|
85
94
|
{ definition: createBulkTasksTool, handler: handleCreateBulkTasks },
|
|
86
95
|
{ definition: updateBulkTasksTool, handler: handleUpdateBulkTasks },
|
|
@@ -427,3 +427,53 @@ Notes:
|
|
|
427
427
|
}
|
|
428
428
|
}
|
|
429
429
|
};
|
|
430
|
+
/**
|
|
431
|
+
* Tool definition for creating a comment on a task
|
|
432
|
+
*/
|
|
433
|
+
export const createTaskCommentTool = {
|
|
434
|
+
name: "create_task_comment",
|
|
435
|
+
description: `Purpose: Create a comment on a ClickUp task.
|
|
436
|
+
|
|
437
|
+
Valid Usage:
|
|
438
|
+
1. Use taskId (preferred)
|
|
439
|
+
2. Use taskName + listName
|
|
440
|
+
|
|
441
|
+
Requirements:
|
|
442
|
+
- EITHER taskId OR (taskName + listName) is REQUIRED
|
|
443
|
+
- commentText is REQUIRED
|
|
444
|
+
|
|
445
|
+
Notes:
|
|
446
|
+
- When using taskName, providing listName helps locate the correct task
|
|
447
|
+
- Set notifyAll to true to send notifications to all task assignees
|
|
448
|
+
- Use assignee to assign the comment to a specific user (optional)`,
|
|
449
|
+
inputSchema: {
|
|
450
|
+
type: "object",
|
|
451
|
+
properties: {
|
|
452
|
+
taskId: {
|
|
453
|
+
type: "string",
|
|
454
|
+
description: "ID of task to comment on (preferred). Works with both regular task IDs (9 characters) and custom IDs with uppercase prefixes (like 'DEV-1234')."
|
|
455
|
+
},
|
|
456
|
+
taskName: {
|
|
457
|
+
type: "string",
|
|
458
|
+
description: "Name of task to comment on. When using this parameter, you MUST also provide listName."
|
|
459
|
+
},
|
|
460
|
+
listName: {
|
|
461
|
+
type: "string",
|
|
462
|
+
description: "Name of list containing the task. REQUIRED when using taskName."
|
|
463
|
+
},
|
|
464
|
+
commentText: {
|
|
465
|
+
type: "string",
|
|
466
|
+
description: "REQUIRED: Text content of the comment to create."
|
|
467
|
+
},
|
|
468
|
+
notifyAll: {
|
|
469
|
+
type: "boolean",
|
|
470
|
+
description: "Whether to notify all assignees. Default is false."
|
|
471
|
+
},
|
|
472
|
+
assignee: {
|
|
473
|
+
type: "number",
|
|
474
|
+
description: "Optional user ID to assign the comment to."
|
|
475
|
+
}
|
|
476
|
+
},
|
|
477
|
+
required: ["commentText"]
|
|
478
|
+
}
|
|
479
|
+
};
|
|
@@ -6,14 +6,17 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* Get a timestamp for a relative time
|
|
8
8
|
*
|
|
9
|
+
* @param minutes Minutes from now
|
|
9
10
|
* @param hours Hours from now
|
|
10
11
|
* @param days Days from now
|
|
11
12
|
* @param weeks Weeks from now
|
|
12
13
|
* @param months Months from now
|
|
13
14
|
* @returns Timestamp in milliseconds
|
|
14
15
|
*/
|
|
15
|
-
export function getRelativeTimestamp(hours = 0, days = 0, weeks = 0, months = 0) {
|
|
16
|
+
export function getRelativeTimestamp(minutes = 0, hours = 0, days = 0, weeks = 0, months = 0) {
|
|
16
17
|
const now = new Date();
|
|
18
|
+
if (minutes)
|
|
19
|
+
now.setMinutes(now.getMinutes() + minutes);
|
|
17
20
|
if (hours)
|
|
18
21
|
now.setHours(now.getHours() + hours);
|
|
19
22
|
if (days)
|
|
@@ -44,7 +47,7 @@ export function parseDueDate(dateString) {
|
|
|
44
47
|
return today.getTime();
|
|
45
48
|
}
|
|
46
49
|
// Handle relative dates with specific times
|
|
47
|
-
const relativeTimeRegex = /(?:(\d+)\s*(days?|weeks?|months?)\s*from\s*now|tomorrow|next\s+(?:week|month))\s*(?:at\s+(\d+)(?::(\d+))?\s*(am|pm)?)?/i;
|
|
50
|
+
const relativeTimeRegex = /(?:(\d+)\s*(minutes?|days?|weeks?|months?)\s*from\s*now|tomorrow|next\s+(?:week|month))\s*(?:at\s+(\d+)(?::(\d+))?\s*(am|pm)?)?/i;
|
|
48
51
|
const match = lowerDate.match(relativeTimeRegex);
|
|
49
52
|
if (match) {
|
|
50
53
|
const date = new Date();
|
|
@@ -52,7 +55,10 @@ export function parseDueDate(dateString) {
|
|
|
52
55
|
// Calculate the future date
|
|
53
56
|
if (amount && unit) {
|
|
54
57
|
const value = parseInt(amount);
|
|
55
|
-
if (unit.startsWith('
|
|
58
|
+
if (unit.startsWith('minute')) {
|
|
59
|
+
date.setMinutes(date.getMinutes() + value);
|
|
60
|
+
}
|
|
61
|
+
else if (unit.startsWith('day')) {
|
|
56
62
|
date.setDate(date.getDate() + value);
|
|
57
63
|
}
|
|
58
64
|
else if (unit.startsWith('week')) {
|
|
@@ -89,25 +95,30 @@ export function parseDueDate(dateString) {
|
|
|
89
95
|
return date.getTime();
|
|
90
96
|
}
|
|
91
97
|
// Handle hours from now
|
|
98
|
+
const minutesRegex = /(\d+)\s*minutes?\s*from\s*now/i;
|
|
92
99
|
const hoursRegex = /(\d+)\s*hours?\s*from\s*now/i;
|
|
93
100
|
const daysRegex = /(\d+)\s*days?\s*from\s*now/i;
|
|
94
101
|
const weeksRegex = /(\d+)\s*weeks?\s*from\s*now/i;
|
|
95
102
|
const monthsRegex = /(\d+)\s*months?\s*from\s*now/i;
|
|
103
|
+
if (minutesRegex.test(lowerDate)) {
|
|
104
|
+
const minutes = parseInt(lowerDate.match(minutesRegex)[1]);
|
|
105
|
+
return getRelativeTimestamp(minutes);
|
|
106
|
+
}
|
|
96
107
|
if (hoursRegex.test(lowerDate)) {
|
|
97
108
|
const hours = parseInt(lowerDate.match(hoursRegex)[1]);
|
|
98
|
-
return getRelativeTimestamp(hours);
|
|
109
|
+
return getRelativeTimestamp(0, hours);
|
|
99
110
|
}
|
|
100
111
|
if (daysRegex.test(lowerDate)) {
|
|
101
112
|
const days = parseInt(lowerDate.match(daysRegex)[1]);
|
|
102
|
-
return getRelativeTimestamp(0, days);
|
|
113
|
+
return getRelativeTimestamp(0, 0, days);
|
|
103
114
|
}
|
|
104
115
|
if (weeksRegex.test(lowerDate)) {
|
|
105
116
|
const weeks = parseInt(lowerDate.match(weeksRegex)[1]);
|
|
106
|
-
return getRelativeTimestamp(0, 0, weeks);
|
|
117
|
+
return getRelativeTimestamp(0, 0, 0, weeks);
|
|
107
118
|
}
|
|
108
119
|
if (monthsRegex.test(lowerDate)) {
|
|
109
120
|
const months = parseInt(lowerDate.match(monthsRegex)[1]);
|
|
110
|
-
return getRelativeTimestamp(0, 0, 0, months);
|
|
121
|
+
return getRelativeTimestamp(0, 0, 0, 0, months);
|
|
111
122
|
}
|
|
112
123
|
// Try to parse as a date string
|
|
113
124
|
const date = new Date(dateString);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taazkareem/clickup-mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "ClickUp MCP Server - Integrate ClickUp tasks with AI through Model Context Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
},
|
|
56
56
|
"homepage": "https://github.com/taazkareem/clickup-mcp-server#readme",
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@modelcontextprotocol/sdk": "0.6.0",
|
|
59
|
-
"axios": "1.6.7",
|
|
60
|
-
"dotenv": "16.4.1"
|
|
58
|
+
"@modelcontextprotocol/sdk": "^0.6.0",
|
|
59
|
+
"axios": "^1.6.7",
|
|
60
|
+
"dotenv": "^16.4.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/node": "^20.11.16",
|
package/build/mcp-tools.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { Logger } from "./logger.js";
|
|
2
|
-
// Create a logger instance
|
|
3
|
-
const logger = new Logger('MCPTools');
|
|
4
|
-
/**
|
|
5
|
-
* Register a handler for a tool that may receive JSON string parameters
|
|
6
|
-
* This wrapper ensures that array and object parameters are properly parsed
|
|
7
|
-
*
|
|
8
|
-
* @param server MCP Server instance
|
|
9
|
-
* @param name Tool name
|
|
10
|
-
* @param handler Handler function
|
|
11
|
-
*/
|
|
12
|
-
export function registerToolHandler(server, name, handler) {
|
|
13
|
-
// Create a wrapper handler that pre-processes parameters
|
|
14
|
-
const wrappedHandler = async (params) => {
|
|
15
|
-
logger.debug(`Processing parameters for tool ${name}`, { params });
|
|
16
|
-
try {
|
|
17
|
-
// Process the parameters before passing them to the actual handler
|
|
18
|
-
const processedParams = {};
|
|
19
|
-
// Process each parameter - try to parse strings that might be JSON
|
|
20
|
-
for (const [key, value] of Object.entries(params)) {
|
|
21
|
-
if (typeof value === 'string') {
|
|
22
|
-
try {
|
|
23
|
-
// Check if this might be a JSON array or object
|
|
24
|
-
if ((value.startsWith('[') && value.endsWith(']')) ||
|
|
25
|
-
(value.startsWith('{') && value.endsWith('}'))) {
|
|
26
|
-
try {
|
|
27
|
-
processedParams[key] = JSON.parse(value);
|
|
28
|
-
logger.debug(`Parsed JSON parameter: ${key}`, { original: value, parsed: processedParams[key] });
|
|
29
|
-
}
|
|
30
|
-
catch (parseError) {
|
|
31
|
-
// If parsing fails, use the original string
|
|
32
|
-
processedParams[key] = value;
|
|
33
|
-
logger.debug(`Failed to parse JSON for parameter: ${key}, using original`, { error: parseError.message });
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
processedParams[key] = value;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
// If there's any error, use the original value
|
|
42
|
-
processedParams[key] = value;
|
|
43
|
-
logger.debug(`Error processing parameter: ${key}`, { error: error.message });
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
// Non-string values are used as-is
|
|
48
|
-
processedParams[key] = value;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
logger.debug(`Processed parameters for tool ${name}`, { processedParams });
|
|
52
|
-
// Call the original handler with processed parameters
|
|
53
|
-
return handler(processedParams);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
logger.error(`Error in wrapped handler for tool ${name}:`, { error: error.stack || error.message });
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
// Use setRequestHandler to register the wrapped handler
|
|
61
|
-
logger.info(`Registering wrapped handler for tool: ${name}`);
|
|
62
|
-
// Override the tool's handler in the CallTool switch statement
|
|
63
|
-
// The server.ts file will use the switch case to call this handler
|
|
64
|
-
}
|
package/build/server-state.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server State Management Module
|
|
3
|
-
*
|
|
4
|
-
* This module provides shared state management for the MCP server,
|
|
5
|
-
* particularly for controlling shutdown behavior and tracking busy states.
|
|
6
|
-
*/
|
|
7
|
-
// State variables
|
|
8
|
-
let serverBusyState = false; // Tracks if server is doing critical work
|
|
9
|
-
let gracePeriodActive = false; // Tracks if we're in post-initialization grace period
|
|
10
|
-
let gracePeriodTimer = null;
|
|
11
|
-
export const GRACE_PERIOD_MS = 10000; // 10 second grace period after startup
|
|
12
|
-
/**
|
|
13
|
-
* Logging helper that avoids circular dependency
|
|
14
|
-
*/
|
|
15
|
-
function safeLog(level, message, data) {
|
|
16
|
-
// Use console as a fallback to avoid circular dependency with logger
|
|
17
|
-
const timestamp = new Date().toISOString();
|
|
18
|
-
if (level === 'error') {
|
|
19
|
-
console.error(`[${timestamp}] ${level.toUpperCase()}: ${message}`, data || '');
|
|
20
|
-
}
|
|
21
|
-
else if (level === 'debug' && process.env.DEBUG) {
|
|
22
|
-
console.debug(`[${timestamp}] ${level.toUpperCase()}: ${message}`, data || '');
|
|
23
|
-
}
|
|
24
|
-
else if (level !== 'debug') {
|
|
25
|
-
console.log(`[${timestamp}] ${level.toUpperCase()}: ${message}`, data || '');
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Set the server as busy doing critical work that shouldn't be interrupted
|
|
30
|
-
* @param busy Whether the server is currently busy with critical operations
|
|
31
|
-
*/
|
|
32
|
-
export function setServerBusy(busy) {
|
|
33
|
-
serverBusyState = busy;
|
|
34
|
-
safeLog('debug', `Server busy state set to: ${busy}`);
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Start grace period after initialization to prevent immediate shutdown
|
|
38
|
-
*/
|
|
39
|
-
export function startGracePeriod() {
|
|
40
|
-
gracePeriodActive = true;
|
|
41
|
-
safeLog('debug', `Starting ${GRACE_PERIOD_MS}ms grace period to prevent premature shutdown`);
|
|
42
|
-
if (gracePeriodTimer) {
|
|
43
|
-
clearTimeout(gracePeriodTimer);
|
|
44
|
-
}
|
|
45
|
-
gracePeriodTimer = setTimeout(() => {
|
|
46
|
-
gracePeriodActive = false;
|
|
47
|
-
safeLog('debug', 'Grace period ended, server will now respond to shutdown signals');
|
|
48
|
-
gracePeriodTimer = null;
|
|
49
|
-
}, GRACE_PERIOD_MS);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Cancel the grace period if needed
|
|
53
|
-
*/
|
|
54
|
-
export function cancelGracePeriod() {
|
|
55
|
-
if (gracePeriodTimer) {
|
|
56
|
-
clearTimeout(gracePeriodTimer);
|
|
57
|
-
gracePeriodTimer = null;
|
|
58
|
-
}
|
|
59
|
-
gracePeriodActive = false;
|
|
60
|
-
safeLog('debug', 'Grace period canceled, server will now respond to shutdown signals');
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Check if the server should ignore shutdown signals
|
|
64
|
-
* @returns true if shutdown signals should be ignored
|
|
65
|
-
*/
|
|
66
|
-
export function shouldIgnoreShutdown() {
|
|
67
|
-
// Ignore shutdown if explicitly configured via environment variable
|
|
68
|
-
if (process.env.FORCE_KEEP_ALIVE === 'true') {
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
// Ignore shutdown during the grace period after startup
|
|
72
|
-
if (gracePeriodActive) {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
// Ignore shutdown if the server is doing critical work
|
|
76
|
-
if (serverBusyState) {
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
// Otherwise, allow normal shutdown
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Check if grace period is currently active
|
|
84
|
-
*/
|
|
85
|
-
export function isGracePeriodActive() {
|
|
86
|
-
return gracePeriodActive;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Check if server is currently in busy state
|
|
90
|
-
*/
|
|
91
|
-
export function isServerBusy() {
|
|
92
|
-
return serverBusyState;
|
|
93
|
-
}
|
package/build/server.log
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
[2025-03-21T18:53:07.767Z] [PID:44431] INFO: [SponsorService] SponsorService initialized
|
|
2
|
-
{
|
|
3
|
-
"enabled": true
|
|
4
|
-
}
|
|
5
|
-
[2025-03-21T18:53:07.789Z] [PID:44431] INFO: [SharedServices] Creating shared ClickUp services singleton
|
|
6
|
-
[2025-03-21T18:53:07.790Z] [PID:44431] INFO: [ClickUpServices] Starting ClickUp services initialization
|
|
7
|
-
{
|
|
8
|
-
"teamId": "9014370478",
|
|
9
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
10
|
-
}
|
|
11
|
-
[2025-03-21T18:53:07.790Z] [PID:44431] INFO: [ClickUpServices] Initializing ClickUp Workspace service
|
|
12
|
-
[2025-03-21T18:53:07.792Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Initialized WorkspaceService
|
|
13
|
-
{
|
|
14
|
-
"teamId": "9014370478",
|
|
15
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
16
|
-
}
|
|
17
|
-
[2025-03-21T18:53:07.792Z] [PID:44431] INFO: [ClickUpServices] Initializing ClickUp Task service
|
|
18
|
-
[2025-03-21T18:53:07.792Z] [PID:44431] DEBUG: [ClickUp:TaskService] Initialized TaskService
|
|
19
|
-
{
|
|
20
|
-
"teamId": "9014370478",
|
|
21
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
22
|
-
}
|
|
23
|
-
[2025-03-21T18:53:07.792Z] [PID:44431] INFO: [ClickUp:TaskService] Operation: constructor
|
|
24
|
-
{
|
|
25
|
-
"usingSharedWorkspaceService": true
|
|
26
|
-
}
|
|
27
|
-
[2025-03-21T18:53:07.793Z] [PID:44431] DEBUG: [ClickUp:ListService] Initialized ListService
|
|
28
|
-
{
|
|
29
|
-
"teamId": "9014370478",
|
|
30
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
31
|
-
}
|
|
32
|
-
[2025-03-21T18:53:07.793Z] [PID:44431] INFO: [ClickUp:TaskService] Operation: constructor
|
|
33
|
-
{
|
|
34
|
-
"initialized": true
|
|
35
|
-
}
|
|
36
|
-
[2025-03-21T18:53:07.793Z] [PID:44431] INFO: [ClickUpServices] Initializing ClickUp List service
|
|
37
|
-
[2025-03-21T18:53:07.793Z] [PID:44431] DEBUG: [ClickUp:ListService] Initialized ListService
|
|
38
|
-
{
|
|
39
|
-
"teamId": "9014370478",
|
|
40
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
41
|
-
}
|
|
42
|
-
[2025-03-21T18:53:07.794Z] [PID:44431] INFO: [ClickUpServices] Initializing ClickUp Folder service
|
|
43
|
-
[2025-03-21T18:53:07.794Z] [PID:44431] DEBUG: [ClickUp:FolderService] Initialized FolderService
|
|
44
|
-
{
|
|
45
|
-
"teamId": "9014370478",
|
|
46
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
47
|
-
}
|
|
48
|
-
[2025-03-21T18:53:07.794Z] [PID:44431] INFO: [ClickUpServices] All ClickUp services initialized successfully
|
|
49
|
-
{
|
|
50
|
-
"services": [
|
|
51
|
-
"workspace",
|
|
52
|
-
"task",
|
|
53
|
-
"list",
|
|
54
|
-
"folder"
|
|
55
|
-
],
|
|
56
|
-
"baseUrl": "https://api.clickup.com/api/v2"
|
|
57
|
-
}
|
|
58
|
-
[2025-03-21T18:53:07.794Z] [PID:44431] INFO: [SharedServices] Services initialization complete
|
|
59
|
-
{
|
|
60
|
-
"services": "workspace, task, list, folder",
|
|
61
|
-
"teamId": "9014370478"
|
|
62
|
-
}
|
|
63
|
-
[2025-03-21T18:53:07.794Z] [PID:44431] INFO: [BulkService] BulkService initialized
|
|
64
|
-
[2025-03-21T18:53:07.795Z] [PID:44431] INFO: [BulkService] BulkService initialized
|
|
65
|
-
[2025-03-21T18:53:07.795Z] [PID:44431] INFO: Starting ClickUp MCP Server...
|
|
66
|
-
[2025-03-21T18:53:08.317Z] [PID:44431] INFO: Server environment
|
|
67
|
-
{
|
|
68
|
-
"pid": 44431,
|
|
69
|
-
"node": "v23.5.0",
|
|
70
|
-
"os": "darwin",
|
|
71
|
-
"arch": "x64"
|
|
72
|
-
}
|
|
73
|
-
[2025-03-21T18:53:08.318Z] [PID:44431] INFO: Initializing workspace tools
|
|
74
|
-
[2025-03-21T18:53:08.318Z] [PID:44431] INFO: [WorkspaceTool] Initializing workspace tool
|
|
75
|
-
[2025-03-21T18:53:08.318Z] [PID:44431] INFO: [WorkspaceTool] Workspace tool initialized successfully
|
|
76
|
-
{
|
|
77
|
-
"serviceType": "WorkspaceService"
|
|
78
|
-
}
|
|
79
|
-
[2025-03-21T18:53:08.318Z] [PID:44431] INFO: Configuring server request handlers
|
|
80
|
-
[2025-03-21T18:53:08.319Z] [PID:44431] INFO: [Server] Registering server request handlers
|
|
81
|
-
[2025-03-21T18:53:08.319Z] [PID:44431] INFO: [Server] Registering tool handlers
|
|
82
|
-
{
|
|
83
|
-
"toolCount": 22,
|
|
84
|
-
"categories": [
|
|
85
|
-
"workspace",
|
|
86
|
-
"task",
|
|
87
|
-
"list",
|
|
88
|
-
"folder"
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
[2025-03-21T18:53:08.319Z] [PID:44431] INFO: Connecting to MCP stdio transport
|
|
92
|
-
[2025-03-21T18:53:08.319Z] [PID:44431] INFO: Server startup complete - ready to handle requests
|
|
93
|
-
[2025-03-21T18:53:08.337Z] [PID:44431] DEBUG: [Server] Received ListTools request
|
|
94
|
-
[2025-03-21T18:53:15.519Z] [PID:44431] INFO: [Server] Received CallTool request for tool: get_workspace_hierarchy
|
|
95
|
-
{
|
|
96
|
-
"params": {}
|
|
97
|
-
}
|
|
98
|
-
[2025-03-21T18:53:15.919Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 399ms
|
|
99
|
-
[2025-03-21T18:53:16.322Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 403ms
|
|
100
|
-
[2025-03-21T18:53:16.693Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 370ms
|
|
101
|
-
[2025-03-21T18:53:17.078Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 385ms
|
|
102
|
-
[2025-03-21T18:53:17.079Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Found 2 folderless lists in space 90141365861
|
|
103
|
-
[2025-03-21T18:53:17.079Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding 2 lists directly to space Talib's Space (90141365861)
|
|
104
|
-
[2025-03-21T18:53:17.079Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Personal List (901403617613)
|
|
105
|
-
[2025-03-21T18:53:17.079Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Work List (901403621899)
|
|
106
|
-
[2025-03-21T18:53:17.532Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 453ms
|
|
107
|
-
[2025-03-21T18:53:17.950Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 417ms
|
|
108
|
-
[2025-03-21T18:53:18.312Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 361ms
|
|
109
|
-
[2025-03-21T18:53:18.312Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Found 0 folderless lists in space 90141864154
|
|
110
|
-
[2025-03-21T18:53:18.312Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding 0 lists directly to space Education (90141864154)
|
|
111
|
-
[2025-03-21T18:53:18.683Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 371ms
|
|
112
|
-
[2025-03-21T18:53:19.187Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 504ms
|
|
113
|
-
[2025-03-21T18:53:19.187Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Found 1 folderless lists in space 90141369187
|
|
114
|
-
[2025-03-21T18:53:19.187Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding 1 lists directly to space Social Media Content (90141369187)
|
|
115
|
-
[2025-03-21T18:53:19.187Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: VibeCase (901403679582)
|
|
116
|
-
[2025-03-21T18:53:19.583Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 396ms
|
|
117
|
-
[2025-03-21T18:53:20.005Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 421ms
|
|
118
|
-
[2025-03-21T18:53:20.386Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 380ms
|
|
119
|
-
[2025-03-21T18:53:20.793Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 407ms
|
|
120
|
-
[2025-03-21T18:53:21.171Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 378ms
|
|
121
|
-
[2025-03-21T18:53:21.518Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 347ms
|
|
122
|
-
[2025-03-21T18:53:21.888Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 369ms
|
|
123
|
-
[2025-03-21T18:53:22.256Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 367ms
|
|
124
|
-
[2025-03-21T18:53:22.672Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 416ms
|
|
125
|
-
[2025-03-21T18:53:23.078Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 406ms
|
|
126
|
-
[2025-03-21T18:53:23.475Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 397ms
|
|
127
|
-
[2025-03-21T18:53:23.832Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Request completed successfully in 357ms
|
|
128
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Found 9 folderless lists in space 90141392755
|
|
129
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding 9 lists directly to space Custom Space (90141392755)
|
|
130
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Job Applications (901404823810)
|
|
131
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: goal-tracker (901408127809)
|
|
132
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Bulk Test List 1 (901408285531)
|
|
133
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Bulk Test List 2 (901408285532)
|
|
134
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Style Scraper (901408105509)
|
|
135
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Prompts | Snippets | Commands (901407112060)
|
|
136
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: cursor-rules-mcp-server (901408144363)
|
|
137
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: Items to Sell Online (901404691843)
|
|
138
|
-
[2025-03-21T18:53:23.833Z] [PID:44431] DEBUG: [ClickUp:WorkspaceService] Adding list directly to space: clickup-mcp-server (901408020907)
|
|
139
|
-
[2025-03-21T18:53:29.131Z] [PID:44431] INFO: [Server] Received CallTool request for tool: create_task
|
|
140
|
-
{
|
|
141
|
-
"params": {
|
|
142
|
-
"name": "🧪 Test task for sponsor message",
|
|
143
|
-
"listName": "Bulk Test List 1",
|
|
144
|
-
"description": "This is a test task to verify sponsor message positioning"
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
[2025-03-21T18:53:29.131Z] [PID:44431] INFO: [ClickUp:TaskService] Operation: createTask
|
|
148
|
-
{
|
|
149
|
-
"listId": "901408285531",
|
|
150
|
-
"name": "🧪 Test task for sponsor message",
|
|
151
|
-
"description": "This is a test task to verify sponsor message positioning"
|
|
152
|
-
}
|
|
153
|
-
[2025-03-21T18:53:29.779Z] [PID:44431] DEBUG: [ClickUp:TaskService] Request completed successfully in 648ms
|
|
154
|
-
[2025-03-21T18:53:49.644Z] [PID:44431] INFO: [Server] Received CallTool request for tool: get_task
|
|
155
|
-
{
|
|
156
|
-
"params": {
|
|
157
|
-
"taskId": "86b4c2nqd"
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
[2025-03-21T18:53:49.644Z] [PID:44431] INFO: [ClickUp:TaskService] Operation: getTask
|
|
161
|
-
{
|
|
162
|
-
"taskId": "86b4c2nqd"
|
|
163
|
-
}
|
|
164
|
-
[2025-03-21T18:53:50.129Z] [PID:44431] DEBUG: [ClickUp:TaskService] Request completed successfully in 485ms
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Alternative implementation for bulk tasks creation
|
|
3
|
-
*/
|
|
4
|
-
import { handleCreateBulkTasks } from './task.js';
|
|
5
|
-
/**
|
|
6
|
-
* Alternative tool definition for bulk task creation to work around MCP validation issues
|
|
7
|
-
*/
|
|
8
|
-
export const createTasksBulkTool = {
|
|
9
|
-
name: "create_tasks_bulk",
|
|
10
|
-
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",
|
|
11
|
-
inputSchema: {
|
|
12
|
-
type: "object",
|
|
13
|
-
properties: {
|
|
14
|
-
listId: {
|
|
15
|
-
type: "string",
|
|
16
|
-
description: "ID of list for new tasks (preferred). Use this instead of listName if you have it."
|
|
17
|
-
},
|
|
18
|
-
listName: {
|
|
19
|
-
type: "string",
|
|
20
|
-
description: "Name of list for new tasks. Only use if you don't have listId."
|
|
21
|
-
},
|
|
22
|
-
tasks: {
|
|
23
|
-
// Define minimally to avoid validation issues
|
|
24
|
-
description: "Array of tasks to create. Each task must have at least a name."
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
required: ["tasks"]
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* Handler for create_tasks_bulk tool
|
|
32
|
-
*/
|
|
33
|
-
export async function handleCreateTasksBulk(parameters) {
|
|
34
|
-
// Use the same implementation as handleCreateBulkTasks
|
|
35
|
-
return handleCreateBulkTasks(parameters);
|
|
36
|
-
}
|