asana_create_subtask
Create a subtask within an existing Asana task to break down work into manageable components. Specify details like name, description, due date, and assignee to organize project workflows.
Instructions
Create a new subtask for an existing task
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| parent_task_id | Yes | The parent task ID to create the subtask under | |
| name | Yes | Name of the subtask | |
| notes | No | Description of the subtask | |
| 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> | |
| due_on | No | Due date in YYYY-MM-DD format | |
| assignee | No | Assignee (can be 'me' or a user ID) | |
| opt_fields | No | Comma-separated list of optional fields to include |
Implementation Reference
- src/tool-handler.ts:342-382 (handler)Handler function in the main tool switch statement that processes calls to 'asana_create_subtask', performs HTML validation if notes provided, and calls the AsanaClientWrapper.createSubtask method.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)Tool schema definition for 'asana_create_subtask' including input schema with properties like parent_task_id, name, notes, etc.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:38-86 (registration)Registration of the tool in the all_tools array and exported as list_of_tools (filtered for read-only mode if enabled). Note: createSubtaskTool is included at line 52.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, ]; // List of tools that only read Asana state const READ_ONLY_TOOLS = [ 'asana_list_workspaces', 'asana_search_projects', 'asana_search_tasks', 'asana_get_task', 'asana_get_task_stories', 'asana_get_project', 'asana_get_project_task_counts', 'asana_get_project_status', 'asana_get_project_statuses', 'asana_get_project_sections', 'asana_get_multiple_tasks_by_gid', 'asana_get_tasks_for_tag', 'asana_get_tags_for_workspace' ]; // Filter tools based on READ_ONLY_MODE const isReadOnlyMode = process.env.READ_ONLY_MODE === 'true'; // Export filtered list of tools export const list_of_tools = isReadOnlyMode ? all_tools.filter(tool => READ_ONLY_TOOLS.includes(tool.name)) : all_tools;
- src/asana-client-wrapper.ts:237-245 (helper)Helper method in AsanaClientWrapper that wraps the Asana SDK call to createSubtaskForTask, which is invoked by the tool handler.async createSubtask(parentTaskId: string, data: any, opts: any = {}) { const taskData = { data: { ...data } }; const response = await this.tasks.createSubtaskForTask(taskData, parentTaskId, opts); return response.data; }