Skip to main content
Glama
bsmi021

MCP Task Manager Server

by bsmi021

listTasks

Retrieve tasks for a specific project on the MCP Task Manager Server. Filter by task status and optionally include nested subtasks for detailed task management.

Instructions

Retrieves a list of tasks for a specified project. Allows optional filtering by task status ('todo', 'in-progress', 'review', 'done'). Provides an option to include nested subtasks directly within their parent task objects in the response. Returns an array of task objects.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
include_subtasksNoOptional flag (default false). If true, the response will include subtasks nested within their parent tasks.
project_idYesThe unique identifier (UUID) of the project whose tasks are to be listed. This project must exist.
statusNoOptional filter to return only tasks matching the specified status.

Implementation Reference

  • The handler function that executes the listTasks tool: logs request, calls TaskService.listTasks with args, returns JSON-stringified tasks or throws MCP errors.
    const processRequest = async (args: ListTasksArgs) => {
        logger.info(`[${TOOL_NAME}] Received request with args:`, args);
        try {
            // Call the service method to list tasks
            const tasks = await taskService.listTasks({
                project_id: args.project_id,
                status: args.status,
                include_subtasks: args.include_subtasks,
            });
    
            // Format the successful response
            logger.info(`[${TOOL_NAME}] Found ${tasks.length} tasks for project ${args.project_id}`);
            return {
                content: [{
                    type: "text" as const,
                    text: JSON.stringify(tasks) // Return the array of task objects
                }]
            };
        } catch (error: unknown) {
            // Handle potential errors
            logger.error(`[${TOOL_NAME}] Error processing request:`, error);
    
            if (error instanceof NotFoundError) {
                // Specific error if the project wasn't found
                throw new McpError(ErrorCode.InvalidParams, error.message); // Map NotFound to InvalidParams for project_id
            } else {
                // Generic internal error
                const message = error instanceof Error ? error.message : 'An unknown error occurred while listing tasks.';
                throw new McpError(ErrorCode.InternalError, message);
            }
        }
    };
  • Zod schema (TOOL_PARAMS) and type (ListTasksArgs) for listTasks tool inputs: required project_id UUID, optional status enum, optional include_subtasks bool (default false). Includes TOOL_NAME = 'listTasks'.
    const TaskStatusEnum = z.enum(['todo', 'in-progress', 'review', 'done']);
    
    // Zod schema for the parameters, matching FR-003 and listTasksTool.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 whose tasks are to be listed. This project must exist."), // Required, UUID format
    
        status: TaskStatusEnum
            .optional()
            .describe("Optional filter to return only tasks matching the specified status."), // Optional, enum
    
        include_subtasks: z.boolean()
            .optional()
            .default(false) // Default value
            .describe("Optional flag (default false). If true, the response will include subtasks nested within their parent tasks."), // Optional, boolean, default
    });
    
    // Define the expected type for arguments based on the Zod schema
    export type ListTasksArgs = z.infer<typeof TOOL_PARAMS>;
  • The registration function listTasksTool that defines the handler and calls server.tool to register 'listTasks' with MCP server.
    export const listTasksTool = (server: McpServer, taskService: TaskService): void => {
    
        const processRequest = async (args: ListTasksArgs) => {
            logger.info(`[${TOOL_NAME}] Received request with args:`, args);
            try {
                // Call the service method to list tasks
                const tasks = await taskService.listTasks({
                    project_id: args.project_id,
                    status: args.status,
                    include_subtasks: args.include_subtasks,
                });
    
                // Format the successful response
                logger.info(`[${TOOL_NAME}] Found ${tasks.length} tasks for project ${args.project_id}`);
                return {
                    content: [{
                        type: "text" as const,
                        text: JSON.stringify(tasks) // Return the array of task objects
                    }]
                };
            } catch (error: unknown) {
                // Handle potential errors
                logger.error(`[${TOOL_NAME}] Error processing request:`, error);
    
                if (error instanceof NotFoundError) {
                    // Specific error if the project wasn't found
                    throw new McpError(ErrorCode.InvalidParams, error.message); // Map NotFound to InvalidParams for project_id
                } else {
                    // Generic internal error
                    const message = error instanceof Error ? error.message : 'An unknown error occurred while listing tasks.';
                    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.`);
    };
  • Imports and invokes listTasksTool during overall tool registration in the tools index.
    import { listTasksTool } from "./listTasksTool.js";
    import { showTaskTool } from "./showTaskTool.js";
    import { setTaskStatusTool } from "./setTaskStatusTool.js";
    import { expandTaskTool } from "./expandTaskTool.js";
    import { getNextTaskTool } from "./getNextTaskTool.js";
    import { exportProjectTool } from "./exportProjectTool.js";
    import { importProjectTool } from "./importProjectTool.js";
    import { updateTaskTool } from "./updateTaskTool.js"; // Import the new tool
    import { deleteTaskTool } from "./deleteTaskTool.js"; // Import deleteTask tool
    import { deleteProjectTool } from "./deleteProjectTool.js"; // Import deleteProject tool
    // import { yourTool } from "./yourTool.js"; // Add other new tool imports here
    
    /**
     * Register all defined tools with the MCP server instance.
     * This function centralizes tool registration logic.
     * It also instantiates necessary services and repositories.
     */
    export function registerTools(server: McpServer): void {
        logger.info("Registering tools...");
        const configManager = ConfigurationManager.getInstance();
    
        // --- Instantiate Dependencies ---
        // Note: Consider dependency injection frameworks for larger applications
        try {
            const dbManager = DatabaseManager.getInstance();
            const db = dbManager.getDb(); // Get the initialized DB connection
    
            // Instantiate Repositories
            const projectRepository = new ProjectRepository(db);
            const taskRepository = new TaskRepository(db); // Instantiate TaskRepository
    
            // Instantiate Services
            const projectService = new ProjectService(db, projectRepository, taskRepository); // Pass db and both repos
            const taskService = new TaskService(db, taskRepository, projectRepository); // Instantiate TaskService, passing db and repos
    
            // --- Register Tools ---
            // Register each tool, passing necessary services
    
            // exampleTool(server, configManager.getExampleServiceConfig()); // Example commented out
    
            createProjectTool(server, projectService);
            addTaskTool(server, taskService);
            listTasksTool(server, taskService);
  • TaskService.listTasks method: validates project, fetches tasks from repo, filters top-level or builds nested structure with subtasks if requested.
    public async listTasks(options: ListTasksOptions): Promise<TaskData[] | StructuredTaskData[]> {
        logger.info(`[TaskService] Attempting to list tasks for project: ${options.project_id}`, options);
        const projectExists = this.projectRepository.findById(options.project_id);
        if (!projectExists) {
            logger.warn(`[TaskService] Project not found: ${options.project_id}`);
            throw new NotFoundError(`Project with ID ${options.project_id} not found.`);
        }
    
        try {
            const allTasks = this.taskRepository.findByProjectId(options.project_id, options.status);
    
            if (!options.include_subtasks) {
                const topLevelTasks = allTasks.filter(task => !task.parent_task_id);
                logger.info(`[TaskService] Found ${topLevelTasks.length} top-level tasks for project ${options.project_id}`);
                return topLevelTasks;
            } else {
                const taskMap: Map<string, StructuredTaskData> = new Map();
                const rootTasks: StructuredTaskData[] = [];
                for (const task of allTasks) {
                    taskMap.set(task.task_id, { ...task, subtasks: [] });
                }
                for (const task of allTasks) {
                    if (task.parent_task_id && taskMap.has(task.parent_task_id)) {
                        const parent = taskMap.get(task.parent_task_id)!;
                        parent.subtasks!.push(taskMap.get(task.task_id)!);
                    } else if (!task.parent_task_id) {
                        rootTasks.push(taskMap.get(task.task_id)!);
                    }
                }
                logger.info(`[TaskService] Found ${rootTasks.length} structured root tasks for project ${options.project_id}`);
                return rootTasks;
            }
        } catch (error) {
            logger.error(`[TaskService] Error listing tasks for project ${options.project_id}:`, error);
            throw error;
        }
    }
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