Skip to main content
Glama

remove_dependency

Remove task dependencies to simplify workflows in AI-driven development. Specify task IDs and project paths to eliminate unnecessary dependencies, ensuring cleaner task management in the Task Master system.

Instructions

Remove a dependency from a task

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dependsOnYesTask ID to remove as a dependency
fileNoAbsolute path to the tasks file (default: tasks/tasks.json)
idYesTask ID to remove dependency from
projectRootYesThe directory of the project. Must be an absolute path.
tagNoTag context to operate on

Implementation Reference

  • MCP tool handler: resolves project tag, locates tasks.json, validates inputs, calls removeDependencyDirect, handles response and logging.
    execute: withToolContext('remove-dependency', async (args, context) => {
    	try {
    		const resolvedTag = resolveTag({
    			projectRoot: args.projectRoot,
    			tag: args.tag
    		});
    		context.log.info(
    			`Removing dependency for task ${args.id} from ${args.dependsOn} with args: ${JSON.stringify(args)}`
    		);
    
    		// Use args.projectRoot directly (guaranteed by withToolContext)
    		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 removeDependencyDirect(
    			{
    				tasksJsonPath: tasksJsonPath,
    				id: args.id,
    				dependsOn: args.dependsOn,
    				projectRoot: args.projectRoot,
    				tag: resolvedTag
    			},
    			context.log
    		);
    
    		if (result.success) {
    			context.log.info(
    				`Successfully removed dependency: ${result.data.message}`
    			);
    		} else {
    			context.log.error(
    				`Failed to remove dependency: ${result.error.message}`
    			);
    		}
    
    		return handleApiResult({
    			result,
    			log: context.log,
    			errorPrefix: 'Error removing dependency',
    			projectRoot: args.projectRoot
    		});
    	} catch (error) {
    		context.log.error(`Error in removeDependency tool: ${error.message}`);
    		return createErrorResponse(error.message);
    	}
    })
  • Input schema definition using Zod for the remove_dependency tool parameters.
    name: 'remove_dependency',
    description: 'Remove a dependency from a task',
    parameters: z.object({
    	id: z.string().describe('Task ID to remove dependency from'),
    	dependsOn: z.string().describe('Task ID to remove as a dependency'),
    	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')
    }),
  • Registration function that adds the remove_dependency tool to the MCP server.
    export function registerRemoveDependencyTool(server) {
    	server.addTool({
    		name: 'remove_dependency',
    		description: 'Remove a dependency from a task',
    		parameters: z.object({
    			id: z.string().describe('Task ID to remove dependency from'),
    			dependsOn: z.string().describe('Task ID to remove as a dependency'),
    			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')
    		}),
    		execute: withToolContext('remove-dependency', async (args, context) => {
    			try {
    				const resolvedTag = resolveTag({
    					projectRoot: args.projectRoot,
    					tag: args.tag
    				});
    				context.log.info(
    					`Removing dependency for task ${args.id} from ${args.dependsOn} with args: ${JSON.stringify(args)}`
    				);
    
    				// Use args.projectRoot directly (guaranteed by withToolContext)
    				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 removeDependencyDirect(
    					{
    						tasksJsonPath: tasksJsonPath,
    						id: args.id,
    						dependsOn: args.dependsOn,
    						projectRoot: args.projectRoot,
    						tag: resolvedTag
    					},
    					context.log
    				);
    
    				if (result.success) {
    					context.log.info(
    						`Successfully removed dependency: ${result.data.message}`
    					);
    				} else {
    					context.log.error(
    						`Failed to remove dependency: ${result.error.message}`
    					);
    				}
    
    				return handleApiResult({
    					result,
    					log: context.log,
    					errorPrefix: 'Error removing dependency',
    					projectRoot: args.projectRoot
    				});
    			} catch (error) {
    				context.log.error(`Error in removeDependency tool: ${error.message}`);
    				return createErrorResponse(error.message);
    			}
    		})
    	});
    }
  • Central tool registry mapping 'remove_dependency' to its registration function.
    remove_dependency: registerRemoveDependencyTool,
  • Core helper function that performs the actual dependency removal logic on tasks.json: locates task/subtask, removes specific dependency from array, persists changes.
    async function removeDependency(tasksPath, taskId, dependencyId, context = {}) {
    	log('info', `Removing dependency ${dependencyId} from task ${taskId}...`);
    
    	// Read tasks file
    	const data = readJSON(tasksPath, context.projectRoot, context.tag);
    	if (!data || !data.tasks) {
    		log('error', 'No valid tasks found.');
    		process.exit(1);
    	}
    
    	// Format the task and dependency IDs correctly
    	const formattedTaskId =
    		typeof taskId === 'string' && taskId.includes('.')
    			? taskId
    			: parseInt(taskId, 10);
    
    	const formattedDependencyId = formatTaskId(dependencyId);
    
    	// Find the task to update
    	let targetTask = null;
    	let isSubtask = false;
    
    	if (typeof formattedTaskId === 'string' && formattedTaskId.includes('.')) {
    		// Handle dot notation for subtasks (e.g., "1.2")
    		const [parentId, subtaskId] = formattedTaskId
    			.split('.')
    			.map((id) => parseInt(id, 10));
    		const parentTask = data.tasks.find((t) => t.id === parentId);
    
    		if (!parentTask) {
    			log('error', `Parent task ${parentId} not found.`);
    			process.exit(1);
    		}
    
    		if (!parentTask.subtasks) {
    			log('error', `Parent task ${parentId} has no subtasks.`);
    			process.exit(1);
    		}
    
    		targetTask = parentTask.subtasks.find((s) => s.id === subtaskId);
    		isSubtask = true;
    
    		if (!targetTask) {
    			log('error', `Subtask ${formattedTaskId} not found.`);
    			process.exit(1);
    		}
    	} else {
    		// Regular task (not a subtask)
    		targetTask = data.tasks.find((t) => t.id === formattedTaskId);
    
    		if (!targetTask) {
    			log('error', `Task ${formattedTaskId} not found.`);
    			process.exit(1);
    		}
    	}
    
    	// Check if the task has any dependencies
    	if (!targetTask.dependencies || targetTask.dependencies.length === 0) {
    		log(
    			'info',
    			`Task ${formattedTaskId} has no dependencies, nothing to remove.`
    		);
    		return;
    	}
    
    	// Normalize the dependency ID for comparison to handle different formats
    	const normalizedDependencyId = String(formattedDependencyId);
    
    	// Check if the dependency exists by comparing string representations
    	const dependencyIndex = targetTask.dependencies.findIndex((dep) => {
    		// Direct string comparison (handles both numeric IDs and dot notation)
    		const depStr = String(dep);
    		if (depStr === normalizedDependencyId) {
    			return true;
    		}
    
    		// For subtasks: handle numeric dependencies that might be references to other subtasks
    		// in the same parent (e.g., subtask 1.2 depending on subtask 1.1 stored as just "1")
    		if (typeof dep === 'number' && dep < 100 && isSubtask) {
    			const [parentId] = formattedTaskId.split('.');
    			const fullSubtaskRef = `${parentId}.${dep}`;
    			if (fullSubtaskRef === normalizedDependencyId) {
    				return true;
    			}
    		}
    
    		return false;
    	});
    
    	if (dependencyIndex === -1) {
    		log(
    			'info',
    			`Task ${formattedTaskId} does not depend on ${formattedDependencyId}, no changes made.`
    		);
    		return;
    	}
    
    	// Remove the dependency
    	targetTask.dependencies.splice(dependencyIndex, 1);
    
    	// Save the updated tasks
    	writeJSON(tasksPath, data, context.projectRoot, context.tag);
    
    	// Success message
    	log(
    		'success',
    		`Removed dependency: Task ${formattedTaskId} no longer depends on ${formattedDependencyId}`
    	);
    
    	if (!isSilentMode()) {
    		// Display a more visually appealing success message
    		console.log(
    			boxen(
    				chalk.green(`Successfully removed dependency:\n\n`) +
    					`Task ${chalk.bold(formattedTaskId)} no longer depends on ${chalk.bold(formattedDependencyId)}`,
    				{
    					padding: 1,
    					borderColor: 'green',
    					borderStyle: 'round',
    					margin: { top: 1 }
    				}
    			)
    		);
    	}
    
    	// Regenerate task files
    	// await generateTaskFiles(tasksPath, path.dirname(tasksPath));
    }

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