Skip to main content
Glama

Create TODO

create_todo

Create a TODO list with optional tasks and markdown support to organize multi-step work, track bug fixes, or plan feature development. Use for explicit requests and structured task management.

Instructions

Create a new TODO list with optional initial tasks and rich markdown support.

When to use this tool:

  • User explicitly requests "create a TODO"

  • Planning multi-step implementation tasks

  • Organizing feature development work

  • Tracking bug fixes or improvements

  • Creating task lists for later execution

Key features:

  • Rich markdown support in task content

  • Optional initial task list

  • Auto-incrementing TODO numbers

  • Task content supports code blocks

  • Hierarchical task organization

You should:

  1. ONLY create when user explicitly requests

  2. Include clear, actionable task descriptions

  3. Break complex work into subtasks

  4. Use markdown for code examples in tasks

  5. Number tasks logically

  6. Keep descriptions concise but complete

  7. Group related tasks together

DO NOT use when:

  • User hasn't explicitly asked for TODO

  • Tasks are trivial or single-step

  • Work will be done immediately

  • TODO already exists for this work

Tasks need {title: str, content?: str} format Returns: {success: bool, todo_number: int, message: str, error?: str}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
descriptionYesDescription of the TODO list
project_idYesThe project identifier
tasksNoOptional initial tasks as {title, content} objects

Implementation Reference

  • The core handler function that executes the create_todo tool. Creates project/TODO/{number} directory, writes index.json metadata, creates initial TASK markdown files with frontmatter, and auto-commits to git.
    async createTodoAsync(params: {
      project_id: z.infer<typeof secureProjectIdSchema>;
      description: z.infer<typeof secureTodoDescriptionSchema>;
      tasks?: z.infer<typeof taskInputSchema>[];
    }): Promise<string> {
      const context = this.createContext('create_todo', params);
    
      try {
        const { project_id, description, tasks = [] } = params;
        const [originalId, projectPath] = await createProjectEntryAsync(this.storagePath, project_id);
        const todoPath = join(projectPath, 'TODO');
    
        // Create TODO directory if it doesn't exist
        await mkdir(todoPath, { recursive: true });
    
        // Get next TODO number
        const todoNumber = await this.getNextTodoNumberAsync(todoPath);
        const todoDir = join(todoPath, todoNumber.toString());
    
        // Create TODO directory
        await mkdir(todoDir);
    
        // Create index.json
        const metadata: TodoMetadata = {
          created: new Date().toISOString(),
          description,
        };
        await writeFile(join(todoDir, 'index.json'), JSON.stringify(metadata, null, 2));
    
        // Create initial tasks if provided
        for (let i = 0; i < tasks.length; i++) {
          const task = tasks[i];
          const taskNumber = i + 1;
          const taskFilename = `TASK-${taskNumber.toString().padStart(3, '0')}-${slugify(task.title ?? 'task', { lower: true, strict: true })}.md`;
    
          const taskMetadata: TaskMetadata = {
            completed: false,
            created: new Date().toISOString(),
            updated: new Date().toISOString(),
          };
    
          const frontmatter = yaml.dump(taskMetadata);
          const taskContent = `---\n${frontmatter}---\n\n# ${task.title}\n\n${task.content ?? ''}`;
          await writeFile(join(todoDir, taskFilename), taskContent);
        }
    
        // Auto-commit
        await autoCommitAsync(this.storagePath, `Create TODO #${todoNumber} in ${originalId}`);
    
        this.logSuccess('create_todo', { project_id, todo_number: todoNumber }, context);
        return this.formatSuccessResponse({
          todo_number: todoNumber,
          message:
            tasks.length > 0
              ? `Created TODO #${todoNumber} with ${tasks.length} initial task${tasks.length !== 1 ? 's' : ''}`
              : `Created TODO #${todoNumber}`,
        });
      } catch (error) {
        const mcpError =
          error instanceof MCPError
            ? error
            : new MCPError(
                MCPErrorCode.FILE_SYSTEM_ERROR,
                `Failed to create TODO: ${error instanceof Error ? error.message : String(error)}`,
                { project_id: params.project_id, traceId: context.traceId }
              );
        this.logError('create_todo', params, mcpError, context);
        return this.formatErrorResponse(mcpError, context);
      }
  • MCP server registration of the create_todo tool, defining input schema with Zod validation and wiring to TodoToolHandler.createTodoAsync.
    server.registerTool(
      'create_todo',
      {
        title: 'Create TODO',
        description: TOOL_DESCRIPTIONS.create_todo,
        inputSchema: {
          project_id: secureProjectIdSchema.describe('The project identifier'),
          description: secureTodoDescriptionSchema.describe('Description of the TODO list'),
          tasks: z
            .array(
              z.object({
                title: secureTaskTitleSchema.describe('Brief task title (max 200 chars)'),
                content: secureTaskContentSchema.describe('Full markdown content with details'),
              })
            )
            .optional()
            .describe('Optional initial tasks as {title, content} objects'),
        },
      },
      async ({ project_id, description, tasks }) => {
        const result = await todoHandler.createTodoAsync({ project_id, description, tasks });
        return {
          content: [
            {
              type: 'text',
              text: result,
            },
          ],
        };
      }
    );
  • Zod schemas defining input validation for create_todo parameters: project_id (shared), todo description, task title/content, and composite taskInputSchema for tasks array.
    export const secureTodoNumberSchema = z
      .number()
      .int('TODO number must be an integer')
      .positive('TODO number must be positive')
      .max(99999, 'TODO number too large');
    
    export const secureTodoDescriptionSchema = z
      .string()
      .min(1, 'TODO description cannot be empty')
      .max(500, 'TODO description too long (max 500 characters)')
      .refine((val) => !val.includes('\0'), 'TODO description cannot contain null bytes')
      .refine((val) => val.trim() === val, 'TODO description cannot have leading/trailing spaces');
    
    // Task title for brief identification (used in filenames)
    export const secureTaskTitleSchema = z
      .string()
      .min(1, 'Task title cannot be empty')
      .max(200, 'Task title too long (max 200 characters)')
      .refine((val) => !val.includes('\0'), 'Task title cannot contain null bytes')
      .refine((val) => val.trim() === val, 'Task title cannot have leading/trailing spaces');
    
    // Full markdown content for task details
    export const secureTaskContentSchema = z
      .string()
      .max(100 * 1024, 'Task content too large (max 100KB)')
      .refine((val) => !val.includes('\0'), 'Task content cannot contain null bytes')
      .optional();
    
    // Task input schema for new markdown-based tasks
    export const taskInputSchema = z.object({
      title: secureTaskTitleSchema,
      content: secureTaskContentSchema,
    });
  • Detailed usage description string for the create_todo tool, used in server registration to guide LLM tool usage.
      create_todo: `Create a new TODO list with optional initial tasks and rich markdown support.
    
    When to use this tool:
    - User explicitly requests "create a TODO"
    - Planning multi-step implementation tasks
    - Organizing feature development work
    - Tracking bug fixes or improvements
    - Creating task lists for later execution
    
    Key features:
    - Rich markdown support in task content
    - Optional initial task list
    - Auto-incrementing TODO numbers
    - Task content supports code blocks
    - Hierarchical task organization
    
    You should:
    1. ONLY create when user explicitly requests
    2. Include clear, actionable task descriptions
    3. Break complex work into subtasks
    4. Use markdown for code examples in tasks
    5. Number tasks logically
    6. Keep descriptions concise but complete
    7. Group related tasks together
    
    DO NOT use when:
    - User hasn't explicitly asked for TODO
    - Tasks are trivial or single-step
    - Work will be done immediately
    - TODO already exists for this work
    
    Tasks need {title: str, content?: str} format
    Returns: {success: bool, todo_number: int, message: str, error?: str}`,
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 discloses key behavioral traits: it creates new items (implies mutation), supports markdown and hierarchical organization, auto-increments TODO numbers, and returns a specific response format. It doesn't cover permissions or rate limits, but provides substantial operational context.

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 (key features, usage guidelines, do-not-use cases) and bullet points, but could be more front-loaded. Some sentences (e.g., 'Break complex work into subtasks') are more user guidance than tool description, 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?

For a creation tool with no annotations and no output schema, the description is fairly complete: it explains purpose, usage, behavioral traits, and return format. It could benefit from more detail on error handling or permissions, but covers core aspects adequately given the context.

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 parameters. The description mentions 'optional initial tasks' and 'tasks need {title: str, content?: str} format', which aligns with but doesn't add significant meaning beyond the schema. Baseline 3 is appropriate as 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 tool creates a new TODO list with optional initial tasks and rich markdown support. It distinguishes from siblings like 'add_todo_task' (which adds to existing lists) and 'list_todos' (which retrieves lists), making the purpose specific and differentiated.

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 'When to use this tool' scenarios (e.g., user explicitly requests, planning multi-step tasks) and 'DO NOT use when' exclusions (e.g., user hasn't explicitly asked, trivial tasks). It also implicitly distinguishes from siblings by focusing on creation rather than modification or retrieval.

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