Skip to main content
Glama

Get Next TODO Task

get_next_todo_task

Retrieve the next incomplete task from a TODO list for sequential execution. Use this tool to identify pending tasks, continue interrupted work, or follow task order efficiently while managing projects.

Instructions

Get the next incomplete task in a TODO list for sequential execution.

When to use this tool:

  • Working through TODO sequentially

  • Finding next task to implement

  • Checking for remaining work

  • Continuing interrupted work

  • Following task order

Key features:

  • Returns first incomplete task

  • Provides task number and description

  • Indicates when all complete

  • Maintains task sequence

You should:

  1. Use after completing current task

  2. Follow sequential task order

  3. Handle "all complete" case

  4. Read full task details if needed

  5. Mark complete before getting next

DO NOT use when:

  • Need specific task (not next)

  • Want full TODO overview

  • All tasks already complete

Returns: {success: bool, task?: {number: int, description: str}, message?: str, error?: str}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesThe project identifier
todo_numberYesThe TODO list number

Implementation Reference

  • The core handler function that implements the logic for 'get_next_todo_task'. It locates the next incomplete task in the specified TODO list by scanning task files, parsing metadata, and returning task details or completion status.
    async getNextTodoTaskAsync(params: {
      project_id: z.infer<typeof secureProjectIdSchema>;
      todo_number: z.infer<typeof secureTodoNumberSchema>;
    }): Promise<string> {
      const context = this.createContext('get_next_todo_task', params);
    
      try {
        const { project_id, todo_number } = params;
        const projectInfo = await getProjectDirectoryAsync(this.storagePath, project_id);
    
        if (!projectInfo) {
          throw new MCPError(MCPErrorCode.PROJECT_NOT_FOUND, `Project ${project_id} not found`, {
            project_id,
            traceId: context.traceId,
          });
        }
    
        const [, projectPath] = projectInfo;
        const todoDir = join(projectPath, 'TODO', todo_number.toString());
    
        // Check if TODO exists
        try {
          await access(todoDir);
        } catch {
          throw new MCPError(MCPErrorCode.TODO_NOT_FOUND, `TODO #${todo_number} not found`, {
            project_id,
            todo_number,
            traceId: context.traceId,
          });
        }
    
        // Find all task files
        const taskFiles = await this.getTaskFilesAsync(todoDir);
    
        // Look for first incomplete task
        for (const taskFile of taskFiles) {
          const taskPath = join(todoDir, taskFile);
          const content = await readFile(taskPath, 'utf8');
          const parsed = fm<TaskMetadata>(content);
    
          if (!parsed.attributes.completed) {
            const taskNumber = this.extractTaskNumber(taskFile);
            const taskData = await this.parseTaskDataAsync(taskPath);
    
            this.logSuccess(
              'get_next_todo_task',
              { project_id, todo_number, task_number: taskNumber },
              context
            );
            return this.formatSuccessResponse({
              task: {
                number: taskNumber,
                description: taskData.title,
              },
            });
          }
        }
    
        // No incomplete tasks
        this.logSuccess('get_next_todo_task', { project_id, todo_number, found: false }, context);
        return this.formatSuccessResponse({
          message: 'All tasks completed',
        });
      } catch (error) {
        this.logError('get_next_todo_task', params, error as MCPError, context);
        return this.formatErrorResponse(error, context);
      }
    }
  • Registers the 'get_next_todo_task' tool with the MCP server, specifying title, description, input schema, and the handler function that delegates to TodoToolHandler.getNextTodoTaskAsync.
      'get_next_todo_task',
      {
        title: 'Get Next TODO Task',
        description: TOOL_DESCRIPTIONS.get_next_todo_task,
        inputSchema: {
          project_id: secureProjectIdSchema.describe('The project identifier'),
          todo_number: secureTodoNumberSchema.describe('The TODO list number'),
        },
      },
      async ({ project_id, todo_number }) => {
        const result = await todoHandler.getNextTodoTaskAsync({ project_id, todo_number });
        return {
          content: [
            {
              type: 'text',
              text: result,
            },
          ],
        };
      }
    );
  • Defines the input schema for the tool using Zod schemas for project_id and todo_number with descriptions.
    inputSchema: {
      project_id: secureProjectIdSchema.describe('The project identifier'),
      todo_number: secureTodoNumberSchema.describe('The TODO list number'),
    },
  • Helper method to extract the task number from task filenames like 'TASK-001-slug.md', used in the handler to identify tasks.
    private extractTaskNumber(filename: string): number {
      const match = filename.match(/^TASK-(\d{3})-.*\.md$/);
      return match ? parseInt(match[1], 10) : 0;
    }
  • Async helper to list and sort task files (.md starting with TASK-) in a TODO directory, crucial for scanning tasks in the handler.
    private async getTaskFilesAsync(todoDir: string): Promise<string[]> {
      const files = await readdir(todoDir);
      return files.filter((file) => file.startsWith('TASK-') && file.endsWith('.md')).sort();
    }
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: returns the first incomplete task, indicates when all are complete, maintains sequence, and requires marking tasks complete before getting the next. However, it lacks details on error handling or performance aspects like rate limits, though these are less critical for a read-only tool.

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

Conciseness4/5

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

The description is well-structured with sections like 'When to use this tool,' 'Key features,' 'You should,' and 'DO NOT use when,' making it easy to scan. However, it includes some redundancy (e.g., 'Get the next incomplete task' is reiterated in 'Key features'), and the bullet points could be more concise, slightly reducing efficiency.

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?

Given no annotations and no output schema, the description does a good job covering purpose, usage, and behavior. It includes return value details in 'Returns,' which compensates for the lack of output schema. However, it could benefit from more context on error cases or integration with sibling tools like 'complete_todo_task,' making it slightly incomplete.

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?

The input schema has 100% description coverage, clearly documenting both parameters ('project_id' and 'todo_number'). The description does not add any parameter-specific information beyond what the schema provides, such as explaining how these IDs relate to task sequencing. This meets the baseline of 3 for high schema coverage.

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 tool's purpose as 'Get the next incomplete task in a TODO list for sequential execution,' which includes a specific verb ('Get'), resource ('next incomplete task'), and scope ('sequential execution'). It distinguishes from sibling tools like 'get_todo_tasks' (which likely returns all tasks) and 'complete_todo_task' (which modifies tasks).

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

Usage Guidelines5/5

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

The description provides explicit guidance with 'When to use this tool' (e.g., 'Working through TODO sequentially') and 'DO NOT use when' (e.g., 'Need specific task (not next)'), including alternatives like avoiding it for 'full TODO overview' (which suggests using 'get_todo_tasks' instead). This clearly differentiates usage from other 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/sven-borkert/knowledge-mcp'

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