Skip to main content
Glama
bsmi021

MCP Task Manager Server

by bsmi021

setTaskStatus

Update the status of multiple tasks in a project using project ID, task IDs, and target status. Validates task existence and returns the count of updated tasks.

Instructions

Updates the status ('todo', 'in-progress', 'review', 'done') for one or more tasks within a specified project. Requires the project ID, an array of task IDs (1-100), and the target status. Verifies all tasks exist in the project before updating. Returns the count of updated tasks.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesThe unique identifier (UUID) of the project containing the tasks.
statusYesThe target status to set for the specified tasks.
task_idsYesAn array of task IDs (1-100) whose status should be updated.

Implementation Reference

  • Handler function processRequest that executes the setTaskStatus tool logic: logs request, calls TaskService.setTaskStatus, returns JSON response with updated count, handles NotFoundError as InvalidParams and other errors as InternalError.
    const processRequest = async (args: SetTaskStatusArgs) => {
        logger.info(`[${TOOL_NAME}] Received request with args:`, args);
        try {
            // Call the service method to update the status
            const updatedCount = await taskService.setTaskStatus(
                args.project_id,
                args.task_ids,
                args.status
            );
    
            // Format the successful response
            const responsePayload = { success: true, updated_count: updatedCount };
            logger.info(`[${TOOL_NAME}] Updated status for ${updatedCount} tasks in project ${args.project_id}`);
            return {
                content: [{
                    type: "text" as const,
                    text: JSON.stringify(responsePayload)
                }]
            };
        } catch (error: unknown) {
            // Handle potential errors
            logger.error(`[${TOOL_NAME}] Error processing request:`, error);
    
            if (error instanceof NotFoundError) {
                // Specific error if the project or any task wasn't found
                // Map to InvalidParams as the provided ID(s) are invalid
                throw new McpError(ErrorCode.InvalidParams, error.message);
            } else {
                // Generic internal error
                const message = error instanceof Error ? error.message : 'An unknown error occurred while setting task status.';
                throw new McpError(ErrorCode.InternalError, message);
            }
        }
    };
  • Schema definitions: TOOL_NAME, TOOL_DESCRIPTION, Zod TOOL_PARAMS for input validation (project_id UUID, task_ids array 1-100 strings, status enum), and inferred SetTaskStatusArgs type.
    export const TOOL_NAME = "setTaskStatus";
    
    export const TOOL_DESCRIPTION = `
    Updates the status ('todo', 'in-progress', 'review', 'done') for one or more tasks within a specified project.
    Requires the project ID, an array of task IDs (1-100), and the target status.
    Verifies all tasks exist in the project before updating. Returns the count of updated tasks.
    `;
    
    // Re-use enum from other param files
    const TaskStatusEnum = z.enum(['todo', 'in-progress', 'review', 'done']);
    
    // Zod schema for the parameters, matching FR-005 and setTaskStatusTool.md spec
    export const TOOL_PARAMS = z.object({
        project_id: z.string()
            .uuid("The project_id must be a valid UUID.")
            .describe("The unique identifier (UUID) of the project containing the tasks."), // Required, UUID format
    
        task_ids: z.array(
                z.string().min(1, "Task ID cannot be empty.")
                // Add .uuid() if task IDs are UUIDs
                .describe("A unique identifier of a task to update.")
            )
            .min(1, "At least one task ID must be provided.")
            .max(100, "Cannot update more than 100 tasks per call.")
            .describe("An array of task IDs (1-100) whose status should be updated."), // Required, array of strings, limits
    
        status: TaskStatusEnum
            .describe("The target status to set for the specified tasks."), // Required, enum
    });
    
    // Define the expected type for arguments based on the Zod schema
    export type SetTaskStatusArgs = z.infer<typeof TOOL_PARAMS>;
  • Registration function setTaskStatusTool that defines the handler, registers it with MCP server.tool(TOOL_NAME, DESCRIPTION, PARAMS.shape, handler), and logs success.
    export const setTaskStatusTool = (server: McpServer, taskService: TaskService): void => {
    
        const processRequest = async (args: SetTaskStatusArgs) => {
            logger.info(`[${TOOL_NAME}] Received request with args:`, args);
            try {
                // Call the service method to update the status
                const updatedCount = await taskService.setTaskStatus(
                    args.project_id,
                    args.task_ids,
                    args.status
                );
    
                // Format the successful response
                const responsePayload = { success: true, updated_count: updatedCount };
                logger.info(`[${TOOL_NAME}] Updated status for ${updatedCount} tasks in project ${args.project_id}`);
                return {
                    content: [{
                        type: "text" as const,
                        text: JSON.stringify(responsePayload)
                    }]
                };
            } catch (error: unknown) {
                // Handle potential errors
                logger.error(`[${TOOL_NAME}] Error processing request:`, error);
    
                if (error instanceof NotFoundError) {
                    // Specific error if the project or any task wasn't found
                    // Map to InvalidParams as the provided ID(s) are invalid
                    throw new McpError(ErrorCode.InvalidParams, error.message);
                } else {
                    // Generic internal error
                    const message = error instanceof Error ? error.message : 'An unknown error occurred while setting task status.';
                    throw new McpError(ErrorCode.InternalError, message);
                }
            }
        };
    
        // Register the tool with the server
        server.tool(TOOL_NAME, TOOL_DESCRIPTION, TOOL_PARAMS.shape, processRequest);
    
        logger.info(`[${TOOL_NAME}] Tool registered successfully.`);
    };
  • Top-level call to setTaskStatusTool during registerTools to initialize and register the tool with dependencies.
    setTaskStatusTool(server, taskService);
  • Supporting TaskService.setTaskStatus method: validates project/tasks exist, updates statuses via repository, returns updated count.
        public async setTaskStatus(projectId: string, taskIds: string[], status: TaskData['status']): Promise<number> {
            logger.info(`[TaskService] Attempting to set status to '${status}' for ${taskIds.length} tasks in project ${projectId}`);
            const projectExists = this.projectRepository.findById(projectId);
            if (!projectExists) {
                logger.warn(`[TaskService] Project not found: ${projectId}`);
                throw new NotFoundError(`Project with ID ${projectId} not found.`);
            }
    
            const existenceCheck = this.taskRepository.checkTasksExist(projectId, taskIds);
            if (!existenceCheck.allExist) {
                logger.warn(`[TaskService] One or more tasks not found in project ${projectId}:`, existenceCheck.missingIds);
                throw new NotFoundError(`One or more tasks not found in project ${projectId}: ${existenceCheck.missingIds.join(', ')}`);
            }
    
            try {
                const now = new Date().toISOString();
                const updatedCount = this.taskRepository.updateStatus(projectId, taskIds, status, now);
                if (updatedCount !== taskIds.length) {
                    logger.warn(`[TaskService] Expected to update ${taskIds.length} tasks, but ${updatedCount} were affected.`);
                }
                logger.info(`[TaskService] Successfully updated status for ${updatedCount} tasks in project ${projectId}`);
                return updatedCount;
            } catch (error) {
                logger.error(`[TaskService] Error setting status for tasks in project ${projectId}:`, error);
                throw error;
            }
    }
Behavior4/5

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

With no annotations provided, the description carries full burden and does well by disclosing key behaviors: it verifies task existence before updating (safety mechanism), handles batch updates (1-100 tasks), and returns a count of updated tasks. However, it doesn't mention error handling, permission requirements, or whether the operation is idempotent.

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?

Four concise sentences with zero waste: first states purpose, second lists required parameters, third describes verification behavior, fourth specifies return value. Each sentence earns its place by adding distinct value. The description is appropriately sized and front-loaded with the core functionality.

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

Completeness4/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 does well by explaining the verification behavior and return value. However, it doesn't cover error scenarios, permission requirements, or what happens when some tasks don't exist. Given the complexity of a batch update operation, some additional context would be helpful.

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 fully documents all three parameters. The description adds minimal value beyond the schema - it mentions the status enum values and the 1-100 task ID range, but these are already in the schema. Baseline 3 is appropriate when the schema does the heavy lifting.

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

Purpose5/5

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

The description clearly states the specific action ('Updates the status'), resource ('tasks within a specified project'), and scope ('one or more tasks'). It distinguishes this tool from siblings like 'updateTask' by focusing specifically on status updates rather than general task modifications.

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

Usage Guidelines3/5

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

The description implies usage context through parameter requirements but doesn't explicitly state when to use this tool versus alternatives like 'updateTask'. It mentions prerequisites (project ID, task IDs, status) but doesn't provide guidance on when this tool is preferred over other task-modification tools.

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/bsmi021/mcp-task-manager-server'

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