Skip to main content
Glama

tasks_add

Add new tasks to the MCP Tasks server with specified status and optional positioning. Supports batch operations for efficient task creation.

Instructions

Add new tasks with a specific status. It's faster and cheaper if you use this in batch. User can add atomically while AI works using the CLI add tool

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
source_idNoSource ID from task_setup() response - Defaults to most recent in the workspace if not provided - Try to always provide it! - If you don't have it, ask the user for a file path and call task_setup()
textsYesEach text becomes a task
statusYesYou might need to infer it from the context: - "To Do" for tasks coming up next (e.g. "Do X next") - "In Progress" for what you'll do now (e.g. "First do X") - "Reminders" instructions for you (the AI) to be constantly reminded of - "Notes" to collect non-actionable notes
indexNo0-based index to place the tasks. e.g.: - 0 for "Do this next" - Omit to place at the end ("Do this later")

Implementation Reference

  • Core handler logic for tasks_add (internally 'add' tool). Loads metadata, removes duplicates, handles special statuses, applies auto-WIP rules, inserts tasks at index, saves state, and returns updated summary.
    handler: (args, context) => {
      let meta = metadata.load(args.source_id)
      const { source, state } = meta
      const { texts, status } = args
      // Remove existing tasks with same text from all groups (duplicate handling)
      for (const groupName of meta.statuses) {
        if (state.groups[groupName]) {
          state.groups[groupName] = state.groups[groupName].filter(text => !texts.includes(text))
        }
      }
      let group = state.groups[status]
      // Special handling for Deleted and other unknown statuses
      if (!group) {
        storage.save(source.path, state)
        return getSummary(source.id)
      }
      const wip = state.groups[env.STATUS_WIP]
      const todos = state.groups[env.STATUS_TODO]
      if (env.AUTO_WIP && args.status === env.STATUS_WIP) {
        // Move all WIP but the first to ToDo
        todos.unshift(...wip)
        wip.length = 0
      }
    
      // Add new tasks at the specified index
      const index = util.clamp(args.index ?? group.length, 0, group.length)
      group.splice(index, 0, ...texts)
      const isUpdate = !!context?.update
      if (env.AUTO_WIP && !wip.length && todos[0] && (todos[0] !== texts[0] || isUpdate)) {
        // Move first ToDo to WIP (but not for updates)
        wip.push(todos.shift()!)
      }
      storage.save(source.path, state)
      // Re-load metadata after state changes
      meta = metadata.load(source.id)
      const affected = _.compact(texts.map(t => meta.tasksByIdOrText[t]))
      return getSummary(source.id, { [isUpdate ? 'updated' : 'added']: affected })
    },
  • Input schema for tasks_add tool using Zod: requires source_id, texts (array of strings), status, optional index.
    schema: z.object({
      source_id: schemas.sourceId,
      texts: z.array(z.string().min(1)).describe('Each text becomes a task'),
      status: schemas.status,
      index: schemas.index,
    }),
  • src/server.ts:16-42 (registration)
    Generic registration loop that adds the tasks_add tool (and others) to the FastMCP server via server.addTool, using the tool's name (tasks_add), description, schema, and cli.runTool for execution.
    for (const tool of Object.values(tools)) {
      if (!tool.isEnabled) {
        continue
      }
      if (tool.isResource) {
        // Register as resource
        server.addResource({
          uri: `resource://${tool.name}`,
          name: tool.description,
          mimeType: 'text/plain',
          load: () => cli.runTool(tool, []).then(text => ({ text })),
        })
      } else {
        // Register as tool with enhanced logging
        server.addTool({
          annotations: {
            openWorldHint: false, // This tool doesn't interact with external systems
            readOnlyHint: tool.isReadOnly,
            title: tool.name,
          },
          name: tool.name,
          description: tool.description,
          parameters: tool.schema,
          execute: (args) => cli.runTool(tool, args),
        })
      }
    }
  • src/tools.ts:68-115 (registration)
    Tool definition for 'add', which is renamed to 'tasks_add' by defineTool due to PREFIX_TOOLS=true, and added to the exported tools object.
    add: defineTool('add', {
      schema: z.object({
        source_id: schemas.sourceId,
        texts: z.array(z.string().min(1)).describe('Each text becomes a task'),
        status: schemas.status,
        index: schemas.index,
      }),
      fromArgs: ([text, status = env.STATUS_TODO, index]) => ({ texts: [text], status, index: index ? Number(index) : undefined }),
      description: 'Add new tasks with a specific status. It\'s faster and cheaper if you use this in batch. User can add atomically while AI works using the CLI add tool',
      handler: (args, context) => {
        let meta = metadata.load(args.source_id)
        const { source, state } = meta
        const { texts, status } = args
        // Remove existing tasks with same text from all groups (duplicate handling)
        for (const groupName of meta.statuses) {
          if (state.groups[groupName]) {
            state.groups[groupName] = state.groups[groupName].filter(text => !texts.includes(text))
          }
        }
        let group = state.groups[status]
        // Special handling for Deleted and other unknown statuses
        if (!group) {
          storage.save(source.path, state)
          return getSummary(source.id)
        }
        const wip = state.groups[env.STATUS_WIP]
        const todos = state.groups[env.STATUS_TODO]
        if (env.AUTO_WIP && args.status === env.STATUS_WIP) {
          // Move all WIP but the first to ToDo
          todos.unshift(...wip)
          wip.length = 0
        }
    
        // Add new tasks at the specified index
        const index = util.clamp(args.index ?? group.length, 0, group.length)
        group.splice(index, 0, ...texts)
        const isUpdate = !!context?.update
        if (env.AUTO_WIP && !wip.length && todos[0] && (todos[0] !== texts[0] || isUpdate)) {
          // Move first ToDo to WIP (but not for updates)
          wip.push(todos.shift()!)
        }
        storage.save(source.path, state)
        // Re-load metadata after state changes
        meta = metadata.load(source.id)
        const affected = _.compact(texts.map(t => meta.tasksByIdOrText[t]))
        return getSummary(source.id, { [isUpdate ? 'updated' : 'added']: affected })
      },
    }),
  • defineTool helper that prefixes tool names with 'tasks_' (e.g., 'add' -> 'tasks_add') if PREFIX_TOOLS is true, and sets other properties.
    function defineTool<S extends ZodSchema>(name: string, tool: {
      schema: S
      description: string
      isResource?: boolean
      isReadOnly?: boolean
      isEnabled?: boolean
      handler: (args: z.infer<S>, context?: any) => any
      fromArgs: (args: string[]) => z.infer<S>
    }) {
      const toolName = env.PREFIX_TOOLS ? `tasks_${name}` : name
      return {
        ...tool,
        name: toolName,
        isResource: tool.isResource ?? false,
        isReadOnly: tool.isReadOnly ?? false,
        isEnabled: tool.isEnabled ?? true,
      }
    }
Behavior3/5

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

Annotations indicate readOnlyHint=false and openWorldHint=false, confirming this is a write operation with closed-world behavior. The description adds value by noting batch efficiency and atomic CLI usage, but doesn't disclose critical behavioral traits like error handling, rate limits, or mutation effects beyond what annotations imply. No contradiction with annotations exists.

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

Conciseness3/5

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

The description is relatively concise but could be more front-loaded. The first sentence states the purpose, but the second sentence about batch efficiency and CLI usage, while useful, adds some redundancy. It's not overly verbose but lacks optimal structure for quick scanning.

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 tool's complexity (4 parameters, write operation) and lack of output schema, the description is moderately complete. It covers basic purpose and usage hints but misses details on return values, error conditions, and sibling tool differentiation. Annotations provide some context, but more behavioral disclosure would improve completeness.

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 fully documents all parameters. The description doesn't add any parameter-specific semantics beyond what's in the schema (e.g., it doesn't explain 'texts' or 'status' beyond the schema's enum descriptions). Baseline score of 3 applies as the schema carries the full burden.

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

Purpose4/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: 'Add new tasks with a specific status.' It specifies the verb ('Add') and resource ('tasks'), and mentions batch capability. However, it doesn't explicitly differentiate from sibling tools like tasks_update or tasks_setup, which could handle similar operations.

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 provides some usage context: 'It's faster and cheaper if you use this in batch' and mentions the CLI add tool for atomic operations. However, it lacks explicit guidance on when to use this tool versus alternatives like tasks_update or tasks_setup, and doesn't clarify prerequisites or exclusions beyond the batch efficiency note.

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/flesler/mcp-tasks'

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