asana_create_task
Create a new task in an Asana project with details like name, description, due date, assignee, and custom fields to organize work and track progress.
Instructions
Create a new task in a project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | The project to create the task in | |
| name | Yes | Name of the task | |
| notes | No | Description of the task | |
| html_notes | No | HTML-like formatted description of the task. Does not support ALL HTML tags. Only a subset. The only allowed TAG in the HTML are: <body> <h1> <h2> <ol> <ul> <li> <strong> <em> <u> <s> <code> <pre> <blockquote> <a data-asana-type="" data-asana-gid=""> <hr> <img> <table> <tr> <td>. No other tags are allowed. Use the \n to create a newline. Do not use \n after <body>. Example: <body><h1>Motivation</h1> A customer called in to complain <h1>Goal</h1> Fix the problem</body> | |
| due_on | No | Due date in YYYY-MM-DD format | |
| assignee | No | Assignee (can be 'me' or a user ID) | |
| followers | No | Array of user IDs to add as followers | |
| parent | No | The parent task ID to set this task under | |
| projects | No | Array of project IDs to add this task to | |
| 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. |
Implementation Reference
- src/tool-handler.ts:140-178 (handler)Main execution handler for the 'asana_create_task' tool. Destructures input args into project_id and taskData, calls AsanaClientWrapper.createTask, and provides specialized error handling for HTML notes validation using validateAsanaXml.case "asana_create_task": { const { project_id, ...taskData } = args; try { const response = await asanaClient.createTask(project_id, taskData); return { content: [{ type: "text", text: JSON.stringify(response) }], }; } catch (error) { // When error occurs and html_notes was provided, validate it if (taskData.html_notes && error instanceof Error && [400, 500].includes(error.status)) { const xmlValidationErrors = validateAsanaXml(taskData.html_notes); if (xmlValidationErrors.length > 0) { // Provide detailed validation errors to help the user return { content: [{ type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error), validation_errors: xmlValidationErrors, message: "The HTML notes contain invalid XML formatting. Please check the validation errors above." }) }], }; } else { // HTML is valid, something else caused the error return { content: [{ type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error), html_notes_validation: "The HTML notes format is valid. The error must be related to something else." }) }], }; } } throw error; // re-throw to be caught by the outer try/catch } }
- src/tools/task-tools.ts:263-322 (schema)Defines the Tool metadata including name, description, and comprehensive inputSchema with properties like project_id, name, notes, html_notes, due_on, assignee, custom_fields, etc., and required fields.export const createTaskTool: Tool = { name: "asana_create_task", description: "Create a new task in a project", inputSchema: { type: "object", properties: { project_id: { type: "string", description: "The project to create the task in" }, name: { type: "string", description: "Name of the task" }, notes: { type: "string", description: "Description of the task" }, html_notes: { type: "string", description: "HTML-like formatted description of the task. Does not support ALL HTML tags. Only a subset. The only allowed TAG in the HTML are: <body> <h1> <h2> <ol> <ul> <li> <strong> <em> <u> <s> <code> <pre> <blockquote> <a data-asana-type=\"\" data-asana-gid=\"\"> <hr> <img> <table> <tr> <td>. No other tags are allowed. Use the \\n to create a newline. Do not use \\n after <body>. Example: <body><h1>Motivation</h1>\nA customer called in to complain\n<h1>Goal</h1>\nFix the problem</body>" }, due_on: { type: "string", description: "Due date in YYYY-MM-DD format" }, assignee: { type: "string", description: "Assignee (can be 'me' or a user ID)" }, followers: { type: "array", items: { type: "string" }, description: "Array of user IDs to add as followers" }, parent: { type: "string", description: "The parent task ID to set this task under" }, projects: { type: "array", items: { type: "string" }, description: "Array of project IDs to add this task to" }, 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: ["project_id", "name"] } };
- src/tool-handler.ts:38-61 (registration)Registers the createTaskTool (asana_create_task) by including it in the all_tools array, which is filtered based on read-only mode and exported as list_of_tools for the MCP server.const all_tools: Tool[] = [ listWorkspacesTool, searchProjectsTool, searchTasksTool, getTaskTool, createTaskTool, getStoriesForTaskTool, updateTaskTool, getProjectTool, getProjectTaskCountsTool, getProjectSectionsTool, createTaskStoryTool, addTaskDependenciesTool, addTaskDependentsTool, createSubtaskTool, getMultipleTasksByGidTool, getProjectStatusTool, getProjectStatusesForProjectTool, createProjectStatusTool, deleteProjectStatusTool, setParentForTaskTool, getTasksForTagTool, getTagsForWorkspaceTool, ];
- src/asana-client-wrapper.ts:122-141 (helper)Supporting method in AsanaClientWrapper that prepares task creation data (adds project to projects array if missing, sets defaults for resource_subtype and custom_fields), then delegates to the Asana SDK TasksApi.createTask.async createTask(projectId: string, data: any) { // Ensure projects array includes the projectId const projects = data.projects || []; if (!projects.includes(projectId)) { projects.push(projectId); } const taskData = { data: { ...data, projects, // Handle resource_subtype if provided resource_subtype: data.resource_subtype || 'default_task', // Handle custom_fields if provided custom_fields: data.custom_fields || {} } }; const response = await this.tasks.createTask(taskData); return response.data; }