Skip to main content
Glama
guifelix

MCP Todo.txt Integration

add-task

Add a new task to a Todo.txt file with optional priority, contexts, and projects. Specify a plain text description and format tags with @ for contexts and + for projects.

Instructions

Add a new task to the todo list. Description must be plain text. Priority must be a single uppercase letter (A-Z). Contexts must start with @, projects with +.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
descriptionYes
priorityNo
contextsNo
projectsNo
extensionsNo

Implementation Reference

  • The handler function for the 'add-task' tool. Validates inputs defensively, loads existing tasks, creates a new Item with the provided description and optional properties (priority, contexts, projects, extensions), appends it to the list, saves to file, and returns success message with new task ID.
    async ({ description, priority, contexts, projects, extensions }) => {
        // Handler-level validation (defensive)
        if (priority && typeof priority === "string" && !/^[A-Z]$/.test(priority)) {
            return { content: [{ type: "text", text: "Invalid priority: must be a single uppercase letter (A-Z)." }], isError: true };
        }
        if (Array.isArray(contexts) && contexts.some((ctx: string) => !/^@\w+$/.test(ctx))) {
            return { content: [{ type: "text", text: "Invalid context: must start with @ and contain only word characters." }], isError: true };
        }
        if (Array.isArray(projects) && projects.some((proj: string) => !/^\+\w+$/.test(proj))) {
            return { content: [{ type: "text", text: "Invalid project: must start with + and contain only word characters." }], isError: true };
        }
        const tasks = await loadTasks();
        const newTask = new Item(description as string);
        if (priority && typeof priority === "string") newTask.setPriority(priority);
        if (Array.isArray(contexts)) contexts.forEach((context: string) => newTask.addContext(context));
        if (Array.isArray(projects)) projects.forEach((project: string) => newTask.addProject(project));
        if (extensions) {
            Object.entries(extensions).forEach(([key, value]) => newTask.setExtension(key as string, value as string));
        }
        tasks.push(newTask);
        await saveTasks(tasks);
        return {
            content: [
                { type: "text", text: `Task added successfully. ID: ${tasks.length - 1}` },
            ],
        };
    }
  • Input schema for 'add-task' tool using Zod: required description (non-empty, single-line <=200 chars), optional priority (single A-Z), contexts (array of @word), projects (+word), extensions (object).
    {
        description: z.string().min(1, "Description cannot be empty").max(200, "Description too long").regex(/^[^\n\r]+$/, "Description must be a single line"),
        priority: z.string().regex(/^[A-Z]$/, "Priority must be a single uppercase letter (A-Z)").optional(),
        contexts: z.array(z.string().regex(/^@\w+$/, "Contexts must start with @ and contain only word characters")).optional(),
        projects: z.array(z.string().regex(/^\+\w+$/, "Projects must start with + and contain only word characters")).optional(),
        extensions: z.record(z.string(), z.string()).optional(),
    },
  • src/tools.ts:20-22 (registration)
    Registration of the 'add-task' tool via server.tool() call, providing name, description, schema, and handler.
    server.tool(
        "add-task",
        "Add a new task to the todo list. Description must be plain text. Priority must be a single uppercase letter (A-Z). Contexts must start with @, projects with +.",
  • Helper function saveTasks used by 'add-task' (and others) to persist the updated task list to the TODO_FILE_PATH.
    async function saveTasks(tasks: Item[]) {
        const content = tasks.map((task) => task.toString()).join("\n");
        await fs.writeFile(TODO_FILE_PATH, content, "utf-8");
    }
Behavior2/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 mentions that the tool adds a task but doesn't cover critical aspects like whether this is a write operation (implied but not stated), what permissions are needed, how errors are handled, or what the response looks like. The description provides some formatting rules but lacks broader behavioral context.

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?

The description is extremely concise and front-loaded, with every sentence providing essential information. The first sentence states the purpose, and subsequent sentences directly explain parameter constraints without any filler or redundant text. It efficiently communicates all necessary details in minimal space.

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

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (5 parameters, no output schema, no annotations), the description does well on parameter semantics but lacks completeness in other areas. It doesn't explain the tool's behavior beyond parameter formatting, such as what happens after adding (e.g., success response, error cases) or how it interacts with sibling tools. The absence of annotations and output schema increases the need for more behavioral context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates fully by explaining the semantics of all parameters: 'description must be plain text', 'priority must be a single uppercase letter', 'contexts must start with @', and 'projects with +'. It adds crucial formatting rules not evident from the schema patterns alone, making parameter usage clear.

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 action ('Add a new task') and the target resource ('to the todo list'), distinguishing it from sibling tools like 'update-task' or 'complete-task' which modify existing tasks rather than creating new ones. It specifies the exact operation without ambiguity.

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 for creating new tasks but doesn't explicitly state when to use this tool versus alternatives like 'update-task' for modifying existing tasks or 'batch-operations' for bulk additions. No guidance is provided on prerequisites or exclusions, leaving the agent to infer context from sibling tool names.

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

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/guifelix/mcp-server-todotxt'

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