Skip to main content
Glama

add_tag

Create and organize tags for tasks in the Task Master MCP server, enabling efficient categorization, task copying, and project management in AI-driven workflows.

Instructions

Create a new tag for organizing tasks in different contexts

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
copyFromCurrentNoWhether to copy tasks from the current tag (default: false)
copyFromTagNoSpecific tag to copy tasks from
descriptionNoOptional description for the tag
fileNoPath to the tasks file (default: tasks/tasks.json)
fromBranchNoCreate tag name from current git branch (ignores name parameter)
nameYesName of the new tag to create
projectRootYesThe directory of the project. Must be an absolute path.

Implementation Reference

  • Registers the 'add_tag' MCP tool including input schema, description, and execute handler that delegates to addTagDirect after path resolution.
    export function registerAddTagTool(server) {
    	server.addTool({
    		name: 'add_tag',
    		description: 'Create a new tag for organizing tasks in different contexts',
    		parameters: z.object({
    			name: z.string().describe('Name of the new tag to create'),
    			copyFromCurrent: z
    				.boolean()
    				.optional()
    				.describe(
    					'Whether to copy tasks from the current tag (default: false)'
    				),
    			copyFromTag: z
    				.string()
    				.optional()
    				.describe('Specific tag to copy tasks from'),
    			fromBranch: z
    				.boolean()
    				.optional()
    				.describe(
    					'Create tag name from current git branch (ignores name parameter)'
    				),
    			description: z
    				.string()
    				.optional()
    				.describe('Optional description for the tag'),
    			file: z
    				.string()
    				.optional()
    				.describe('Path to the tasks file (default: tasks/tasks.json)'),
    			projectRoot: z
    				.string()
    				.describe('The directory of the project. Must be an absolute path.')
    		}),
    		execute: withNormalizedProjectRoot(async (args, { log, session }) => {
    			try {
    				log.info(`Starting add-tag with args: ${JSON.stringify(args)}`);
    
    				// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
    				let tasksJsonPath;
    				try {
    					tasksJsonPath = findTasksPath(
    						{ projectRoot: args.projectRoot, file: args.file },
    						log
    					);
    				} catch (error) {
    					log.error(`Error finding tasks.json: ${error.message}`);
    					return createErrorResponse(
    						`Failed to find tasks.json: ${error.message}`
    					);
    				}
    
    				// Call the direct function
    				const result = await addTagDirect(
    					{
    						tasksJsonPath: tasksJsonPath,
    						name: args.name,
    						copyFromCurrent: args.copyFromCurrent,
    						copyFromTag: args.copyFromTag,
    						fromBranch: args.fromBranch,
    						description: args.description,
    						projectRoot: args.projectRoot
    					},
    					log,
    					{ session }
    				);
    
    				return handleApiResult({
    					result,
    					log: log,
    					errorPrefix: 'Error creating tag',
    					projectRoot: args.projectRoot
    				});
    			} catch (error) {
    				log.error(`Error in add-tag tool: ${error.message}`);
    				return createErrorResponse(error.message);
    			}
    		})
    	});
    }
  • Core handler function addTagDirect that implements the add tag logic, supporting creation from branch or direct name, with git integration and error handling.
    export async function addTagDirect(args, log, context = {}) {
    	// Destructure expected args
    	const {
    		tasksJsonPath,
    		name,
    		copyFromCurrent = false,
    		copyFromTag,
    		fromBranch = false,
    		description,
    		projectRoot
    	} = args;
    	const { session } = context;
    
    	// Enable silent mode to prevent console logs from interfering with JSON response
    	enableSilentMode();
    
    	// Create logger wrapper using the utility
    	const mcpLog = createLogWrapper(log);
    
    	try {
    		// Check if tasksJsonPath was provided
    		if (!tasksJsonPath) {
    			log.error('addTagDirect called without tasksJsonPath');
    			disableSilentMode();
    			return {
    				success: false,
    				error: {
    					code: 'MISSING_ARGUMENT',
    					message: 'tasksJsonPath is required'
    				}
    			};
    		}
    
    		// Handle --from-branch option
    		if (fromBranch) {
    			log.info('Creating tag from current git branch');
    
    			// Import git utilities
    			const gitUtils = await import(
    				'../../../../scripts/modules/utils/git-utils.js'
    			);
    
    			// Check if we're in a git repository
    			if (!(await gitUtils.isGitRepository(projectRoot))) {
    				log.error('Not in a git repository');
    				disableSilentMode();
    				return {
    					success: false,
    					error: {
    						code: 'NOT_GIT_REPO',
    						message: 'Not in a git repository. Cannot use fromBranch option.'
    					}
    				};
    			}
    
    			// Get current git branch
    			const currentBranch = await gitUtils.getCurrentBranch(projectRoot);
    			if (!currentBranch) {
    				log.error('Could not determine current git branch');
    				disableSilentMode();
    				return {
    					success: false,
    					error: {
    						code: 'NO_CURRENT_BRANCH',
    						message: 'Could not determine current git branch.'
    					}
    				};
    			}
    
    			// Prepare options for branch-based tag creation
    			const branchOptions = {
    				copyFromCurrent,
    				copyFromTag,
    				description:
    					description || `Tag created from git branch "${currentBranch}"`
    			};
    
    			// Call the createTagFromBranch function
    			const result = await createTagFromBranch(
    				tasksJsonPath,
    				currentBranch,
    				branchOptions,
    				{
    					session,
    					mcpLog,
    					projectRoot
    				},
    				'json' // outputFormat - use 'json' to suppress CLI UI
    			);
    
    			// Restore normal logging
    			disableSilentMode();
    
    			return {
    				success: true,
    				data: {
    					branchName: result.branchName,
    					tagName: result.tagName,
    					created: result.created,
    					mappingUpdated: result.mappingUpdated,
    					message: `Successfully created tag "${result.tagName}" from git branch "${result.branchName}"`
    				}
    			};
    		} else {
    			// Check required parameters for regular tag creation
    			if (!name || typeof name !== 'string') {
    				log.error('Missing required parameter: name');
    				disableSilentMode();
    				return {
    					success: false,
    					error: {
    						code: 'MISSING_PARAMETER',
    						message: 'Tag name is required and must be a string'
    					}
    				};
    			}
    
    			log.info(`Creating new tag: ${name}`);
    
    			// Prepare options
    			const options = {
    				copyFromCurrent,
    				copyFromTag,
    				description
    			};
    
    			// Call the createTag function
    			const result = await createTag(
    				tasksJsonPath,
    				name,
    				options,
    				{
    					session,
    					mcpLog,
    					projectRoot
    				},
    				'json' // outputFormat - use 'json' to suppress CLI UI
    			);
    
    			// Restore normal logging
    			disableSilentMode();
    
    			return {
    				success: true,
    				data: {
    					tagName: result.tagName,
    					created: result.created,
    					tasksCopied: result.tasksCopied,
    					sourceTag: result.sourceTag,
    					description: result.description,
    					message: `Successfully created tag "${result.tagName}"`
    				}
    			};
    		}
    	} catch (error) {
    		// Make sure to restore normal logging even if there's an error
    		disableSilentMode();
    
    		log.error(`Error in addTagDirect: ${error.message}`);
    		return {
    			success: false,
    			error: {
    				code: error.code || 'ADD_TAG_ERROR',
    				message: error.message
    			}
    		};
    	}
    }
  • Tool registry entry mapping 'add_tag' to its registration function for dynamic tool setup.
    import { registerAddTagTool } from './add-tag.js';
    import { registerAddTaskTool } from './add-task.js';
    import { registerAnalyzeProjectComplexityTool } from './analyze.js';
    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,
    	move_task: registerMoveTaskTool,
    	add_dependency: registerAddDependencyTool,
    	remove_dependency: registerRemoveDependencyTool,
    	validate_dependencies: registerValidateDependenciesTool,
    	fix_dependencies: registerFixDependenciesTool,
    	list_tags: registerListTagsTool,
    	add_tag: registerAddTagTool,
  • Re-exports and registers addTagDirect in the central direct functions map.
    import { addTagDirect } from './direct-functions/add-tag.js';
    import { addTaskDirect } from './direct-functions/add-task.js';
    import { analyzeTaskComplexityDirect } from './direct-functions/analyze-task-complexity.js';
    // Import direct function implementations
    import { getCacheStatsDirect } from './direct-functions/cache-stats.js';
    import { clearSubtasksDirect } from './direct-functions/clear-subtasks.js';
    import { complexityReportDirect } from './direct-functions/complexity-report.js';
    import { copyTagDirect } from './direct-functions/copy-tag.js';
    import { deleteTagDirect } from './direct-functions/delete-tag.js';
    import { expandAllTasksDirect } from './direct-functions/expand-all-tasks.js';
    import { expandTaskDirect } from './direct-functions/expand-task.js';
    import { fixDependenciesDirect } from './direct-functions/fix-dependencies.js';
    import { initializeProjectDirect } from './direct-functions/initialize-project.js';
    import { listTagsDirect } from './direct-functions/list-tags.js';
    import { modelsDirect } from './direct-functions/models.js';
    import { moveTaskCrossTagDirect } from './direct-functions/move-task-cross-tag.js';
    import { moveTaskDirect } from './direct-functions/move-task.js';
    import { nextTaskDirect } from './direct-functions/next-task.js';
    import { parsePRDDirect } from './direct-functions/parse-prd.js';
    import { removeDependencyDirect } from './direct-functions/remove-dependency.js';
    import { removeSubtaskDirect } from './direct-functions/remove-subtask.js';
    import { removeTaskDirect } from './direct-functions/remove-task.js';
    import { renameTagDirect } from './direct-functions/rename-tag.js';
    import { researchDirect } from './direct-functions/research.js';
    import { scopeDownDirect } from './direct-functions/scope-down.js';
    import { scopeUpDirect } from './direct-functions/scope-up.js';
    import { setTaskStatusDirect } from './direct-functions/set-task-status.js';
    import { updateSubtaskByIdDirect } from './direct-functions/update-subtask-by-id.js';
    import { updateTaskByIdDirect } from './direct-functions/update-task-by-id.js';
    import { updateTasksDirect } from './direct-functions/update-tasks.js';
    import { useTagDirect } from './direct-functions/use-tag.js';
    import { validateDependenciesDirect } from './direct-functions/validate-dependencies.js';
    
    // Re-export utility functions
    export { findTasksPath } from './utils/path-utils.js';
    
    // Use Map for potential future enhancements like introspection or dynamic dispatch
    export const directFunctions = new Map([
    	['getCacheStatsDirect', getCacheStatsDirect],
    	['parsePRDDirect', parsePRDDirect],
    	['updateTasksDirect', updateTasksDirect],
    	['updateTaskByIdDirect', updateTaskByIdDirect],
    	['updateSubtaskByIdDirect', updateSubtaskByIdDirect],
    	['setTaskStatusDirect', setTaskStatusDirect],
    	['nextTaskDirect', nextTaskDirect],
    	['expandTaskDirect', expandTaskDirect],
    	['addTaskDirect', addTaskDirect],
    	['addSubtaskDirect', addSubtaskDirect],
    	['removeSubtaskDirect', removeSubtaskDirect],
    	['analyzeTaskComplexityDirect', analyzeTaskComplexityDirect],
    	['clearSubtasksDirect', clearSubtasksDirect],
    	['expandAllTasksDirect', expandAllTasksDirect],
    	['removeDependencyDirect', removeDependencyDirect],
    	['validateDependenciesDirect', validateDependenciesDirect],
    	['fixDependenciesDirect', fixDependenciesDirect],
    	['complexityReportDirect', complexityReportDirect],
    	['addDependencyDirect', addDependencyDirect],
    	['removeTaskDirect', removeTaskDirect],
    	['initializeProjectDirect', initializeProjectDirect],
    	['modelsDirect', modelsDirect],
    	['moveTaskDirect', moveTaskDirect],
    	['moveTaskCrossTagDirect', moveTaskCrossTagDirect],
    	['researchDirect', researchDirect],
    	['addTagDirect', addTagDirect],

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