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, } }

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