Files
claude-task-master/mcp-server/src/tools/update.js
Eyal Toledano 9d437f8594 refactor(mcp): apply withNormalizedProjectRoot HOF to update tool
Problem: The  MCP tool previously handled project root acquisition and path resolution within its  method, leading to potential inconsistencies and repetition.

Solution: Refactored the  tool () to utilize the new  Higher-Order Function (HOF) from .

Specific Changes:
- Imported  HOF.
- Updated the Zod schema for the  parameter to be optional, as the HOF handles deriving it from the session if not provided.
- Wrapped the entire  function body with the  HOF.
- Removed the manual call to  from within the  function body.
- Destructured the  from the  object received by the wrapped  function, ensuring it's the normalized path provided by the HOF.
- Used the normalized  variable when calling  and when passing arguments to .

This change standardizes project root handling for the  tool, simplifies its  method, and ensures consistent path normalization. This serves as the pattern for refactoring other MCP tools.
2025-05-02 02:14:32 -04:00

95 lines
2.6 KiB
JavaScript

/**
* tools/update.js
* Tool to update tasks based on new context/prompt
*/
import { z } from 'zod';
import {
handleApiResult,
createErrorResponse,
withNormalizedProjectRoot
} from './utils.js';
import { updateTasksDirect } from '../core/task-master-core.js';
import { findTasksJsonPath } from '../core/utils/path-utils.js';
/**
* Register the update tool with the MCP server
* @param {Object} server - FastMCP server instance
*/
export function registerUpdateTool(server) {
server.addTool({
name: 'update',
description:
"Update multiple upcoming tasks (with ID >= 'from' ID) based on new context or changes provided in the prompt. Use 'update_task' instead for a single specific task or 'update_subtask' for subtasks.",
parameters: z.object({
from: z
.string()
.describe(
"Task ID from which to start updating (inclusive). IMPORTANT: This tool uses 'from', not 'id'"
),
prompt: z
.string()
.describe('Explanation of changes or new context to apply'),
research: z
.boolean()
.optional()
.describe('Use Perplexity AI for research-backed updates'),
file: z
.string()
.optional()
.describe('Path to the tasks file relative to project root'),
projectRoot: z
.string()
.optional()
.describe(
'The directory of the project. (Optional, usually from session)'
)
}),
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
const toolName = 'update';
const { from, prompt, research, file, projectRoot } = args;
try {
log.info(
`Executing ${toolName} tool with normalized root: ${projectRoot}`
);
let tasksJsonPath;
try {
tasksJsonPath = findTasksJsonPath({ projectRoot, file }, log);
log.info(`${toolName}: Resolved tasks path: ${tasksJsonPath}`);
} catch (error) {
log.error(`${toolName}: Error finding tasks.json: ${error.message}`);
return createErrorResponse(
`Failed to find tasks.json within project root '${projectRoot}': ${error.message}`
);
}
const result = await updateTasksDirect(
{
tasksJsonPath: tasksJsonPath,
from: from,
prompt: prompt,
research: research,
projectRoot: projectRoot
},
log,
{ session }
);
log.info(
`${toolName}: Direct function result: success=${result.success}`
);
return handleApiResult(result, log, 'Error updating tasks');
} catch (error) {
log.error(
`Critical error in ${toolName} tool execute: ${error.message}`
);
return createErrorResponse(
`Internal tool error (${toolName}): ${error.message}`
);
}
})
});
}