Skip to main content
Glama
Leanware-io

ClickUp MCP Integration

by Leanware-io

clickup_update_task

Modify ClickUp task details including name, description, priority, due dates, tags, time estimates, assignees, and parent relationships by providing the task ID.

Instructions

Update a task by its ID

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
task_idYesClickUp task ID
nameNoTask name
markdown_descriptionNoTask description in markdown format
priorityNoTask priority (1-4): 1=Urgent, 2=High, 3=Normal, 4=Low
due_dateNoDue date as Unix timestamp in milliseconds
tagsNoArray of tag names to add to the task
time_estimateNoTime estimate in milliseconds
assigneesNoUser IDs to add or remove from the task
parentNoParent task ID to move this task as a subtask

Implementation Reference

  • Full definition of the 'clickup_update_task' tool, including name, input schema, description, and handler function that maps inputs to UpdateTaskParams and calls taskService.updateTask
    const updateTaskTool = defineTool((z) => ({
      name: "clickup_update_task",
      description: "Update a task by its ID",
      inputSchema: {
        task_id: z.string().describe("ClickUp task ID"),
        name: z.string().optional().describe("Task name"),
        markdown_description: z
          .string()
          .optional()
          .describe("Task description in markdown format"),
        priority: z
          .number()
          .optional()
          .describe("Task priority (1-4): 1=Urgent, 2=High, 3=Normal, 4=Low"),
        due_date: z
          .number()
          .optional()
          .describe("Due date as Unix timestamp in milliseconds"),
        tags: z
          .array(z.string())
          .optional()
          .describe("Array of tag names to add to the task"),
        time_estimate: z
          .number()
          .optional()
          .describe("Time estimate in milliseconds"),
        assignees: z
          .object({
            add: z
              .array(z.number())
              .optional()
              .describe("Array of user IDs to add to the task"),
            rem: z
              .array(z.number())
              .optional()
              .describe("Array of user IDs to remove from the task"),
          })
          .optional()
          .describe("User IDs to add or remove from the task"),
        parent: z
          .string()
          .optional()
          .describe("Parent task ID to move this task as a subtask"),
      },
      handler: async (input): Promise<any> => {
        const { task_id, ...updateData } = input;
        const taskParams: UpdateTaskParams = {
          name: updateData.name,
          markdown_description: updateData.markdown_description,
          priority: updateData.priority,
          due_date: updateData.due_date,
          tags: updateData.tags,
          time_estimate: updateData.time_estimate,
          assignees: updateData.assignees,
          parent: updateData.parent,
        };
    
        const response = await taskService.updateTask(task_id, taskParams);
        return {
          content: [{ type: "text", text: JSON.stringify(response) }],
        };
      },
    }));
  • The TaskService.updateTask helper method that sends a PUT request to the ClickUp API to update the specified task.
    async updateTask(
      taskId: string,
      params: UpdateTaskParams
    ): Promise<ClickUpTask> {
      return this.request<ClickUpTask>(`/task/${taskId}`, {
        method: "PUT",
        body: JSON.stringify(params),
      });
    }
  • src/index.ts:89-91 (registration)
    Registration loop where all imported tools, including 'clickup_update_task', are registered on the MCP server using server.tool()
    tools.forEach((tool) => {
      server.tool(tool.name, tool.description, tool.inputSchema, tool.handler);
    });
  • Private request helper method in TaskService used by updateTask to make HTTP requests to ClickUp API.
    private async request<T>(
      endpoint: string,
      options: RequestInit = {}
    ): Promise<T> {
      const response = await fetch(`${BASE_URL}${endpoint}`, {
        ...options,
        headers: this.headers,
      });
      return response.json();
    }
  • Zod-based input schema for validating parameters to the clickup_update_task tool.
    inputSchema: {
      task_id: z.string().describe("ClickUp task ID"),
      name: z.string().optional().describe("Task name"),
      markdown_description: z
        .string()
        .optional()
        .describe("Task description in markdown format"),
      priority: z
        .number()
        .optional()
        .describe("Task priority (1-4): 1=Urgent, 2=High, 3=Normal, 4=Low"),
      due_date: z
        .number()
        .optional()
        .describe("Due date as Unix timestamp in milliseconds"),
      tags: z
        .array(z.string())
        .optional()
        .describe("Array of tag names to add to the task"),
      time_estimate: z
        .number()
        .optional()
        .describe("Time estimate in milliseconds"),
      assignees: z
        .object({
          add: z
            .array(z.number())
            .optional()
            .describe("Array of user IDs to add to the task"),
          rem: z
            .array(z.number())
            .optional()
            .describe("Array of user IDs to remove from the task"),
        })
        .optional()
        .describe("User IDs to add or remove from the task"),
      parent: z
        .string()
        .optional()
        .describe("Parent task ID to move this task as a subtask"),
    },
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. 'Update' implies a mutation operation, but the description doesn't disclose any behavioral traits: it doesn't mention authentication requirements, rate limits, partial vs. full updates, error handling, or what happens to unspecified fields. This leaves significant gaps for a mutation tool.

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 a single, efficient sentence that states the core purpose without any fluff. It's appropriately sized and front-loaded, with every word earning its place. No structural issues or unnecessary elaboration.

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

Completeness2/5

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

For a mutation tool with 9 parameters, no annotations, and no output schema, the description is incomplete. It doesn't address behavioral aspects like side effects, error conditions, or response format. The agent lacks context about what a successful update entails or how to handle failures.

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?

The schema description coverage is 100%, with each parameter well-documented in the schema itself (e.g., priority mapping, timestamp format). The description adds no additional parameter semantics beyond what's in the schema, so it meets the baseline of 3 where the schema does the heavy lifting.

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 verb ('Update') and resource ('a task by its ID'), making the purpose immediately understandable. It distinguishes this from creation tools like 'clickup_create_task' by specifying it updates existing tasks. However, it doesn't specify what fields can be updated, which prevents a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'clickup_update_task_by_custom_id' or 'clickup_set_custom_field_value', nor does it indicate prerequisites (e.g., needing an existing task ID). The agent must infer usage from the tool name alone.

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/Leanware-io/clickup-mcp-server'

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