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));
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral disclosure. 'Remove a dependency' implies a mutation operation, but the description doesn't specify whether this requires specific permissions, whether the change is reversible, what happens to dependent tasks, or what the response looks like. For a mutation tool with zero annotation coverage, this represents a significant gap in behavioral transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that communicates the core purpose without unnecessary words. It's appropriately sized for a tool with this level of complexity and gets straight to the point with zero wasted verbiage.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description is insufficiently complete. It doesn't explain what happens after dependency removal, whether there are side effects on other tasks, what success/failure looks like, or how this interacts with sibling dependency management tools. The description should provide more context given the tool's complexity and lack of structured metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 5 parameters thoroughly. The description adds no additional parameter information beyond what's in the schema. According to scoring rules, when schema coverage is high (>80%), the baseline is 3 even with no parameter information in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Remove') and target ('a dependency from a task'), making the purpose immediately understandable. However, it doesn't differentiate this tool from sibling tools like 'remove_subtask' or 'remove_task', which would require more specific language about what distinguishes dependency removal from other removal operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance about when to use this tool versus alternatives. With sibling tools like 'fix_dependencies' and 'validate_dependencies' available, there's no indication of whether this tool is for manual dependency correction versus automated fixes, or any prerequisites for its use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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