UNPKG

@djclarkson/clickup-mcp-server

Version:

ClickUp MCP Server - Enhanced fork with task dependency management and parameter fixes

163 lines (162 loc) 6.36 kB
/** * 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) }; } }