@djclarkson/clickup-mcp-server
Version:
ClickUp MCP Server - Enhanced fork with task dependency management and parameter fixes
163 lines (162 loc) • 6.36 kB
JavaScript
/**
* SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
* SPDX-License-Identifier: MIT
*
* Task dependency management tools for ClickUp MCP server
*/
import { Logger } from '../../logger.js';
const logger = new Logger('TaskDependencyHandlers');
import { clickUpServices } from '../../services/shared.js';
const { task: taskService } = clickUpServices;
/**
* Handler for adding a task dependency
*/
export async function handleAddTaskDependency(params) {
try {
logger.info('Adding task dependency', { params });
// Validate parameters
if (!params.taskId && !params.taskName) {
throw new Error('Either taskId or taskName must be provided');
}
if (!params.dependsOnTaskId && !params.dependsOnTaskName) {
throw new Error('Either dependsOnTaskId or dependsOnTaskName must be provided');
}
if (params.taskName && !params.listName) {
logger.warn('Using taskName without listName may result in ambiguous matches');
}
if (params.dependsOnTaskName && !params.dependsOnListName) {
logger.warn('Using dependsOnTaskName without dependsOnListName may result in ambiguous matches');
}
// Call the service method
const result = await taskService.addTaskDependency(params);
if (!result.success) {
throw result.error || new Error('Failed to add task dependency');
}
logger.info('Task dependency added successfully', {
dependency: result.data
});
return {
success: true,
dependency: result.data,
message: 'Task dependency created successfully'
};
}
catch (error) {
logger.error('Failed to add task dependency', { error: error.message, params });
throw {
error: `Failed to add task dependency: ${error.message}`,
params: JSON.stringify(params)
};
}
}
/**
* Handler for removing a task dependency
*/
export async function handleRemoveTaskDependency(params) {
try {
logger.info('Removing task dependency', { params });
// Validate parameters
if (!params.taskId && !params.taskName) {
throw new Error('Either taskId or taskName must be provided');
}
if (!params.dependencyTaskId && !params.dependencyTaskName) {
throw new Error('Either dependencyTaskId or dependencyTaskName must be provided');
}
if (params.taskName && !params.listName) {
logger.warn('Using taskName without listName may result in ambiguous matches');
}
if (params.dependencyTaskName && !params.dependencyListName) {
logger.warn('Using dependencyTaskName without dependencyListName may result in ambiguous matches');
}
// Call the service method
const result = await taskService.removeTaskDependency(params);
if (!result.success) {
throw result.error || new Error('Failed to remove task dependency');
}
logger.info('Task dependency removed successfully');
return {
success: true,
message: 'Task dependency removed successfully'
};
}
catch (error) {
logger.error('Failed to remove task dependency', { error: error.message, params });
throw {
error: `Failed to remove task dependency: ${error.message}`,
params: JSON.stringify(params)
};
}
}
/**
* Handler for getting task dependencies
*/
export async function handleGetTaskDependencies(params) {
try {
logger.info('Getting task dependencies', { params });
// Validate parameters
if (!params.taskId && !params.taskName) {
throw new Error('Either taskId or taskName must be provided');
}
if (params.taskName && !params.listName) {
logger.warn('Using taskName without listName may result in ambiguous matches');
}
// Call the service method
const result = await taskService.getTaskDependencies(params);
if (!result.success) {
throw result.error || new Error('Failed to get task dependencies');
}
logger.info('Task dependencies retrieved successfully', {
taskId: result.data?.task.id,
dependencyCount: (result.data?.dependencies.waiting_on.length || 0) +
(result.data?.dependencies.blocking.length || 0)
});
return result.data;
}
catch (error) {
logger.error('Failed to get task dependencies', { error: error.message, params });
throw {
error: `Failed to get task dependencies: ${error.message}`,
params: JSON.stringify(params)
};
}
}
/**
* Handler for adding bulk dependencies
*/
export async function handleAddBulkDependencies(params) {
try {
logger.info('Adding bulk dependencies', {
count: params.dependencies?.length,
options: params.options
});
// Validate parameters
if (!params.dependencies || !Array.isArray(params.dependencies) || params.dependencies.length === 0) {
throw new Error('Dependencies array is required and must not be empty');
}
// Validate each dependency item
for (const dep of params.dependencies) {
if (!dep.taskId) {
throw new Error('Each dependency item must have a taskId');
}
if (!dep.dependsOn || !Array.isArray(dep.dependsOn) || dep.dependsOn.length === 0) {
throw new Error('Each dependency item must have a non-empty dependsOn array');
}
}
// Call the service method
const result = await taskService.addBulkDependencies(params);
if (!result.success) {
throw result.error || new Error('Failed to add bulk dependencies');
}
logger.info('Bulk dependencies operation completed', {
summary: result.data?.summary
});
return result.data;
}
catch (error) {
logger.error('Failed to add bulk dependencies', { error: error.message, params });
throw {
error: `Failed to add bulk dependencies: ${error.message}`,
params: JSON.stringify(params)
};
}
}