diff --git a/.changeset/two-bats-smoke.md b/.changeset/two-bats-smoke.md index f9463947..9d87411c 100644 --- a/.changeset/two-bats-smoke.md +++ b/.changeset/two-bats-smoke.md @@ -16,6 +16,11 @@ - Parent directory traversal to find tasks.json - Package directory as fallback +- Updated all MCP tools to work without explicitly requiring project root: + - Changed all tool definitions from `projectRoot: z.string().describe(...)` to `projectRoot: z.string().optional().describe(...)` + - Updated all direct function implementations from `findTasksJsonPath(args.file, args.projectRoot)` to use the proper `findTasksJsonPath(args, log)` pattern + - These changes allow MCP tools to work properly without requiring the projectRoot parameter, using smart detection to automatically determine the project root + - Add comprehensive PROJECT_MARKERS array for detecting common project files: - Task Master specific files (tasks.json, tasks/tasks.json) - Version control markers (.git, .svn) diff --git a/mcp-server/src/core/direct-functions/add-subtask.js b/mcp-server/src/core/direct-functions/add-subtask.js index f3a71898..b647984c 100644 --- a/mcp-server/src/core/direct-functions/add-subtask.js +++ b/mcp-server/src/core/direct-functions/add-subtask.js @@ -47,7 +47,7 @@ export async function addSubtaskDirect(args, log) { } // Find the tasks.json path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + const tasksPath = findTasksJsonPath(args, log); // Parse dependencies if provided let dependencies = []; diff --git a/mcp-server/src/core/direct-functions/add-task.js b/mcp-server/src/core/direct-functions/add-task.js index b8ecd71b..ad2a5e51 100644 --- a/mcp-server/src/core/direct-functions/add-task.js +++ b/mcp-server/src/core/direct-functions/add-task.js @@ -20,8 +20,8 @@ import { findTasksJsonPath } from '../utils/path-utils.js'; */ export async function addTaskDirect(args, log) { try { - // Resolve the tasks file path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + // Find the tasks.json path + const tasksPath = findTasksJsonPath(args, log); // Check required parameters if (!args.prompt) { diff --git a/mcp-server/src/core/direct-functions/analyze-task-complexity.js b/mcp-server/src/core/direct-functions/analyze-task-complexity.js index c8f42e28..112dd275 100644 --- a/mcp-server/src/core/direct-functions/analyze-task-complexity.js +++ b/mcp-server/src/core/direct-functions/analyze-task-complexity.js @@ -24,7 +24,7 @@ export async function analyzeTaskComplexityDirect(args, log) { log.info(`Analyzing task complexity with args: ${JSON.stringify(args)}`); // Find the tasks.json path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + const tasksPath = findTasksJsonPath(args, log); // Determine output path let outputPath = args.output || 'scripts/task-complexity-report.json'; diff --git a/mcp-server/src/core/direct-functions/clear-subtasks.js b/mcp-server/src/core/direct-functions/clear-subtasks.js index 1d2f249a..516d55c4 100644 --- a/mcp-server/src/core/direct-functions/clear-subtasks.js +++ b/mcp-server/src/core/direct-functions/clear-subtasks.js @@ -32,7 +32,7 @@ export async function clearSubtasksDirect(args, log) { } // Find the tasks.json path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + const tasksPath = findTasksJsonPath(args, log); // Check if tasks.json exists if (!fs.existsSync(tasksPath)) { diff --git a/mcp-server/src/core/direct-functions/expand-all-tasks.js b/mcp-server/src/core/direct-functions/expand-all-tasks.js index ed49fd10..d2896950 100644 --- a/mcp-server/src/core/direct-functions/expand-all-tasks.js +++ b/mcp-server/src/core/direct-functions/expand-all-tasks.js @@ -22,7 +22,7 @@ export async function expandAllTasksDirect(args, log) { log.info(`Expanding all tasks with args: ${JSON.stringify(args)}`); // Find the tasks.json path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + const tasksPath = findTasksJsonPath(args, log); // Parse parameters const numSubtasks = args.num ? parseInt(args.num, 10) : undefined; diff --git a/mcp-server/src/core/direct-functions/fix-dependencies.js b/mcp-server/src/core/direct-functions/fix-dependencies.js index d5994a04..ff3d0a02 100644 --- a/mcp-server/src/core/direct-functions/fix-dependencies.js +++ b/mcp-server/src/core/direct-functions/fix-dependencies.js @@ -18,8 +18,8 @@ export async function fixDependenciesDirect(args, log) { try { log.info(`Fixing invalid dependencies in tasks...`); - // Determine the tasks file path - const tasksPath = args.file || await findTasksJsonPath(args.projectRoot); + // Find the tasks.json path + const tasksPath = findTasksJsonPath(args, log); // Verify the file exists if (!fs.existsSync(tasksPath)) { diff --git a/mcp-server/src/core/direct-functions/remove-dependency.js b/mcp-server/src/core/direct-functions/remove-dependency.js index 16ab652c..38f245c5 100644 --- a/mcp-server/src/core/direct-functions/remove-dependency.js +++ b/mcp-server/src/core/direct-functions/remove-dependency.js @@ -41,7 +41,7 @@ export async function removeDependencyDirect(args, log) { } // Find the tasks.json path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + const tasksPath = findTasksJsonPath(args, log); // Format IDs for the core function const taskId = args.id.includes && args.id.includes('.') ? args.id : parseInt(args.id, 10); diff --git a/mcp-server/src/core/direct-functions/remove-subtask.js b/mcp-server/src/core/direct-functions/remove-subtask.js index 2e9e47b9..6072b181 100644 --- a/mcp-server/src/core/direct-functions/remove-subtask.js +++ b/mcp-server/src/core/direct-functions/remove-subtask.js @@ -42,7 +42,7 @@ export async function removeSubtaskDirect(args, log) { } // Find the tasks.json path - const tasksPath = findTasksJsonPath(args.file, args.projectRoot); + const tasksPath = findTasksJsonPath(args, log); // Convert convertToTask to a boolean const convertToTask = args.convert === true; diff --git a/mcp-server/src/core/direct-functions/validate-dependencies.js b/mcp-server/src/core/direct-functions/validate-dependencies.js index 27fbf7dd..3f652cce 100644 --- a/mcp-server/src/core/direct-functions/validate-dependencies.js +++ b/mcp-server/src/core/direct-functions/validate-dependencies.js @@ -18,8 +18,8 @@ export async function validateDependenciesDirect(args, log) { try { log.info(`Validating dependencies in tasks...`); - // Determine the tasks file path - const tasksPath = args.file || await findTasksJsonPath(args.projectRoot); + // Find the tasks.json path + const tasksPath = findTasksJsonPath(args, log); // Verify the file exists if (!fs.existsSync(tasksPath)) { diff --git a/mcp-server/src/tools/add-dependency.js b/mcp-server/src/tools/add-dependency.js index e500bc42..22d78812 100644 --- a/mcp-server/src/tools/add-dependency.js +++ b/mcp-server/src/tools/add-dependency.js @@ -22,7 +22,7 @@ export function registerAddDependencyTool(server) { id: z.string().describe("ID of task that will depend on another task"), dependsOn: z.string().describe("ID of task that will become a dependency"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/add-subtask.js b/mcp-server/src/tools/add-subtask.js index 7a0e29dd..b3abc761 100644 --- a/mcp-server/src/tools/add-subtask.js +++ b/mcp-server/src/tools/add-subtask.js @@ -28,7 +28,7 @@ export function registerAddSubtaskTool(server) { dependencies: z.string().optional().describe("Comma-separated list of dependency IDs for the new subtask"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), skipGenerate: z.boolean().optional().describe("Skip regenerating task files"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/add-task.js b/mcp-server/src/tools/add-task.js index 6fea5d8b..4ea8c9cd 100644 --- a/mcp-server/src/tools/add-task.js +++ b/mcp-server/src/tools/add-task.js @@ -23,7 +23,7 @@ export function registerAddTaskTool(server) { 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().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async ({ prompt, dependencies, priority, file, projectRoot }, log) => { try { diff --git a/mcp-server/src/tools/analyze.js b/mcp-server/src/tools/analyze.js index ffac81e0..2fc35581 100644 --- a/mcp-server/src/tools/analyze.js +++ b/mcp-server/src/tools/analyze.js @@ -24,7 +24,7 @@ export function registerAnalyzeTool(server) { threshold: z.union([z.number(), z.string()]).optional().describe("Minimum complexity score to recommend expansion (1-10) (default: 5)"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), research: z.boolean().optional().describe("Use Perplexity AI for research-backed complexity analysis"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/clear-subtasks.js b/mcp-server/src/tools/clear-subtasks.js index b0c2d561..60f52c2b 100644 --- a/mcp-server/src/tools/clear-subtasks.js +++ b/mcp-server/src/tools/clear-subtasks.js @@ -22,7 +22,7 @@ export function registerClearSubtasksTool(server) { id: z.string().optional().describe("Task IDs (comma-separated) to clear subtasks from"), all: z.boolean().optional().describe("Clear subtasks from all tasks"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }).refine(data => data.id || data.all, { message: "Either 'id' or 'all' parameter must be provided", path: ["id", "all"] diff --git a/mcp-server/src/tools/complexity-report.js b/mcp-server/src/tools/complexity-report.js index d8c37257..415ad713 100644 --- a/mcp-server/src/tools/complexity-report.js +++ b/mcp-server/src/tools/complexity-report.js @@ -20,7 +20,7 @@ export function registerComplexityReportTool(server) { description: "Display the complexity analysis report in a readable format", parameters: z.object({ file: z.string().optional().describe("Path to the report file (default: scripts/task-complexity-report.json)"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/expand-all.js b/mcp-server/src/tools/expand-all.js index e088c4e7..ddd6fbff 100644 --- a/mcp-server/src/tools/expand-all.js +++ b/mcp-server/src/tools/expand-all.js @@ -24,7 +24,7 @@ export function registerExpandAllTool(server) { prompt: z.string().optional().describe("Additional context to guide subtask generation"), force: z.boolean().optional().describe("Force regeneration of subtasks for tasks that already have them"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/fix-dependencies.js b/mcp-server/src/tools/fix-dependencies.js index 62219542..70340c67 100644 --- a/mcp-server/src/tools/fix-dependencies.js +++ b/mcp-server/src/tools/fix-dependencies.js @@ -20,7 +20,7 @@ export function registerFixDependenciesTool(server) { description: "Fix invalid dependencies in tasks automatically", parameters: z.object({ file: z.string().optional().describe("Path to the tasks file"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/remove-dependency.js b/mcp-server/src/tools/remove-dependency.js index c9d2dacb..2cecf3d6 100644 --- a/mcp-server/src/tools/remove-dependency.js +++ b/mcp-server/src/tools/remove-dependency.js @@ -22,7 +22,7 @@ export function registerRemoveDependencyTool(server) { id: z.string().describe("Task ID to remove dependency from"), dependsOn: z.string().describe("Task ID to remove as a dependency"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/mcp-server/src/tools/remove-subtask.js b/mcp-server/src/tools/remove-subtask.js index 1878aa9c..786de1fe 100644 --- a/mcp-server/src/tools/remove-subtask.js +++ b/mcp-server/src/tools/remove-subtask.js @@ -23,7 +23,7 @@ export function registerRemoveSubtaskTool(server) { convert: z.boolean().optional().describe("Convert the subtask to a standalone task instead of deleting it"), file: z.string().optional().describe("Path to the tasks file (default: tasks/tasks.json)"), skipGenerate: z.boolean().optional().describe("Skip regenerating task files"), - projectRoot: z.string().describe("Root directory of the project (default: current working directory)") + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") }), execute: async (args, { log }) => { try { diff --git a/tasks/task_023.txt b/tasks/task_023.txt index 9bd06e40..c75d2fe7 100644 --- a/tasks/task_023.txt +++ b/tasks/task_023.txt @@ -1207,9 +1207,3 @@ This method provides a consistent way to access environment variables defined in ### Details: -## 47. adjust rules so it prioritizes mcp commands over script [pending] -### Dependencies: None -### Description: -### Details: - - diff --git a/tasks/tasks.json b/tasks/tasks.json index e282ea64..697668d0 100644 --- a/tasks/tasks.json +++ b/tasks/tasks.json @@ -1780,15 +1780,6 @@ "status": "pending", "dependencies": [], "parentTaskId": 23 - }, - { - "id": 47, - "title": "adjust rules so it prioritizes mcp commands over script", - "description": "", - "details": "", - "status": "pending", - "dependencies": [], - "parentTaskId": 23 } ] },