Skip to main content
Glama
cristip73

MCP Server for Asana

by cristip73

asana_update_task

Modify existing Asana task details including name, description, due date, assignee, completion status, and custom fields to keep project information current.

Instructions

Update an existing task's details

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
task_idYesThe task ID to update
nameNoNew name for the task
notesNoNew description for the task
due_onNoNew due date in YYYY-MM-DD format
assigneeNoNew assignee (can be 'me' or a user ID)
completedNoMark task as completed or not
resource_subtypeNoThe type of the task. Can be one of 'default_task' or 'milestone'
custom_fieldsNoObject mapping custom field GID strings to their values. For enum fields use the enum option GID as the value.

Implementation Reference

  • The switch case handler that executes the "asana_update_task" tool by destructuring the task_id and passing the remaining taskData to asanaClient.updateTask, then returning the JSON-stringified response.
    case "asana_update_task": {
      const { task_id, ...taskData } = args;
      const response = await asanaClient.updateTask(task_id, taskData);
      return {
        content: [{ type: "text", text: JSON.stringify(response) }],
      };
    }
  • The core AsanaClientWrapper.updateTask method that processes input data (including custom fields parsing), constructs the API request body, calls the Asana TasksApi.updateTask, and handles specific errors like custom field issues.
    async updateTask(taskId: string, data: any) {
      // Create a deep clone of the data to avoid modifying the original
      const taskData = JSON.parse(JSON.stringify(data));
      
      // Handle custom fields properly if provided
      if (taskData.custom_fields) {
        try {
          // Import utils only when needed (avoiding circular dependencies)
          const { parseCustomFields } = await import('./utils/field-utils.js');
          taskData.custom_fields = parseCustomFields(taskData.custom_fields);
        } catch (err) {
          throw new Error(`Error processing custom fields: ${(err as Error).message}`);
        }
      }
      
      try {
        const body = {
          data: {
            ...taskData,
            // Handle resource_subtype if provided
            resource_subtype: taskData.resource_subtype || undefined,
          }
        };
        
        const opts = {};
        const response = await this.tasks.updateTask(body, taskId, opts);
        return response.data;
      } catch (error: any) {
        // Add more context for custom field errors
        if (error.message?.includes('custom_field')) {
          throw new Error(`Error updating custom fields: ${error.message}. Make sure you're using the correct format for each field type.`);
        }
        throw error;
      }
    }
  • The complete Tool definition for "asana_update_task" including name, description, and detailed inputSchema specifying required task_id and optional fields like name, notes, due_on, assignee, completed, resource_subtype, and custom_fields.
    export const updateTaskTool: Tool = {
      name: "asana_update_task",
      description: "Update an existing task's details",
      inputSchema: {
        type: "object",
        properties: {
          task_id: {
            type: "string",
            description: "The task ID to update"
          },
          name: {
            type: "string",
            description: "New name for the task"
          },
          notes: {
            type: "string",
            description: "New description for the task"
          },
          due_on: {
            type: "string",
            description: "New due date in YYYY-MM-DD format"
          },
          assignee: {
            type: "string",
            description: "New assignee (can be 'me' or a user ID)"
          },
          completed: {
            type: "boolean",
            description: "Mark task as completed or not"
          },
          resource_subtype: {
            type: "string",
            description: "The type of the task. Can be one of 'default_task' or 'milestone'"
          },
          custom_fields: {
            type: "object",
            description: "Object mapping custom field GID strings to their values. For enum fields use the enum option GID as the value."
          }
        },
        required: ["task_id"]
      }
    };
  • The tools array registration where updateTaskTool is included among all available MCP tools, making it discoverable and callable.
    export const tools: Tool[] = [
      listWorkspacesTool,
      searchProjectsTool,
      getProjectTool,
      getProjectTaskCountsTool,
      getProjectSectionsTool,
      createSectionForProjectTool,
      createProjectForWorkspaceTool,
      updateProjectTool,
      reorderSectionsTool,
      getProjectStatusTool,
      getProjectStatusesForProjectTool,
      createProjectStatusTool,
      deleteProjectStatusTool,
      searchTasksTool,
      getTaskTool,
      createTaskTool,
      updateTaskTool,
      createSubtaskTool,
      getMultipleTasksByGidTool,
      addTaskToSectionTool,
      getTasksForSectionTool,
      getProjectHierarchyTool,
      getSubtasksForTaskTool,
      getTasksForProjectTool,
      getTasksForTagTool,
      getTagsForWorkspaceTool,
      addTagsToTaskTool,
      addTaskDependenciesTool,
      addTaskDependentsTool,
      setParentForTaskTool,
      addFollowersToTaskTool,
      getStoriesForTaskTool,
      createTaskStoryTool,
      getTeamsForUserTool,
      getTeamsForWorkspaceTool,
      addMembersForProjectTool,
      addFollowersForProjectTool,
      getUsersForWorkspaceTool,
      getAttachmentsForObjectTool,
      uploadAttachmentForObjectTool,
      downloadAttachmentTool
    ];
  • Validation logic in validateTaskParameters that ensures task_id is a valid Asana GID for the asana_update_task tool.
    case 'asana_update_task':
      result = validateGid(params.task_id, 'task_id');
      if (!result.valid) errors.push(...result.errors);
      break;

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description carries full responsibility for behavioral disclosure. It only says 'update details' and fails to mention side effects, required permissions, reversibility, or behavior when fields are omitted. For a mutation tool, this is inadequate.

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 compact sentence that is front-loaded with the main action, containing no unnecessary words or repetition.

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?

Despite having 8 parameters and no output schema, the description is too short to convey return values, error behavior, or special considerations like custom field handling. The schema helps but the description alone is insufficient for a tool of this complexity.

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 input schema provides 100% coverage with descriptions for all 8 parameters, so the baseline is 3. The description adds no extra meaning beyond what the schema already offers.

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 uses a clear verb 'update' and identifies the resource as 'an existing task's details', distinguishing it from create_task. However, it doesn't explicitly differentiate from other update-type siblings like set_parent_for_task or add_task_dependencies, so it doesn't get full marks.

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?

No guidance is provided on when to use this tool versus alternatives. It only states the action without mentioning prerequisites, exclusions, or situations where a different tool would be more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.