feat: implement add-task MCP command
- Create direct function wrapper in add-task.js with prompt and dependency handling - Add MCP tool integration for creating new tasks via AI - Update task-master-core.js to expose addTaskDirect function - Update changeset to document the new command
This commit is contained in:
@@ -10,4 +10,5 @@
|
||||
- Implement show-task MCP command for displaying detailed task information
|
||||
- Implement next-task MCP command for finding the next task to work on
|
||||
- Implement expand-task MCP command for breaking down tasks into subtasks
|
||||
- Implement add-task MCP command for creating new tasks using AI assistance
|
||||
- Document MCP server naming conventions in architecture.mdc and mcp.mdc files (file names use kebab-case, direct functions use camelCase with Direct suffix, tool registration functions use camelCase with Tool suffix, and MCP tool names use snake_case)
|
||||
|
||||
67
mcp-server/src/core/direct-functions/add-task.js
Normal file
67
mcp-server/src/core/direct-functions/add-task.js
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* add-task.js
|
||||
* Direct function implementation for adding a new task
|
||||
*/
|
||||
|
||||
import { addTask } from '../../../../scripts/modules/task-manager.js';
|
||||
import { findTasksJsonPath } from '../utils/path-utils.js';
|
||||
|
||||
/**
|
||||
* Direct function wrapper for adding a new task with error handling.
|
||||
*
|
||||
* @param {Object} args - Command arguments
|
||||
* @param {string} args.prompt - Description of the task to add
|
||||
* @param {Array<number>} [args.dependencies=[]] - Task dependencies as array of IDs
|
||||
* @param {string} [args.priority='medium'] - Task priority (high, medium, low)
|
||||
* @param {string} [args.file] - Path to the tasks file
|
||||
* @param {string} [args.projectRoot] - Project root directory
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<Object>} - Result object { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
*/
|
||||
export async function addTaskDirect(args, log) {
|
||||
try {
|
||||
// Resolve the tasks file path
|
||||
const tasksPath = findTasksJsonPath(args.file, args.projectRoot);
|
||||
|
||||
// Check required parameters
|
||||
if (!args.prompt) {
|
||||
log.error('Missing required parameter: prompt');
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'MISSING_PARAMETER',
|
||||
message: 'The prompt parameter is required for adding a task'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Extract and prepare parameters
|
||||
const prompt = args.prompt;
|
||||
const dependencies = Array.isArray(args.dependencies)
|
||||
? args.dependencies
|
||||
: (args.dependencies ? String(args.dependencies).split(',').map(id => parseInt(id.trim(), 10)) : []);
|
||||
const priority = args.priority || 'medium';
|
||||
|
||||
log.info(`Adding new task with prompt: "${prompt}", dependencies: [${dependencies.join(', ')}], priority: ${priority}`);
|
||||
|
||||
// Call the addTask function
|
||||
const newTaskId = await addTask(tasksPath, prompt, dependencies, priority);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
taskId: newTaskId,
|
||||
message: `Successfully added new task #${newTaskId}`
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
log.error(`Error in addTaskDirect: ${error.message}`);
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'ADD_TASK_ERROR',
|
||||
message: error.message
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,28 @@ import { setTaskStatusDirect } from './direct-functions/set-task-status.js';
|
||||
import { showTaskDirect } from './direct-functions/show-task.js';
|
||||
import { nextTaskDirect } from './direct-functions/next-task.js';
|
||||
import { expandTaskDirect } from './direct-functions/expand-task.js';
|
||||
import { addTaskDirect } from './direct-functions/add-task.js';
|
||||
|
||||
// Re-export utility functions
|
||||
export { findTasksJsonPath } from './utils/path-utils.js';
|
||||
|
||||
// Re-export all direct functions
|
||||
// Use Map for potential future enhancements like introspection or dynamic dispatch
|
||||
export const directFunctions = new Map([
|
||||
['listTasksDirect', listTasksDirect],
|
||||
['getCacheStatsDirect', getCacheStatsDirect],
|
||||
['parsePRDDirect', parsePRDDirect],
|
||||
['updateTasksDirect', updateTasksDirect],
|
||||
['updateTaskByIdDirect', updateTaskByIdDirect],
|
||||
['updateSubtaskByIdDirect', updateSubtaskByIdDirect],
|
||||
['generateTaskFilesDirect', generateTaskFilesDirect],
|
||||
['setTaskStatusDirect', setTaskStatusDirect],
|
||||
['showTaskDirect', showTaskDirect],
|
||||
['nextTaskDirect', nextTaskDirect],
|
||||
['expandTaskDirect', expandTaskDirect],
|
||||
['addTaskDirect', addTaskDirect]
|
||||
]);
|
||||
|
||||
// Re-export all direct function implementations
|
||||
export {
|
||||
listTasksDirect,
|
||||
getCacheStatsDirect,
|
||||
@@ -33,23 +50,5 @@ export {
|
||||
showTaskDirect,
|
||||
nextTaskDirect,
|
||||
expandTaskDirect,
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps Task Master functions to their direct implementation
|
||||
* This map is used by tools to look up the appropriate function by name
|
||||
*/
|
||||
export const directFunctions = {
|
||||
list: listTasksDirect,
|
||||
cacheStats: getCacheStatsDirect,
|
||||
parsePRD: parsePRDDirect,
|
||||
update: updateTasksDirect,
|
||||
updateTask: updateTaskByIdDirect,
|
||||
updateSubtask: updateSubtaskByIdDirect,
|
||||
generate: generateTaskFilesDirect,
|
||||
setStatus: setTaskStatusDirect,
|
||||
showTask: showTaskDirect,
|
||||
nextTask: nextTaskDirect,
|
||||
expandTask: expandTaskDirect,
|
||||
// Add more functions as we implement them
|
||||
addTaskDirect
|
||||
};
|
||||
47
mcp-server/src/tools/add-task.js
Normal file
47
mcp-server/src/tools/add-task.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* tools/add-task.js
|
||||
* Tool to add a new task using AI
|
||||
*/
|
||||
|
||||
import { z } from "zod";
|
||||
import {
|
||||
handleApiResult,
|
||||
createErrorResponse
|
||||
} from "./utils.js";
|
||||
import { addTaskDirect } from "../core/task-master-core.js";
|
||||
|
||||
/**
|
||||
* Register the add-task tool with the MCP server
|
||||
* @param {Object} server - FastMCP server instance
|
||||
*/
|
||||
export function registerAddTaskTool(server) {
|
||||
server.addTool({
|
||||
name: "add_task",
|
||||
description: "Add a new task using AI",
|
||||
parameters: z.object({
|
||||
prompt: z.string().describe("Description of the task to add"),
|
||||
dependencies: z.string().optional().describe("Comma-separated list of task IDs this task depends on"),
|
||||
priority: z.string().optional().describe("Task priority (high, medium, low)"),
|
||||
file: z.string().optional().describe("Path to the tasks file"),
|
||||
projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)")
|
||||
}),
|
||||
execute: async ({ prompt, dependencies, priority, file, projectRoot }, log) => {
|
||||
try {
|
||||
log.info(`MCP add_task called with prompt: "${prompt}"`);
|
||||
|
||||
const result = await addTaskDirect({
|
||||
prompt,
|
||||
dependencies,
|
||||
priority,
|
||||
file,
|
||||
projectRoot
|
||||
}, log);
|
||||
|
||||
return handleApiResult(result);
|
||||
} catch (error) {
|
||||
log.error(`Error in add_task MCP tool: ${error.message}`);
|
||||
return createErrorResponse(error.message, "ADD_TASK_ERROR");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import { registerGenerateTool } from "./generate.js";
|
||||
import { registerShowTaskTool } from "./show-task.js";
|
||||
import { registerNextTaskTool } from "./next-task.js";
|
||||
import { registerExpandTaskTool } from "./expand-task.js";
|
||||
import { registerAddTaskTool } from "./add-task.js";
|
||||
|
||||
/**
|
||||
* Register all Task Master tools with the MCP server
|
||||
@@ -30,6 +31,9 @@ export function registerTaskMasterTools(server) {
|
||||
registerShowTaskTool(server);
|
||||
registerNextTaskTool(server);
|
||||
registerExpandTaskTool(server);
|
||||
registerAddTaskTool(server);
|
||||
|
||||
logger.info("Registered all Task Master tools with MCP server");
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@@ -604,7 +604,7 @@ Following MCP implementation standards:
|
||||
- Unit test for expandTaskDirect.js
|
||||
- Integration test for MCP tool
|
||||
|
||||
## 25. Implement add-task MCP command [in-progress]
|
||||
## 25. Implement add-task MCP command [done]
|
||||
### Dependencies: None
|
||||
### Description: Create direct function wrapper and MCP tool for adding new tasks.
|
||||
### Details:
|
||||
|
||||
@@ -1573,7 +1573,7 @@
|
||||
"title": "Implement add-task MCP command",
|
||||
"description": "Create direct function wrapper and MCP tool for adding new tasks.",
|
||||
"details": "Following MCP implementation standards:\n\n1. Create addTaskDirect.js in mcp-server/src/core/direct-functions/:\n - Import addTask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: prompt, priority, dependencies\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n\n2. Export from task-master-core.js:\n - Import the function from its file\n - Add to directFunctions map\n\n3. Create add-task.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import addTaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerAddTaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n4. Register in tools/index.js with tool name 'add_task'\n\n5. Add to .cursor/mcp.json with appropriate schema\n\n6. Write tests following testing guidelines:\n - Unit test for addTaskDirect.js\n - Integration test for MCP tool",
|
||||
"status": "in-progress",
|
||||
"status": "done",
|
||||
"dependencies": [],
|
||||
"parentTaskId": 23
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user