asana_update_task
Modify existing task details including name, description, due date, assignee, completion status, and custom fields in Asana projects.
Instructions
Update an existing task's details
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes | The task ID to update | |
| name | No | New name for the task | |
| notes | No | New description for the task | |
| due_on | No | New due date in YYYY-MM-DD format | |
| assignee | No | New assignee (can be 'me' or a user ID) | |
| completed | No | Mark task as completed or not | |
| resource_subtype | No | The type of the task. Can be one of 'default_task' or 'milestone' | |
| custom_fields | No | Object mapping custom field GID strings to their values. For enum fields use the enum option GID as the value. |
Input Schema (JSON Schema)
{
"properties": {
"assignee": {
"description": "New assignee (can be 'me' or a user ID)",
"type": "string"
},
"completed": {
"description": "Mark task as completed or not",
"type": "boolean"
},
"custom_fields": {
"description": "Object mapping custom field GID strings to their values. For enum fields use the enum option GID as the value.",
"type": "object"
},
"due_on": {
"description": "New due date in YYYY-MM-DD format",
"type": "string"
},
"name": {
"description": "New name for the task",
"type": "string"
},
"notes": {
"description": "New description for the task",
"type": "string"
},
"resource_subtype": {
"description": "The type of the task. Can be one of 'default_task' or 'milestone'",
"type": "string"
},
"task_id": {
"description": "The task ID to update",
"type": "string"
}
},
"required": [
"task_id"
],
"type": "object"
}
Implementation Reference
- src/asana-client-wrapper.ts:388-422 (handler)Core handler function that processes the update data (including custom fields via field-utils helper), constructs the API request body, and calls the Asana TasksApi.updateTask method to perform the task update.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; } }
- src/tools/task-tools.ts:324-365 (schema)Tool definition including name, description, and input schema for parameter validation.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"] } };
- src/tool-handler.ts:190-196 (handler)MCP tool dispatcher case that destructures input arguments and delegates execution to AsanaClientWrapper.updateTask.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) }], }; }
- src/tool-handler.ts:61-103 (registration)Registration of the tool in the global tools array exported for MCP server listing.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 ];
- src/utils/validation.ts:220-223 (helper)Input validation specifically for task_id GID format in validateTaskParameters.case 'asana_update_task': result = validateGid(params.task_id, 'task_id'); if (!result.valid) errors.push(...result.errors); break;