Skip to main content
Glama

update_todo

Modify todo items by updating fields, searching content, or managing tags to keep tasks organized and current.

Instructions

Update fields on a todo item (supports search and tag ops)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Core handler function that processes the update_todo input, resolves the todo selector, builds the update payload, calls the storage update function, and constructs the tool response.
    async function handleUpdateTodo(
      input: UpdateTodoInput
    ): Promise<CallToolResult> {
      const selector =
        input.id !== undefined ? { id: input.id } : { query: input.query };
      const outcome = await updateTodoBySelector(toResolveInput(selector), (todo) =>
        buildUpdatePayload(todo, input)
      );
      if (outcome.kind === 'error' || outcome.kind === 'ambiguous') {
        return outcome.response;
      }
      if (outcome.kind === 'no_updates') {
        return createErrorResponse('E_BAD_REQUEST', 'No fields provided to update');
      }
    
      return createToolResponse({
        ok: true,
        result: {
          item: outcome.todo,
          summary: `Updated todo "${outcome.todo.title}"`,
          nextActions: ['list_todos', 'complete_todo'],
        },
      });
    }
  • Defines the input schema for update_todo tool, including selector (by ID or query) and update fields like title, description, status, tags with clear and tagOps support.
    const updateTodoSelector = buildSelectorSchemas(
      'The ID of the todo to update',
      'Search text to find a single todo to update'
    );
    
    const UpdateTodoFieldsSchema = {
      title: z.string().min(1).max(200).optional().describe('New title'),
      description: z.string().max(2000).optional().describe('New description'),
      completed: z.boolean().optional().describe('Completion status'),
      priority: z
        .enum(['low', 'normal', 'high'])
        .optional()
        .describe('New priority level'),
      dueDate: IsoDateSchema.optional().describe('New due date (ISO format)'),
      tags: z.array(TagSchema).max(50).optional().describe('New tags'),
      clearFields: z
        .array(z.enum(['description', 'dueDate', 'tags']))
        .max(3)
        .optional()
        .describe('Fields to clear'),
      tagOps: TagOpsSchema.optional().describe('Tag modifications to apply'),
    };
    
    export const UpdateTodoSchema: ZodType<UpdateTodoInput> = z.union([
      updateTodoSelector.byId.extend(UpdateTodoFieldsSchema),
      updateTodoSelector.byQuery.extend(UpdateTodoFieldsSchema),
    ]);
  • Registers the 'update_todo' tool on the MCP server with title, description, input/output schemas, annotations, and the async handler function.
    export function registerUpdateTodo(server: McpServer): void {
      server.registerTool(
        'update_todo',
        {
          title: 'Update Todo',
          description: 'Update fields on a todo item (supports search and tag ops)',
          inputSchema: UpdateTodoSchema,
          outputSchema: DefaultOutputSchema,
          annotations: {
            readOnlyHint: false,
            idempotentHint: true,
          },
        },
        async (input) => {
          try {
            return await handleUpdateTodo(input);
          } catch (err) {
            return createErrorResponse('E_UPDATE_TODO', getErrorMessage(err));
          }
        }
      );
    }
  • Imports and calls registerUpdateTodo as part of registering all tools.
    import { registerUpdateTodo } from './update_todo.js';
    
    export function registerAllTools(server: McpServer): void {
      registerAddTodo(server);
      registerAddTodos(server);
      registerListTodos(server);
      registerUpdateTodo(server);
  • Helper function that resolves a todo by selector, builds updates via callback, applies the update if changes exist, and returns the outcome used by the handler.
    export async function updateTodoBySelector(
      input: ResolveTodoInput,
      buildUpdates: (todo: Todo) => TodoUpdate | null
    ): Promise<UpdateTodoOutcome> {
      return withTodos<UpdateTodoOutcome>((todos) => {
        const outcome = unwrapResolution(resolveTodoTargetFromTodos(todos, input));
        if (outcome.kind !== 'match') {
          return { todos, result: outcome };
        }
    
        const updates = buildUpdates(outcome.todo);
        if (!updates || Object.keys(updates).length === 0) {
          return { todos, result: { kind: 'no_updates' } };
        }
    
        const updated = applyUpdateToTodos(todos, outcome.todo.id, updates);
        if (!updated.result) {
          return {
            todos,
            result: createNotFoundOutcome(outcome.todo.id),
          };
        }
    
        return {
          todos: updated.todos,
          result: { kind: 'match', todo: updated.result },
        };
      });

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/j0hanz/todokit-mcp-server'

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