Skip to main content
Glama

clear_subtasks

Remove subtasks from specific or all tasks in a project, using task IDs, tags, or a tasks file, to streamline task management in AI-driven development workflows.

Instructions

Clear subtasks from specified tasks

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
allNoClear subtasks from all tasks
fileNoAbsolute path to the tasks file (default: tasks/tasks.json)
idNoTask IDs (comma-separated) to clear subtasks from
projectRootYesThe directory of the project. Must be an absolute path.
tagNoTag context to operate on

Implementation Reference

  • Registration function for the clear_subtasks MCP tool, including schema definition and execute handler that orchestrates the operation by calling clearSubtasksDirect
    export function registerClearSubtasksTool(server) {
    	server.addTool({
    		name: 'clear_subtasks',
    		description: 'Clear subtasks from specified tasks',
    		parameters: z
    			.object({
    				id: z
    					.string()
    					.optional()
    					.describe('Task IDs (comma-separated) to clear subtasks from'),
    				all: z.boolean().optional().describe('Clear subtasks from all tasks'),
    				file: z
    					.string()
    					.optional()
    					.describe(
    						'Absolute path to the tasks file (default: tasks/tasks.json)'
    					),
    				projectRoot: z
    					.string()
    					.describe('The directory of the project. Must be an absolute path.'),
    				tag: z.string().optional().describe('Tag context to operate on')
    			})
    			.refine((data) => data.id || data.all, {
    				message: "Either 'id' or 'all' parameter must be provided",
    				path: ['id', 'all']
    			}),
    		execute: withToolContext('clear-subtasks', async (args, context) => {
    			try {
    				context.log.info(
    					`Clearing subtasks with args: ${JSON.stringify(args)}`
    				);
    
    				const resolvedTag = resolveTag({
    					projectRoot: args.projectRoot,
    					tag: args.tag
    				});
    
    				// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
    				let tasksJsonPath;
    				try {
    					tasksJsonPath = findTasksPath(
    						{ projectRoot: args.projectRoot, file: args.file },
    						context.log
    					);
    				} catch (error) {
    					context.log.error(`Error finding tasks.json: ${error.message}`);
    					return createErrorResponse(
    						`Failed to find tasks.json: ${error.message}`
    					);
    				}
    
    				const result = await clearSubtasksDirect(
    					{
    						tasksJsonPath: tasksJsonPath,
    						id: args.id,
    						all: args.all,
    
    						projectRoot: args.projectRoot,
    						tag: resolvedTag
    					},
    					context.log,
    					{ session: context.session }
    				);
    
    				if (result.success) {
    					context.log.info(
    						`Subtasks cleared successfully: ${result.data.message}`
    					);
    				} else {
    					context.log.error(
    						`Failed to clear subtasks: ${result.error.message}`
    					);
    				}
    
    				return handleApiResult({
    					result,
    					log: context.log,
    					errorPrefix: 'Error clearing subtasks',
    					projectRoot: args.projectRoot
    				});
    			} catch (error) {
    				context.log.error(`Error in clearSubtasks tool: ${error.message}`);
    				return createErrorResponse(error.message);
    			}
    		})
    	});
    }
  • Direct function handler called by the MCP tool handler, performs validation, calls core clearSubtasks, and returns structured result
    export async function clearSubtasksDirect(args, log) {
    	// Destructure expected args
    	const { tasksJsonPath, id, all, tag, projectRoot } = args;
    	try {
    		log.info(`Clearing subtasks with args: ${JSON.stringify(args)}`);
    
    		// Check if tasksJsonPath was provided
    		if (!tasksJsonPath) {
    			log.error('clearSubtasksDirect called without tasksJsonPath');
    			return {
    				success: false,
    				error: {
    					code: 'MISSING_ARGUMENT',
    					message: 'tasksJsonPath is required'
    				}
    			};
    		}
    
    		// Either id or all must be provided
    		if (!id && !all) {
    			return {
    				success: false,
    				error: {
    					code: 'INPUT_VALIDATION_ERROR',
    					message:
    						'Either task IDs with id parameter or all parameter must be provided'
    				}
    			};
    		}
    
    		// Use provided path
    		const tasksPath = tasksJsonPath;
    
    		// Check if tasks.json exists
    		if (!fs.existsSync(tasksPath)) {
    			return {
    				success: false,
    				error: {
    					code: 'FILE_NOT_FOUND_ERROR',
    					message: `Tasks file not found at ${tasksPath}`
    				}
    			};
    		}
    
    		let taskIds;
    
    		// Use readJSON which handles silent migration and tag resolution
    		const data = readJSON(tasksPath, projectRoot, tag);
    
    		if (!data || !data.tasks) {
    			return {
    				success: false,
    				error: {
    					code: 'INPUT_VALIDATION_ERROR',
    					message: `No tasks found in tasks file: ${tasksPath}`
    				}
    			};
    		}
    
    		const currentTag = data.tag || tag;
    		const tasks = data.tasks;
    
    		// If all is specified, get all task IDs
    		if (all) {
    			log.info(`Clearing subtasks from all tasks in tag '${currentTag}'`);
    			if (tasks.length === 0) {
    				return {
    					success: false,
    					error: {
    						code: 'INPUT_VALIDATION_ERROR',
    						message: `No tasks found in tag context '${currentTag}'`
    					}
    				};
    			}
    			taskIds = tasks.map((t) => t.id).join(',');
    		} else {
    			// Use the provided task IDs
    			taskIds = id;
    		}
    
    		log.info(`Clearing subtasks from tasks: ${taskIds} in tag '${currentTag}'`);
    
    		// Enable silent mode to prevent console logs from interfering with JSON response
    		enableSilentMode();
    
    		// Call the core function
    		clearSubtasks(tasksPath, taskIds, { projectRoot, tag: currentTag });
    
    		// Restore normal logging
    		disableSilentMode();
    
    		// Read the updated data to provide a summary
    		const updatedData = readJSON(tasksPath, projectRoot, currentTag);
    		const taskIdArray = taskIds.split(',').map((id) => parseInt(id.trim(), 10));
    
    		// Build a summary of what was done
    		const clearedTasksCount = taskIdArray.length;
    		const updatedTasks = updatedData.tasks || [];
    
    		const taskSummary = taskIdArray.map((id) => {
    			const task = updatedTasks.find((t) => t.id === id);
    			return task ? { id, title: task.title } : { id, title: 'Task not found' };
    		});
    
    		return {
    			success: true,
    			data: {
    				message: `Successfully cleared subtasks from ${clearedTasksCount} task(s) in tag '${currentTag}'`,
    				tasksCleared: taskSummary,
    				tag: currentTag
    			}
    		};
    	} catch (error) {
    		// Make sure to restore normal logging even if there's an error
    		disableSilentMode();
    
    		log.error(`Error in clearSubtasksDirect: ${error.message}`);
    		return {
    			success: false,
    			error: {
    				code: 'CORE_FUNCTION_ERROR',
    				message: error.message
    			}
    		};
    	}
    }
  • Core implementation function that modifies the tasks.json by clearing subtasks arrays for specified tasks and handles CLI output
    function clearSubtasks(tasksPath, taskIds, context = {}) {
    	const { projectRoot, tag } = context;
    	log('info', `Reading tasks from ${tasksPath}...`);
    	const data = readJSON(tasksPath, projectRoot, tag);
    	if (!data || !data.tasks) {
    		log('error', 'No valid tasks found.');
    		process.exit(1);
    	}
    
    	if (!isSilentMode()) {
    		console.log(
    			boxen(chalk.white.bold('Clearing Subtasks'), {
    				padding: 1,
    				borderColor: 'blue',
    				borderStyle: 'round',
    				margin: { top: 1, bottom: 1 }
    			})
    		);
    	}
    
    	// Handle multiple task IDs (comma-separated)
    	const taskIdArray = taskIds.split(',').map((id) => id.trim());
    	let clearedCount = 0;
    
    	// Create a summary table for the cleared subtasks
    	const summaryTable = new Table({
    		head: [
    			chalk.cyan.bold('Task ID'),
    			chalk.cyan.bold('Task Title'),
    			chalk.cyan.bold('Subtasks Cleared')
    		],
    		colWidths: [10, 50, 20],
    		style: { head: [], border: [] }
    	});
    
    	taskIdArray.forEach((taskId) => {
    		const id = parseInt(taskId, 10);
    		if (Number.isNaN(id)) {
    			log('error', `Invalid task ID: ${taskId}`);
    			return;
    		}
    
    		const task = data.tasks.find((t) => t.id === id);
    		if (!task) {
    			log('error', `Task ${id} not found`);
    			return;
    		}
    
    		if (!task.subtasks || task.subtasks.length === 0) {
    			log('info', `Task ${id} has no subtasks to clear`);
    			summaryTable.push([
    				id.toString(),
    				truncate(task.title, 47),
    				chalk.yellow('No subtasks')
    			]);
    			return;
    		}
    
    		const subtaskCount = task.subtasks.length;
    		task.subtasks = [];
    		clearedCount++;
    		log('info', `Cleared ${subtaskCount} subtasks from task ${id}`);
    
    		summaryTable.push([
    			id.toString(),
    			truncate(task.title, 47),
    			chalk.green(`${subtaskCount} subtasks cleared`)
    		]);
    	});
    
    	if (clearedCount > 0) {
    		writeJSON(tasksPath, data, projectRoot, tag);
    
    		// Show summary table
    		if (!isSilentMode()) {
    			console.log(
    				boxen(chalk.white.bold('Subtask Clearing Summary:'), {
    					padding: { left: 2, right: 2, top: 0, bottom: 0 },
    					margin: { top: 1, bottom: 0 },
    					borderColor: 'blue',
    					borderStyle: 'round'
    				})
    			);
    			console.log(summaryTable.toString());
    		}
    
    		// Success message
    		if (!isSilentMode()) {
    			console.log(
    				boxen(
    					chalk.green(
    						`Successfully cleared subtasks from ${chalk.bold(clearedCount)} task(s)`
    					),
    					{
    						padding: 1,
    						borderColor: 'green',
    						borderStyle: 'round',
    						margin: { top: 1 }
    					}
    				)
    			);
    
    			// Next steps suggestion
    			console.log(
    				boxen(
    					chalk.white.bold('Next Steps:') +
    						'\n\n' +
    						`${chalk.cyan('1.')} Run ${chalk.yellow('task-master expand --id=<id>')} to generate new subtasks\n` +
    						`${chalk.cyan('2.')} Run ${chalk.yellow('task-master list --with-subtasks')} to verify changes`,
    					{
    						padding: 1,
    						borderColor: 'cyan',
    						borderStyle: 'round',
    						margin: { top: 1 }
    					}
    				)
    			);
    		}
    	} else {
    		if (!isSilentMode()) {
    			console.log(
    				boxen(chalk.yellow('No subtasks were cleared'), {
    					padding: 1,
    					borderColor: 'yellow',
    					borderStyle: 'round',
    					margin: { top: 1 }
    				})
    			);
    		}
    	}
    }
  • Tool registry mapping that includes clear_subtasks to its registration function
    import { registerClearSubtasksTool } from './clear-subtasks.js';
    import { registerComplexityReportTool } from './complexity-report.js';
    import { registerCopyTagTool } from './copy-tag.js';
    import { registerDeleteTagTool } from './delete-tag.js';
    import { registerExpandAllTool } from './expand-all.js';
    import { registerExpandTaskTool } from './expand-task.js';
    import { registerFixDependenciesTool } from './fix-dependencies.js';
    import { registerInitializeProjectTool } from './initialize-project.js';
    import { registerListTagsTool } from './list-tags.js';
    import { registerModelsTool } from './models.js';
    import { registerMoveTaskTool } from './move-task.js';
    import { registerNextTaskTool } from './next-task.js';
    import { registerParsePRDTool } from './parse-prd.js';
    import { registerRemoveDependencyTool } from './remove-dependency.js';
    import { registerRemoveSubtaskTool } from './remove-subtask.js';
    import { registerRemoveTaskTool } from './remove-task.js';
    import { registerRenameTagTool } from './rename-tag.js';
    import { registerResearchTool } from './research.js';
    import { registerResponseLanguageTool } from './response-language.js';
    import { registerRulesTool } from './rules.js';
    import { registerScopeDownTool } from './scope-down.js';
    import { registerScopeUpTool } from './scope-up.js';
    import { registerUpdateSubtaskTool } from './update-subtask.js';
    import { registerUpdateTaskTool } from './update-task.js';
    import { registerUpdateTool } from './update.js';
    import { registerUseTagTool } from './use-tag.js';
    import { registerValidateDependenciesTool } from './validate-dependencies.js';
    
    // Import TypeScript tools from apps/mcp
    import {
    	registerAutopilotAbortTool,
    	registerAutopilotCommitTool,
    	registerAutopilotCompleteTool,
    	registerAutopilotFinalizeTool,
    	registerAutopilotNextTool,
    	registerAutopilotResumeTool,
    	registerAutopilotStartTool,
    	registerAutopilotStatusTool,
    	registerGenerateTool,
    	registerGetTaskTool,
    	registerGetTasksTool,
    	registerSetTaskStatusTool
    } from '@tm/mcp';
    
    /**
     * Comprehensive tool registry mapping tool names to their registration functions
     * Used for dynamic tool registration and validation
     */
    export const toolRegistry = {
    	initialize_project: registerInitializeProjectTool,
    	models: registerModelsTool,
    	rules: registerRulesTool,
    	parse_prd: registerParsePRDTool,
    	'response-language': registerResponseLanguageTool,
    	analyze_project_complexity: registerAnalyzeProjectComplexityTool,
    	expand_task: registerExpandTaskTool,
    	expand_all: registerExpandAllTool,
    	scope_up_task: registerScopeUpTool,
    	scope_down_task: registerScopeDownTool,
    	get_tasks: registerGetTasksTool,
    	get_task: registerGetTaskTool,
    	next_task: registerNextTaskTool,
    	complexity_report: registerComplexityReportTool,
    	set_task_status: registerSetTaskStatusTool,
    	add_task: registerAddTaskTool,
    	add_subtask: registerAddSubtaskTool,
    	update: registerUpdateTool,
    	update_task: registerUpdateTaskTool,
    	update_subtask: registerUpdateSubtaskTool,
    	remove_task: registerRemoveTaskTool,
    	remove_subtask: registerRemoveSubtaskTool,
    	clear_subtasks: registerClearSubtasksTool,

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/eyaltoledano/claude-task-master'

If you have feedback or need assistance with the MCP directory API, please join our Discord server