UNPKG

@twofeetup/clickup-mcp

Version:

Optimized ClickUp MCP Server - High-performance AI integration with consolidated tools and response optimization

339 lines (338 loc) 14.9 kB
/** * SPDX-FileCopyrightText: (c) 2025 Sjoerd Tiemensma * SPDX-License-Identifier: MIT * * Task Type Schema Builder * * This module provides helper functions to build tool schemas with dynamic * task type enums based on the types loaded from ClickUp API. */ import { taskTypeService } from '../../services/task-type-service.js'; /** * Get the task_type property schema with dynamic enum values * @returns Property schema for task_type field */ export function getTaskTypeProperty() { const availableTypes = taskTypeService.getAvailableTypes(); // If no types loaded yet or service not initialized, return without enum if (!taskTypeService.isInitialized() || availableTypes.length === 0) { return { type: "string", description: "Task type (e.g., 'milestone', 'Bug/Issue', 'Feature'). Leave empty for normal task." }; } // Return schema with dynamic enum return { type: "string", enum: availableTypes, description: `Task type. Available: ${availableTypes.join(', ')}. Leave empty for normal task.` }; } /** * Build the complete manageTask tool schema with dynamic task types * @returns Tool schema object */ export function buildManageTaskToolSchema() { return { name: "manage_task", description: "Modify tasks with action-based routing. Actions: create (new task), update (modify fields), delete (remove), move (to different list), duplicate (copy to another list). Flexible task identification: taskId (preferred), taskName, or customTaskId. Supports all task fields including priority, dates, assignees, custom fields, tags, and task types.", inputSchema: { type: "object", properties: { action: { type: "string", enum: ["create", "update", "delete", "move", "duplicate"], description: "REQUIRED: Operation to perform on the task" }, // Task Identification (required for update/delete/move/duplicate) taskId: { type: "string", description: "ID of task to modify. Works with both regular and custom task IDs. Not needed for create action." }, taskName: { type: "string", description: "Name of task to modify. When used, recommend also providing listName for faster lookup." }, customTaskId: { type: "string", description: "Custom ID of task (e.g., DEV-123). Alternative to taskId." }, listName: { type: "string", description: "List name - improves lookup speed when using taskName. For create action, listName or listId is required." }, // Create action fields name: { type: "string", description: "REQUIRED for create: Task name. Include emoji + space before name (e.g., '🎯 Build feature')." }, listId: { type: "string", description: "REQUIRED for create (unless listName provided): List ID where task is created. Use if available from prior response." }, // Task type field (dynamic) task_type: getTaskTypeProperty(), // Update action fields description: { type: "string", description: "Plain text task description" }, markdown_description: { type: "string", description: "Markdown formatted description (takes precedence over description)" }, status: { type: "string", description: "Task status (e.g., 'Open', 'In Progress', 'Done')" }, priority: { type: "number", enum: [1, 2, 3, 4], description: "Priority: 1=urgent, 2=high, 3=normal, 4=low. Only set when explicitly requested." }, dueDate: { type: "string", description: "Due date. Supports Unix timestamps (ms) or natural language: 'tomorrow', 'next friday', '2 weeks from now', 'end of month'" }, startDate: { type: "string", description: "Start date. Supports Unix timestamps (ms) or natural language: 'today', 'next monday', etc." }, parent: { type: "string", description: "Parent task ID for creating subtasks (create action only)" }, tags: { type: "array", items: { type: "string" }, description: "Array of tag names. Tags must exist in the space." }, assignees: { type: "array", items: { oneOf: [ { type: "number", description: "User ID" }, { type: "string", description: "Email or username" } ] }, description: "Array of assignees: user IDs, emails, or usernames" }, custom_fields: { type: "array", items: { type: "object", properties: { id: { type: "string", description: "Custom field ID" }, value: { description: "Field value (type depends on field)" } }, required: ["id", "value"] }, description: "Array of custom field values: {id, value}" }, time_estimate: { type: "string", description: "Time estimate: '2h 30m', '150m', '2.5h', or minutes as number" }, check_required_custom_fields: { type: "boolean", description: "For create: validate all required custom fields are set before saving" }, // Move/Duplicate action fields targetListId: { type: "string", description: "For move/duplicate: destination list ID. Use if available." }, targetListName: { type: "string", description: "For move/duplicate: destination list name" } }, required: ["action"] } }; } /** * Build tool schema for single create task operation * @returns Tool schema object */ export function buildCreateTaskToolSchema() { return { name: "create_task", description: "Create a new task in a ClickUp list with optional fields: description, assignees, priority, due date, start date, tags, custom fields, and task type. Supports natural language for dates (e.g., 'tomorrow', 'next friday'). Returns task details including ID and URL.", inputSchema: { type: "object", properties: { name: { type: "string", description: "REQUIRED: Task name. Include emoji + space before name (e.g., '🎯 Build feature')." }, listId: { type: "string", description: "List ID where task is created. If not provided, must provide listName." }, listName: { type: "string", description: "List name. Used if listId not provided. Recommend using listId when available." }, task_type: getTaskTypeProperty(), description: { type: "string", description: "Plain text task description" }, markdown_description: { type: "string", description: "Markdown formatted description (takes precedence over description)" }, status: { type: "string", description: "Task status (e.g., 'Open', 'In Progress'). Must match list's available statuses." }, priority: { type: "number", enum: [1, 2, 3, 4], description: "Priority: 1=urgent, 2=high, 3=normal, 4=low. Only set when explicitly requested." }, dueDate: { type: "string", description: "Due date. Supports Unix timestamps (ms) or natural language: 'tomorrow', 'next friday', '2 weeks from now', 'end of month'" }, startDate: { type: "string", description: "Start date. Supports Unix timestamps (ms) or natural language: 'today', 'next monday', etc." }, parent: { type: "string", description: "Parent task ID for creating subtasks" }, tags: { type: "array", items: { type: "string" }, description: "Array of tag names. Tags must exist in the space." }, assignees: { type: "array", items: { oneOf: [ { type: "number", description: "User ID" }, { type: "string", description: "Email or username" } ] }, description: "Array of assignees: user IDs, emails, or usernames" }, custom_fields: { type: "array", items: { type: "object", properties: { id: { type: "string", description: "Custom field ID" }, value: { description: "Field value (type depends on field)" } }, required: ["id", "value"] }, description: "Array of custom field values: {id, value}" }, time_estimate: { type: "string", description: "Time estimate: '2h 30m', '150m', '2.5h', or minutes as number" }, check_required_custom_fields: { type: "boolean", description: "Validate all required custom fields are set before saving" } }, required: ["name"] } }; } /** * Build tool schema for single update task operation * @returns Tool schema object */ export function buildUpdateTaskToolSchema() { return { name: "update_task", description: "Update an existing task's fields. Flexible task identification: taskId (preferred), taskName (requires listName), or customTaskId. Can update any field including name, description, status, priority, dates, assignees, tags, custom fields, and task type. Returns updated task details.", inputSchema: { type: "object", properties: { taskId: { type: "string", description: "ID of task to update. Works with both regular and custom task IDs. If not provided, must use taskName or customTaskId." }, taskName: { type: "string", description: "Name of task to update. Requires listName for efficient lookup." }, customTaskId: { type: "string", description: "Custom ID of task (e.g., DEV-123). Alternative to taskId." }, listName: { type: "string", description: "List name - required when using taskName" }, name: { type: "string", description: "New task name" }, task_type: getTaskTypeProperty(), description: { type: "string", description: "Plain text task description" }, markdown_description: { type: "string", description: "Markdown formatted description" }, status: { type: "string", description: "Task status (e.g., 'Done', 'In Progress')" }, priority: { type: "number", enum: [1, 2, 3, 4], description: "Priority: 1=urgent, 2=high, 3=normal, 4=low" }, dueDate: { type: "string", description: "Due date. Supports Unix timestamps (ms) or natural language" }, startDate: { type: "string", description: "Start date. Supports Unix timestamps (ms) or natural language" }, tags: { type: "array", items: { type: "string" }, description: "Array of tag names" }, assignees: { type: "array", items: { oneOf: [ { type: "number", description: "User ID" }, { type: "string", description: "Email or username" } ] }, description: "Array of assignees" }, custom_fields: { type: "array", items: { type: "object", properties: { id: { type: "string" }, value: {} }, required: ["id", "value"] }, description: "Array of custom field values" }, time_estimate: { type: "string", description: "Time estimate: '2h 30m', '150m', '2.5h', or minutes" } } } }; }