asana_create_subtask
Create a subtask under an existing Asana task to break down work into manageable steps, assign responsibilities, and track progress with due dates and detailed descriptions.
Instructions
Create a new subtask for an existing task
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| assignee | No | Assignee (can be 'me' or a user ID) | |
| due_on | No | Due date in YYYY-MM-DD format | |
| html_notes | No | HTML-like formatted description of the subtask. 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> | |
| name | Yes | Name of the subtask | |
| notes | No | Description of the subtask | |
| opt_fields | No | Comma-separated list of optional fields to include | |
| parent_task_id | Yes | The parent task ID to create the subtask under |
Input Schema (JSON Schema)
{
"properties": {
"assignee": {
"description": "Assignee (can be 'me' or a user ID)",
"type": "string"
},
"due_on": {
"description": "Due date in YYYY-MM-DD format",
"type": "string"
},
"html_notes": {
"description": "HTML-like formatted description of the subtask. 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>",
"type": "string"
},
"name": {
"description": "Name of the subtask",
"type": "string"
},
"notes": {
"description": "Description of the subtask",
"type": "string"
},
"opt_fields": {
"description": "Comma-separated list of optional fields to include",
"type": "string"
},
"parent_task_id": {
"description": "The parent task ID to create the subtask under",
"type": "string"
}
},
"required": [
"parent_task_id",
"name"
],
"type": "object"
}
Implementation Reference
- src/tool-handler.ts:342-382 (handler)Executes the tool logic: extracts parameters, validates HTML notes if provided, calls AsanaClientWrapper.createSubtask, handles errors.case "asana_create_subtask": { const { parent_task_id, opt_fields, ...taskData } = args; try { // Validate html_notes if provided if (taskData.html_notes) { const xmlValidationErrors = validateAsanaXml(taskData.html_notes); if (xmlValidationErrors.length > 0) { return { content: [{ type: "text", text: JSON.stringify({ error: "HTML validation failed", validation_errors: xmlValidationErrors, message: "The HTML notes contain invalid XML formatting. Please check the validation errors above." }) }], }; } } const response = await asanaClient.createSubtask(parent_task_id, taskData, { opt_fields }); return { content: [{ type: "text", text: JSON.stringify(response) }], }; } catch (error) { // When error occurs and html_notes was provided, help troubleshoot if (taskData.html_notes && error instanceof Error && error.message.includes('400')) { 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:367-404 (schema)Defines the tool's metadata, description, and input schema for validation.export const createSubtaskTool: Tool = { name: "asana_create_subtask", description: "Create a new subtask for an existing task", inputSchema: { type: "object", properties: { parent_task_id: { type: "string", description: "The parent task ID to create the subtask under" }, name: { type: "string", description: "Name of the subtask" }, notes: { type: "string", description: "Description of the subtask" }, html_notes: { type: "string", description: "HTML-like formatted description of the subtask. 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)" }, opt_fields: { type: "string", description: "Comma-separated list of optional fields to include" } }, required: ["parent_task_id", "name"] } };
- src/tool-handler.ts:37-61 (registration)Registers the createSubtaskTool in the array of all available tools, which is exported for MCP tool discovery.// List of all available tools 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:237-245 (helper)Helper method in AsanaClientWrapper that wraps the Asana SDK's createSubtaskForTask API call.async createSubtask(parentTaskId: string, data: any, opts: any = {}) { const taskData = { data: { ...data } }; const response = await this.tasks.createSubtaskForTask(taskData, parentTaskId, opts); return response.data; }