docs: Update rules for MCP/CLI workflow and project root handling
Updated several Cursor rules documentation files (`mcp.mdc`, `utilities.mdc`, `architecture.mdc`, `new_features.mdc`, `commands.mdc`) to accurately reflect recent refactoring and clarify best practices. Key documentation updates include: - Explicitly stating the preference for using MCP tools over CLI commands in integrated environments (`commands.mdc`, `dev_workflow.mdc`). - Describing the new standard pattern for getting the project root using `getProjectRootFromSession` within MCP tool `execute` methods (`mcp.mdc`, `utilities.mdc`, `architecture.mdc`, `new_features.mdc`). - Clarifying the simplified role of `findTasksJsonPath` in direct functions (`mcp.mdc`, `utilities.mdc`, `architecture.mdc`, `new_features.mdc`). - Ensuring proper interlinking between related documentation files.
This commit is contained in:
@@ -8,73 +8,66 @@
|
|||||||
- Rename `list-tasks` to `get-tasks` for more intuitive client requests like "get my tasks"
|
- Rename `list-tasks` to `get-tasks` for more intuitive client requests like "get my tasks"
|
||||||
- Rename `show-task` to `get-task` for consistency with GET-based API naming conventions
|
- Rename `show-task` to `get-task` for consistency with GET-based API naming conventions
|
||||||
|
|
||||||
- Implement robust project root detection with a hierarchical precedence system:
|
- **Refactor project root handling for MCP Server:**
|
||||||
- Environment variable override (TASK_MASTER_PROJECT_ROOT)
|
- **Prioritize Session Roots**: MCP tools now extract the project root path directly from `session.roots[0].uri` provided by the client (e.g., Cursor).
|
||||||
- Explicitly provided project root (--project-root parameter)
|
- **New Utility `getProjectRootFromSession`**: Added to `mcp-server/src/tools/utils.js` to encapsulate session root extraction and decoding.
|
||||||
- Cached project root from previous successful operations
|
- **Simplify `findTasksJsonPath`**: The core path finding utility in `mcp-server/src/core/utils/path-utils.js` now prioritizes the `projectRoot` passed in `args` (originating from the session). Removed checks for `TASK_MASTER_PROJECT_ROOT` env var and package directory fallback.
|
||||||
- Current directory with project markers
|
- **Retain CLI Fallbacks**: Kept `lastFoundProjectRoot` cache check and CWD search in `findTasksJsonPath` for compatibility with direct CLI usage.
|
||||||
- Parent directory traversal to find tasks.json
|
|
||||||
- Package directory as fallback
|
|
||||||
|
|
||||||
- Updated all MCP tools to work without explicitly requiring project root:
|
- Updated all MCP tools to use the new project root handling:
|
||||||
- Changed all tool definitions from `projectRoot: z.string().describe(...)` to `projectRoot: z.string().optional().describe(...)`
|
- Tools now call `getProjectRootFromSession` to determine the root.
|
||||||
- Updated all direct function implementations from `findTasksJsonPath(args.file, args.projectRoot)` to use the proper `findTasksJsonPath(args, log)` pattern
|
- This root is passed explicitly as `projectRoot` in the `args` object to the corresponding `*Direct` function.
|
||||||
- These changes allow MCP tools to work properly without requiring the projectRoot parameter, using smart detection to automatically determine the project root
|
- Direct functions continue to use the (now simplified) `findTasksJsonPath` to locate `tasks.json` within the provided root.
|
||||||
|
- This ensures tools work reliably in integrated environments without requiring the user to specify `--project-root`.
|
||||||
|
|
||||||
- Add comprehensive PROJECT_MARKERS array for detecting common project files:
|
- Add comprehensive PROJECT_MARKERS array for detecting common project files (used in CLI fallback logic).
|
||||||
- Task Master specific files (tasks.json, tasks/tasks.json)
|
- Improved error messages with specific troubleshooting guidance.
|
||||||
- Version control markers (.git, .svn)
|
- Enhanced logging to indicate the source of project root selection.
|
||||||
- Package files (package.json, pyproject.toml, etc.)
|
- DRY refactoring by centralizing path utilities in `core/utils/path-utils.js` and session handling in `tools/utils.js`.
|
||||||
- IDE/editor folders (.cursor, .vscode, .idea)
|
- Keep caching of `lastFoundProjectRoot` for CLI performance.
|
||||||
- Dependency directories (node_modules, venv)
|
|
||||||
- Configuration files (.env, tsconfig.json, etc.)
|
|
||||||
- CI/CD files (.github/workflows, etc.)
|
|
||||||
|
|
||||||
- Improved error messages with specific troubleshooting guidance
|
- Split monolithic task-master-core.js into separate function files within direct-functions directory.
|
||||||
- Enhanced logging to indicate the source of project root selection
|
- Implement update-task MCP command for updating a single task by ID.
|
||||||
- DRY refactoring by centralizing path utilities in core/utils/path-utils.js
|
- Implement update-subtask MCP command for appending information to specific subtasks.
|
||||||
- Add caching of lastFoundProjectRoot for improved performance
|
- Implement generate MCP command for creating individual task files from tasks.json.
|
||||||
|
- Implement set-status MCP command for updating task status.
|
||||||
- Split monolithic task-master-core.js into separate function files within direct-functions directory
|
- Implement get-task MCP command for displaying detailed task information (renamed from show-task).
|
||||||
- Implement update-task MCP command for updating a single task by ID
|
- Implement next-task MCP command for finding the next task to work on.
|
||||||
- Implement update-subtask MCP command for appending information to specific subtasks
|
- Implement expand-task MCP command for breaking down tasks into subtasks.
|
||||||
- Implement generate MCP command for creating individual task files from tasks.json
|
- Implement add-task MCP command for creating new tasks using AI assistance.
|
||||||
- Implement set-status MCP command for updating task status
|
- Implement add-subtask MCP command for adding subtasks to existing tasks.
|
||||||
- Implement get-task MCP command for displaying detailed task information (renamed from show-task)
|
- Implement remove-subtask MCP command for removing subtasks from parent tasks.
|
||||||
- Implement next-task MCP command for finding the next task to work on
|
- Implement expand-all MCP command for expanding all tasks into subtasks.
|
||||||
- Implement expand-task MCP command for breaking down tasks into subtasks
|
- Implement analyze-complexity MCP command for analyzing task complexity.
|
||||||
- Implement add-task MCP command for creating new tasks using AI assistance
|
- Implement clear-subtasks MCP command for clearing subtasks from parent tasks.
|
||||||
- Implement add-subtask MCP command for adding subtasks to existing tasks
|
- Implement remove-dependency MCP command for removing dependencies from tasks.
|
||||||
- Implement remove-subtask MCP command for removing subtasks from parent tasks
|
- Implement validate-dependencies MCP command for checking validity of task dependencies.
|
||||||
- Implement expand-all MCP command for expanding all tasks into subtasks
|
- Implement fix-dependencies MCP command for automatically fixing invalid dependencies.
|
||||||
- Implement analyze-complexity MCP command for analyzing task complexity
|
- Implement complexity-report MCP command for displaying task complexity analysis reports.
|
||||||
- Implement clear-subtasks MCP command for clearing subtasks from parent tasks
|
- Implement add-dependency MCP command for creating dependency relationships between tasks.
|
||||||
- Implement remove-dependency MCP command for removing dependencies from tasks
|
- Implement get-tasks MCP command for listing all tasks (renamed from list-tasks).
|
||||||
- Implement validate-dependencies MCP command for checking validity of task dependencies
|
|
||||||
- Implement fix-dependencies MCP command for automatically fixing invalid dependencies
|
|
||||||
- Implement complexity-report MCP command for displaying task complexity analysis reports
|
|
||||||
- Implement add-dependency MCP command for creating dependency relationships between tasks
|
|
||||||
- Implement get-tasks MCP command for listing all tasks (renamed from list-tasks)
|
|
||||||
|
|
||||||
- Enhance documentation and tool descriptions:
|
- Enhance documentation and tool descriptions:
|
||||||
- Create new `taskmaster.mdc` Cursor rule for comprehensive MCP tool and CLI command reference
|
- Create new `taskmaster.mdc` Cursor rule for comprehensive MCP tool and CLI command reference.
|
||||||
- Bundle taskmaster.mdc with npm package and include in project initialization
|
- Bundle taskmaster.mdc with npm package and include in project initialization.
|
||||||
- Add detailed descriptions for each tool's purpose, parameters, and common use cases
|
- Add detailed descriptions for each tool's purpose, parameters, and common use cases.
|
||||||
- Include natural language patterns and keywords for better intent recognition
|
- Include natural language patterns and keywords for better intent recognition.
|
||||||
- Document parameter descriptions with clear examples and default values
|
- Document parameter descriptions with clear examples and default values.
|
||||||
- Add usage examples and context for each command/tool
|
- Add usage examples and context for each command/tool.
|
||||||
- Improve clarity around project root auto-detection in tool documentation
|
- **Update documentation (`mcp.mdc`, `utilities.mdc`, `architecture.mdc`, `new_features.mdc`, `commands.mdc`) to reflect the new session-based project root handling and the preferred MCP vs. CLI interaction model.**
|
||||||
- Update tool descriptions to better reflect their actual behavior and capabilities
|
- Improve clarity around project root auto-detection in tool documentation.
|
||||||
- Add cross-references between related tools and commands
|
- Update tool descriptions to better reflect their actual behavior and capabilities.
|
||||||
- Include troubleshooting guidance in tool descriptions
|
- Add cross-references between related tools and commands.
|
||||||
|
- Include troubleshooting guidance in tool descriptions.
|
||||||
|
|
||||||
- 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)
|
- 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).
|
||||||
- Update MCP tool naming to follow more intuitive conventions that better align with natural language requests in client chat applications
|
- Update MCP tool naming to follow more intuitive conventions that better align with natural language requests in client chat applications.
|
||||||
- Enhance task show view with a color-coded progress bar for visualizing subtask completion percentage
|
- Enhance task show view with a color-coded progress bar for visualizing subtask completion percentage.
|
||||||
- Add "cancelled" status to UI module status configurations for marking tasks as cancelled without deletion
|
- Add "cancelled" status to UI module status configurations for marking tasks as cancelled without deletion.
|
||||||
- Improve MCP server resource documentation with comprehensive implementation examples and best practices
|
- Improve MCP server resource documentation with comprehensive implementation examples and best practices.
|
||||||
- Enhance progress bars with status breakdown visualization showing proportional sections for different task statuses
|
- Enhance progress bars with status breakdown visualization showing proportional sections for different task statuses.
|
||||||
- Add improved status tracking for both tasks and subtasks with detailed counts by status
|
- Add improved status tracking for both tasks and subtasks with detailed counts by status.
|
||||||
- Optimize progress bar display with width constraints to prevent UI overflow on smaller terminals
|
- Optimize progress bar display with width constraints to prevent UI overflow on smaller terminals.
|
||||||
- Improve status counts display with clear text labels beside status icons for better readability
|
- Improve status counts display with clear text labels beside status icons for better readability.
|
||||||
- Treat deferred and cancelled tasks as effectively complete for progress calculation while maintaining visual distinction
|
- Treat deferred and cancelled tasks as effectively complete for progress calculation while maintaining visual distinction.
|
||||||
|
- **Fix `reportProgress` calls** to use the correct `{ progress, total? }` format.
|
||||||
|
|||||||
@@ -107,10 +107,12 @@ alwaysApply: false
|
|||||||
- Registers Task Master functionalities as tools consumable via MCP.
|
- Registers Task Master functionalities as tools consumable via MCP.
|
||||||
- Handles MCP requests via tool `execute` methods defined in `mcp-server/src/tools/*.js`.
|
- Handles MCP requests via tool `execute` methods defined in `mcp-server/src/tools/*.js`.
|
||||||
- Tool `execute` methods call corresponding **direct function wrappers**.
|
- Tool `execute` methods call corresponding **direct function wrappers**.
|
||||||
|
- Tool `execute` methods use `getProjectRootFromSession` (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) to determine the project root from the client session and pass it to the direct function.
|
||||||
- **Direct function wrappers (`*Direct` functions in `mcp-server/src/core/direct-functions/*.js`) contain the main logic for handling MCP requests**, including path resolution, argument validation, caching, and calling core Task Master functions.
|
- **Direct function wrappers (`*Direct` functions in `mcp-server/src/core/direct-functions/*.js`) contain the main logic for handling MCP requests**, including path resolution, argument validation, caching, and calling core Task Master functions.
|
||||||
|
- Direct functions use `findTasksJsonPath` (from [`core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) to locate `tasks.json` based on the provided `projectRoot`.
|
||||||
- Tool `execute` methods use `handleApiResult` from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) to process the result from the direct function and format the final MCP response.
|
- Tool `execute` methods use `handleApiResult` from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) to process the result from the direct function and format the final MCP response.
|
||||||
- Uses CLI execution via `executeTaskMasterCommand` as a fallback only when necessary.
|
- Uses CLI execution via `executeTaskMasterCommand` as a fallback only when necessary.
|
||||||
- **Implements Robust Path Finding**: The utility [`core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js) (specifically `findTasksJsonPath`) is used **within direct functions** to automatically locate the project root and `tasks.json` file, removing the need for mandatory `projectRoot` parameters in MCP calls.
|
- **Implements Robust Path Finding**: The utility [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) (specifically `getProjectRootFromSession`) and [`core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js) (specifically `findTasksJsonPath`) work together. The tool gets the root via session, passes it to the direct function, which uses `findTasksJsonPath` to locate the specific `tasks.json` file within that root.
|
||||||
- **Implements Caching**: Utilizes a caching layer (`ContextManager` with `lru-cache`). Caching logic is invoked *within* the direct function wrappers using the `getCachedOrExecute` utility for performance-sensitive read operations.
|
- **Implements Caching**: Utilizes a caching layer (`ContextManager` with `lru-cache`). Caching logic is invoked *within* the direct function wrappers using the `getCachedOrExecute` utility for performance-sensitive read operations.
|
||||||
- Standardizes response formatting and data filtering using utilities in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
- Standardizes response formatting and data filtering using utilities in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
||||||
- **Resource Management**: Provides access to static and dynamic resources.
|
- **Resource Management**: Provides access to static and dynamic resources.
|
||||||
@@ -118,11 +120,11 @@ alwaysApply: false
|
|||||||
- `mcp-server/src/index.js`: Main server class definition with FastMCP initialization, resource registration, and server lifecycle management.
|
- `mcp-server/src/index.js`: Main server class definition with FastMCP initialization, resource registration, and server lifecycle management.
|
||||||
- `mcp-server/src/server.js`: Main server setup and initialization.
|
- `mcp-server/src/server.js`: Main server setup and initialization.
|
||||||
- `mcp-server/src/tools/`: Directory containing individual tool definitions. Each tool's `execute` method orchestrates the call to core logic and handles the response.
|
- `mcp-server/src/tools/`: Directory containing individual tool definitions. Each tool's `execute` method orchestrates the call to core logic and handles the response.
|
||||||
- `mcp-server/src/core/utils/`: Directory containing utility functions specific to the MCP server, like **`path-utils.js` for project root detection**.
|
- `mcp-server/src/tools/utils.js`: Provides MCP-specific utilities like `handleApiResult`, `processMCPResponseData`, `getCachedOrExecute`, and **`getProjectRootFromSession`**.
|
||||||
|
- `mcp-server/src/core/utils/`: Directory containing utility functions specific to the MCP server, like **`path-utils.js` for resolving `tasks.json` within a given root**.
|
||||||
- `mcp-server/src/core/direct-functions/`: Directory containing individual files for each **direct function wrapper (`*Direct`)**. These files contain the primary logic for MCP tool execution.
|
- `mcp-server/src/core/direct-functions/`: Directory containing individual files for each **direct function wrapper (`*Direct`)**. These files contain the primary logic for MCP tool execution.
|
||||||
- `mcp-server/src/core/resources/`: Directory containing resource handlers for task templates, workflow definitions, and other static/dynamic data exposed to LLM clients.
|
- `mcp-server/src/core/resources/`: Directory containing resource handlers for task templates, workflow definitions, and other static/dynamic data exposed to LLM clients.
|
||||||
- [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js): Acts as an import/export hub, collecting and exporting direct functions from the `direct-functions` directory and MCP utility functions.
|
- [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js): Acts as an import/export hub, collecting and exporting direct functions from the `direct-functions` directory and MCP utility functions.
|
||||||
- `mcp-server/src/tools/utils.js`: Provides MCP-specific utilities like `handleApiResult`, `processMCPResponseData`, and `getCachedOrExecute`.
|
|
||||||
- **Naming Conventions**:
|
- **Naming Conventions**:
|
||||||
- **Files** use **kebab-case**: `list-tasks.js`, `set-task-status.js`, `parse-prd.js`
|
- **Files** use **kebab-case**: `list-tasks.js`, `set-task-status.js`, `parse-prd.js`
|
||||||
- **Direct Functions** use **camelCase** with `Direct` suffix: `listTasksDirect`, `setTaskStatusDirect`, `parsePRDDirect`
|
- **Direct Functions** use **camelCase** with `Direct` suffix: `listTasksDirect`, `setTaskStatusDirect`, `parsePRDDirect`
|
||||||
@@ -137,7 +139,7 @@ alwaysApply: false
|
|||||||
- **UI for Presentation**: [`ui.js`](mdc:scripts/modules/ui.js) is used by command handlers and task/dependency managers to display information to the user. UI functions primarily consume data and format it for output, without modifying core application state.
|
- **UI for Presentation**: [`ui.js`](mdc:scripts/modules/ui.js) is used by command handlers and task/dependency managers to display information to the user. UI functions primarily consume data and format it for output, without modifying core application state.
|
||||||
- **Utilities for Common Tasks**: [`utils.js`](mdc:scripts/modules/utils.js) provides helper functions used by all other modules for configuration, logging, file operations, and common data manipulations.
|
- **Utilities for Common Tasks**: [`utils.js`](mdc:scripts/modules/utils.js) provides helper functions used by all other modules for configuration, logging, file operations, and common data manipulations.
|
||||||
- **AI Services Integration**: AI functionalities (complexity analysis, task expansion, PRD parsing) are invoked from [`task-manager.js`](mdc:scripts/modules/task-manager.js) and potentially [`commands.js`](mdc:scripts/modules/commands.js), likely using functions that would reside in a dedicated `ai-services.js` module or be integrated within `utils.js` or `task-manager.js`.
|
- **AI Services Integration**: AI functionalities (complexity analysis, task expansion, PRD parsing) are invoked from [`task-manager.js`](mdc:scripts/modules/task-manager.js) and potentially [`commands.js`](mdc:scripts/modules/commands.js), likely using functions that would reside in a dedicated `ai-services.js` module or be integrated within `utils.js` or `task-manager.js`.
|
||||||
- **MCP Server Interaction**: External tools interact with the `mcp-server`. MCP Tool `execute` methods call direct function wrappers (in `mcp-server/src/core/direct-functions/`). These wrappers handle path finding (using `path-utils.js`), validation, caching, call the core logic from `scripts/modules/`, and return a standardized result. The final MCP response is formatted by `mcp-server/src/tools/utils.js`. See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details.
|
- **MCP Server Interaction**: External tools interact with the `mcp-server`. MCP Tool `execute` methods use `getProjectRootFromSession` to find the project root, then call direct function wrappers (in `mcp-server/src/core/direct-functions/`) passing the root in `args`. These wrappers handle path finding for `tasks.json` (using `path-utils.js`), validation, caching, call the core logic from `scripts/modules/`, and return a standardized result. The final MCP response is formatted by `mcp-server/src/tools/utils.js`. See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details.
|
||||||
|
|
||||||
- **Testing Architecture**:
|
- **Testing Architecture**:
|
||||||
|
|
||||||
@@ -188,11 +190,11 @@ Follow these steps to add MCP support for an existing Task Master command (see [
|
|||||||
1. **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.
|
1. **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.
|
||||||
|
|
||||||
2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:
|
2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:
|
||||||
- Create a new file (e.g., `your-command.js`).
|
- Create a new file (e.g., `your-command.js`) using **kebab-case** naming.
|
||||||
- Import necessary core functions and **`findTasksJsonPath` from `../utils/path-utils.js`**.
|
- Import necessary core functions and **`findTasksJsonPath` from `../utils/path-utils.js`**.
|
||||||
- Implement `async function yourCommandDirect(args, log)`:
|
- Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:
|
||||||
- **Get `tasksPath` using `findTasksJsonPath(args, log)`**.
|
- **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` being provided.
|
||||||
- Parse/validate other args.
|
- Parse other `args` and perform necessary validation.
|
||||||
- Implement caching with `getCachedOrExecute` if applicable.
|
- Implement caching with `getCachedOrExecute` if applicable.
|
||||||
- Call core logic.
|
- Call core logic.
|
||||||
- Return `{ success: true/false, data/error, fromCache: boolean }`.
|
- Return `{ success: true/false, data/error, fromCache: boolean }`.
|
||||||
@@ -201,11 +203,14 @@ Follow these steps to add MCP support for an existing Task Master command (see [
|
|||||||
3. **Update `task-master-core.js` with Import/Export**: Add imports/exports for the new `*Direct` function.
|
3. **Update `task-master-core.js` with Import/Export**: Add imports/exports for the new `*Direct` function.
|
||||||
|
|
||||||
4. **Create MCP Tool (`mcp-server/src/tools/`)**:
|
4. **Create MCP Tool (`mcp-server/src/tools/`)**:
|
||||||
- Create a new file (e.g., `your-command.js`).
|
- Create a new file (e.g., `your-command.js`) using **kebab-case**.
|
||||||
- Import `zod`, `handleApiResult`, and your `yourCommandDirect` function.
|
- Import `zod`, `handleApiResult`, **`getProjectRootFromSession`**, and your `yourCommandDirect` function.
|
||||||
- Implement `registerYourCommandTool(server)`.
|
- Implement `registerYourCommandTool(server)`.
|
||||||
- **Define parameters, making `projectRoot` optional**: `projectRoot: z.string().optional().describe(...)`.
|
- **Define parameters, making `projectRoot` optional**: `projectRoot: z.string().optional().describe(...)`.
|
||||||
- Implement the standard `execute` method: Call `yourCommandDirect(args, log)` and pass result to `handleApiResult`.
|
- Implement the standard `execute` method:
|
||||||
|
- Get `rootFolder` using `getProjectRootFromSession` (with fallback to `args.projectRoot`).
|
||||||
|
- Call `yourCommandDirect({ ...args, projectRoot: rootFolder }, log)`.
|
||||||
|
- Pass the result to `handleApiResult`.
|
||||||
|
|
||||||
5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.
|
5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,16 @@ alwaysApply: false
|
|||||||
|
|
||||||
# Command-Line Interface Implementation Guidelines
|
# Command-Line Interface Implementation Guidelines
|
||||||
|
|
||||||
|
**Note on Interaction Method:**
|
||||||
|
|
||||||
|
While this document details the implementation of Task Master's **CLI commands**, the **preferred method for interacting with Task Master in integrated environments (like Cursor) is through the MCP server tools**.
|
||||||
|
|
||||||
|
- **Use MCP Tools First**: Always prefer using the MCP tools (e.g., `get_tasks`, `add_task`) when interacting programmatically or via an integrated tool. They offer better performance, structured data, and richer error handling. See [`taskmaster.mdc`](mdc:.cursor/rules/taskmaster.mdc) for a comprehensive list of MCP tools and their corresponding CLI commands.
|
||||||
|
- **CLI as Fallback/User Interface**: The `task-master` CLI commands described here are primarily intended for:
|
||||||
|
- Direct user interaction in the terminal.
|
||||||
|
- A fallback mechanism if the MCP server is unavailable or a specific functionality is not exposed via an MCP tool.
|
||||||
|
- **Implementation Context**: This document (`commands.mdc`) focuses on the standards for *implementing* the CLI commands using Commander.js within the [`commands.js`](mdc:scripts/modules/commands.js) module.
|
||||||
|
|
||||||
## Command Structure Standards
|
## Command Structure Standards
|
||||||
|
|
||||||
- **Basic Command Template**:
|
- **Basic Command Template**:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ server.addTool({
|
|||||||
param2: z.number().optional().describe("Optional parameter description"),
|
param2: z.number().optional().describe("Optional parameter description"),
|
||||||
// IMPORTANT: For file operations, always include these optional parameters
|
// IMPORTANT: For file operations, always include these optional parameters
|
||||||
file: z.string().optional().describe("Path to the tasks file"),
|
file: z.string().optional().describe("Path to the tasks file"),
|
||||||
projectRoot: z.string().optional().describe("Root directory of the project")
|
projectRoot: z.string().optional().describe("Root directory of the project (typically derived from session)")
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// The execute function is the core of the tool implementation
|
// The execute function is the core of the tool implementation
|
||||||
@@ -44,7 +44,7 @@ server.addTool({
|
|||||||
|
|
||||||
### Execute Function Signature
|
### Execute Function Signature
|
||||||
|
|
||||||
The `execute` function should follow this exact pattern:
|
The `execute` function receives validated arguments and the FastMCP context:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
execute: async (args, context) => {
|
execute: async (args, context) => {
|
||||||
@@ -52,419 +52,117 @@ execute: async (args, context) => {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- **args**: The first parameter contains all the validated parameters defined in the tool's schema
|
- **args**: The first parameter contains all the validated parameters defined in the tool's schema.
|
||||||
- You can destructure specific parameters: `const { param1, param2, file, projectRoot } = args;`
|
- **context**: The second parameter is an object containing `{ log, reportProgress, session }` provided by FastMCP.
|
||||||
- Always pass the full `args` object to direct functions: `await yourDirectFunction(args, context.log);`
|
|
||||||
|
|
||||||
- **context**: The second parameter is an object with specific properties provided by FastMCP
|
|
||||||
- Contains `{ log, reportProgress, session }` - **always destructure these from the context object**
|
|
||||||
- ✅ **DO**: `execute: async (args, { log, reportProgress, session }) => {}`
|
- ✅ **DO**: `execute: async (args, { log, reportProgress, session }) => {}`
|
||||||
- ❌ **DON'T**: `execute: async (args, log) => {}`
|
|
||||||
|
### Standard Tool Execution Pattern
|
||||||
|
|
||||||
|
The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should follow this standard pattern:
|
||||||
|
|
||||||
|
1. **Log Entry**: Log the start of the tool execution with relevant arguments.
|
||||||
|
2. **Get Project Root**: Use the `getProjectRootFromSession(session, log)` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) to extract the project root path from the client session. Fall back to `args.projectRoot` if the session doesn't provide a root.
|
||||||
|
3. **Call Direct Function**: Invoke the corresponding `*Direct` function wrapper (e.g., `listTasksDirect` from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)), passing an updated `args` object that includes the resolved `projectRoot`, along with the `log` object: `await someDirectFunction({ ...args, projectRoot: resolvedRootFolder }, log);`
|
||||||
|
4. **Handle Result**: Receive the result object (`{ success, data/error, fromCache }`) from the `*Direct` function.
|
||||||
|
5. **Format Response**: Pass this result object to the `handleApiResult` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) for standardized MCP response formatting and error handling.
|
||||||
|
6. **Return**: Return the formatted response object provided by `handleApiResult`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Example execute method structure
|
||||||
|
import { getProjectRootFromSession, handleApiResult, createErrorResponse } from './utils.js';
|
||||||
|
import { someDirectFunction } from '../core/task-master-core.js';
|
||||||
|
|
||||||
|
// ... inside server.addTool({...})
|
||||||
|
execute: async (args, { log, reportProgress, session }) => {
|
||||||
|
try {
|
||||||
|
log.info(`Starting tool execution with args: ${JSON.stringify(args)}`);
|
||||||
|
|
||||||
|
// 1. Get Project Root
|
||||||
|
let rootFolder = getProjectRootFromSession(session, log);
|
||||||
|
if (!rootFolder && args.projectRoot) { // Fallback if needed
|
||||||
|
rootFolder = args.projectRoot;
|
||||||
|
log.info(`Using project root from args as fallback: ${rootFolder}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Call Direct Function (passing resolved root)
|
||||||
|
const result = await someDirectFunction({
|
||||||
|
...args,
|
||||||
|
projectRoot: rootFolder // Ensure projectRoot is explicitly passed
|
||||||
|
}, log);
|
||||||
|
|
||||||
|
// 3. Handle and Format Response
|
||||||
|
return handleApiResult(result, log);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error during tool execution: ${error.message}`);
|
||||||
|
return createErrorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Logging Convention
|
### Logging Convention
|
||||||
|
|
||||||
The `log` object provides standardized logging methods:
|
The `log` object (destructured from `context`) provides standardized logging methods. Use it within both the `execute` method and the `*Direct` functions.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Proper logging usage within a tool's execute method
|
// Proper logging usage
|
||||||
execute: async (args, { log, reportProgress, session }) => {
|
log.info(`Starting ${toolName} with parameters: ${JSON.stringify(sanitizedArgs)}`);
|
||||||
try {
|
log.debug("Detailed operation info", { data });
|
||||||
// Log the start of execution with key parameters (but sanitize sensitive data)
|
log.warn("Potential issue detected");
|
||||||
log.info(`Starting ${toolName} with parameters: ${JSON.stringify(args, null, 2)}`);
|
log.error(`Error occurred: ${error.message}`, { stack: error.stack });
|
||||||
|
|
||||||
// For debugging information
|
|
||||||
log.debug("Detailed operation information", { additionalContext: "value" });
|
|
||||||
|
|
||||||
// For warnings that don't prevent execution
|
|
||||||
log.warn("Warning: potential issue detected", { details: "..." });
|
|
||||||
|
|
||||||
// Call the direct function and handle the result
|
|
||||||
const result = await someDirectFunction(args, log);
|
|
||||||
|
|
||||||
// Log successful completion
|
|
||||||
log.info(`Successfully completed ${toolName}`, {
|
|
||||||
resultSummary: "brief summary without sensitive data"
|
|
||||||
});
|
|
||||||
|
|
||||||
return handleApiResult(result, log);
|
|
||||||
} catch (error) {
|
|
||||||
// Log errors with full context
|
|
||||||
log.error(`Error in ${toolName}: ${error.message}`, {
|
|
||||||
errorDetails: error.stack
|
|
||||||
});
|
|
||||||
|
|
||||||
return createErrorResponse(error.message, "ERROR_CODE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Progress Reporting Convention
|
### Progress Reporting Convention
|
||||||
|
|
||||||
Use `reportProgress` for long-running operations to provide feedback to the client:
|
Use `reportProgress` (destructured from `context`) for long-running operations. It expects an object `{ progress: number, total?: number }`.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
execute: async (args, { log, reportProgress, session }) => {
|
await reportProgress({ progress: 0 }); // Start
|
||||||
// Initialize progress at the start
|
// ... work ...
|
||||||
await reportProgress({ progress: 0, total: 100 });
|
await reportProgress({ progress: 50 }); // Intermediate (total optional)
|
||||||
|
// ... more work ...
|
||||||
// For known progress stages, update with specific percentages
|
await reportProgress({ progress: 100 }); // Complete
|
||||||
for (let i = 0; i < stages.length; i++) {
|
|
||||||
// Do some work...
|
|
||||||
|
|
||||||
// Report intermediate progress
|
|
||||||
await reportProgress({
|
|
||||||
progress: Math.floor((i + 1) / stages.length * 100),
|
|
||||||
total: 100
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// For indeterminate progress (no known total)
|
|
||||||
await reportProgress({ progress: 1 }); // Just increment without total
|
|
||||||
|
|
||||||
// When complete
|
|
||||||
await reportProgress({ progress: 100, total: 100 });
|
|
||||||
|
|
||||||
// Return the result
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
FYI reportProgress object is not arbitrary. It must be { progress: number, total: number }.
|
|
||||||
|
|
||||||
### Session Usage Convention
|
### Session Usage Convention
|
||||||
|
|
||||||
The `session` object contains authenticated session data and can be used for:
|
The `session` object (destructured from `context`) contains authenticated session data and client information.
|
||||||
|
|
||||||
1. **Authentication information**: Access user-specific data that was set during authentication
|
- **Authentication**: Access user-specific data (`session.userId`, etc.) if authentication is implemented.
|
||||||
2. **Environment variables**: Access environment variables without direct process.env references (if implemented)
|
- **Project Root**: The primary use in Task Master is accessing `session.roots` to determine the client's project root directory via the `getProjectRootFromSession` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)). See the Standard Tool Execution Pattern above.
|
||||||
3. **User context**: Check user permissions or preferences
|
- **Capabilities**: Can be used to check client capabilities (`session.clientCapabilities`).
|
||||||
|
|
||||||
```javascript
|
## Direct Function Wrappers (`*Direct`)
|
||||||
execute: async (args, { log, reportProgress, session }) => {
|
|
||||||
// Check if session exists (user is authenticated)
|
|
||||||
if (!session) {
|
|
||||||
log.warn("No session data available, operating in anonymous mode");
|
|
||||||
} else {
|
|
||||||
// Access authenticated user information
|
|
||||||
log.info(`Operation requested by user: ${session.userId}`);
|
|
||||||
|
|
||||||
// Access environment variables or configuration via session
|
|
||||||
const apiKey = session.env?.API_KEY;
|
|
||||||
|
|
||||||
// Check user-specific permissions
|
|
||||||
if (session.permissions?.canUpdateTasks) {
|
|
||||||
// Perform privileged operation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue with implementation...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Accessing Project Roots through Session
|
These functions, located in `mcp-server/src/core/direct-functions/`, form the core logic execution layer for MCP tools.
|
||||||
|
|
||||||
The `session` object in FastMCP provides access to filesystem roots via the `session.roots` array, which can be used to get the client's project root directory. This can help bypass some of the path resolution logic in `path-utils.js` when the client explicitly provides its project root.
|
- **Purpose**: Bridge MCP tools and core Task Master modules (`scripts/modules/*`).
|
||||||
|
- **Responsibilities**:
|
||||||
#### What are Session Roots?
|
- Receive `args` (including the `projectRoot` determined by the tool) and `log` object.
|
||||||
|
- **Find `tasks.json`**: Use `findTasksJsonPath(args, log)` from [`core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js). This function prioritizes the provided `args.projectRoot`.
|
||||||
- The `roots` array contains filesystem root objects provided by the FastMCP client (e.g., Cursor).
|
- Validate arguments specific to the core logic.
|
||||||
- Each root object typically represents a mounted filesystem or workspace that the client (IDE) has access to.
|
- **Implement Caching**: Use `getCachedOrExecute` from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) for read operations.
|
||||||
- For tools like Cursor, the first root is usually the current project or workspace root.
|
- Call the underlying function from the core Task Master modules.
|
||||||
|
- Handle errors gracefully.
|
||||||
#### Roots Structure
|
- Return a standardized result object: `{ success: boolean, data?: any, error?: { code: string, message: string }, fromCache: boolean }`.
|
||||||
|
|
||||||
Based on the FastMCP core implementation, the roots structure looks like:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Root type from FastMCP
|
|
||||||
type Root = {
|
|
||||||
uri: string; // URI of the root, e.g., "file:///Users/username/project"
|
|
||||||
name: string; // Display name of the root
|
|
||||||
capabilities?: { // Optional capabilities this root supports
|
|
||||||
// Root-specific capabilities
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Accessing Project Root from Session
|
|
||||||
|
|
||||||
To properly access and use the project root from the session:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
execute: async (args, { log, reportProgress, session }) => {
|
|
||||||
try {
|
|
||||||
// Try to get the project root from session
|
|
||||||
let rootFolder = null;
|
|
||||||
|
|
||||||
if (session && session.roots && session.roots.length > 0) {
|
|
||||||
// The first root is typically the main project workspace in clients like Cursor
|
|
||||||
const firstRoot = session.roots[0];
|
|
||||||
|
|
||||||
if (firstRoot && firstRoot.uri) {
|
|
||||||
// Convert the URI to a file path (strip the file:// prefix if present)
|
|
||||||
const rootUri = firstRoot.uri;
|
|
||||||
rootFolder = rootUri.startsWith('file://')
|
|
||||||
? decodeURIComponent(rootUri.slice(7)) // Remove 'file://' and decode URI components
|
|
||||||
: rootUri;
|
|
||||||
|
|
||||||
log.info(`Using project root from session: ${rootFolder}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use rootFolder if available, otherwise let path-utils.js handle the detection
|
|
||||||
const result = await yourDirectFunction({
|
|
||||||
projectRoot: rootFolder,
|
|
||||||
...args
|
|
||||||
}, log);
|
|
||||||
|
|
||||||
return handleApiResult(result, log);
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error in tool: ${error.message}`);
|
|
||||||
return createErrorResponse(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Integration with path-utils.js
|
|
||||||
|
|
||||||
The `rootFolder` extracted from the session should be passed to the direct function as the `projectRoot` parameter. This integrates with `findTasksJsonPath` in `path-utils.js`, which uses a precedence order for finding the project root:
|
|
||||||
|
|
||||||
1. **TASK_MASTER_PROJECT_ROOT** environment variable
|
|
||||||
2. **Explicitly provided `projectRoot`** (from session.roots or args)
|
|
||||||
3. Previously found/cached project root
|
|
||||||
4. Search from current directory upwards
|
|
||||||
5. Package directory fallback
|
|
||||||
|
|
||||||
By providing the rootFolder from session.roots as the projectRoot parameter, we're using the second option in this hierarchy, allowing the client to explicitly tell us where the project is located rather than having to search for it.
|
|
||||||
|
|
||||||
#### Example Implementation
|
|
||||||
|
|
||||||
Here's a complete example for a tool that properly uses session roots:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
execute: async (args, { log, reportProgress, session }) => {
|
|
||||||
try {
|
|
||||||
log.info(`Starting tool with args: ${JSON.stringify(args)}`);
|
|
||||||
|
|
||||||
// Extract project root from session if available
|
|
||||||
let rootFolder = null;
|
|
||||||
if (session && session.roots && session.roots.length > 0) {
|
|
||||||
const firstRoot = session.roots[0];
|
|
||||||
if (firstRoot && firstRoot.uri) {
|
|
||||||
rootFolder = firstRoot.uri.startsWith('file://')
|
|
||||||
? decodeURIComponent(firstRoot.uri.slice(7))
|
|
||||||
: firstRoot.uri;
|
|
||||||
log.info(`Using project root from session: ${rootFolder}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we couldn't get a root from session but args has projectRoot, use that
|
|
||||||
if (!rootFolder && args.projectRoot) {
|
|
||||||
rootFolder = args.projectRoot;
|
|
||||||
log.info(`Using project root from args: ${rootFolder}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the direct function with the rootFolder
|
|
||||||
const result = await someDirectFunction({
|
|
||||||
projectRoot: rootFolder,
|
|
||||||
...args
|
|
||||||
}, log);
|
|
||||||
|
|
||||||
log.info(`Completed tool successfully`);
|
|
||||||
return handleApiResult(result, log);
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error in tool: ${error.message}`);
|
|
||||||
return createErrorResponse(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Principles
|
## Key Principles
|
||||||
|
|
||||||
- **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers (exported via [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), implemented in [`mcp-server/src/core/direct-functions/`](mdc:mcp-server/src/core/direct-functions/)). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)).
|
- **Prefer Direct Function Calls**: MCP tools should always call `*Direct` wrappers instead of `executeTaskMasterCommand`.
|
||||||
- **Standard Tool Execution Pattern**:
|
- **Standardized Execution Flow**: Follow the pattern: MCP Tool -> `getProjectRootFromSession` -> `*Direct` Function -> Core Logic.
|
||||||
- The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should:
|
- **Path Resolution via Direct Functions**: The `*Direct` function is responsible for finding the exact `tasks.json` path using `findTasksJsonPath`, relying on the `projectRoot` passed in `args`.
|
||||||
1. Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`), passing the *entire* `args` object received from the tool invocation and the `log` object.
|
- **Centralized Utilities**: Use helpers from `mcp-server/src/tools/utils.js` (like `handleApiResult`, `getProjectRootFromSession`, `getCachedOrExecute`) and `mcp-server/src/core/utils/path-utils.js` (`findTasksJsonPath`). See [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc).
|
||||||
2. Receive the result object (typically `{ success, data/error, fromCache }`) from the `*Direct` function.
|
- **Caching in Direct Functions**: Caching logic resides *within* the `*Direct` functions using `getCachedOrExecute`.
|
||||||
3. Pass this result object to the `handleApiResult` utility (from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js)) for standardized response formatting and error handling.
|
|
||||||
4. Return the formatted response object provided by `handleApiResult`.
|
|
||||||
- **CLI Execution as Fallback**: The `executeTaskMasterCommand` utility in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) allows executing commands via the CLI (`task-master ...`). This should **only** be used as a fallback if a direct function wrapper is not yet implemented or if a specific command intrinsically requires CLI execution.
|
|
||||||
- **Robust Project Root Handling**:
|
|
||||||
- **Tool Definition**: Any MCP tool that needs to locate the project's `tasks.json` *must* define the `projectRoot` parameter in its `zod` schema as **optional**: `projectRoot: z.string().optional().describe(...)`. This allows clients to optionally specify a root, but doesn't require it.
|
|
||||||
- **Path Resolution Utility**: The `findTasksJsonPath` utility (in [`core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) handles the actual detection of the project root and `tasks.json` path using a hierarchical approach (env var, explicit arg, cache, cwd search, package fallback).
|
|
||||||
- **Direct Function Usage**: The `*Direct` function wrapper (in `mcp-server/src/core/direct-functions/`) is responsible for getting the correct path by calling `const tasksPath = findTasksJsonPath(args, log);`. It passes the *entire `args` object* received by the tool (which may or may not contain `projectRoot` or `file` properties) and the `log` object. `findTasksJsonPath` will use the values within `args` according to its precedence rules.
|
|
||||||
- **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):
|
|
||||||
- **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation:
|
|
||||||
- `handleApiResult`: Takes the raw result from a `*Direct` function and formats it into a standard MCP success or error response, automatically handling data processing via `processMCPResponseData`. This is called by the tool's `execute` method.
|
|
||||||
- `createContentResponse`/`createErrorResponse`: Used by `handleApiResult` to format successful/error MCP responses.
|
|
||||||
- `processMCPResponseData`: Filters/cleans data (e.g., removing `details`, `testStrategy`) before it's sent in the MCP response. Called by `handleApiResult`.
|
|
||||||
- `getCachedOrExecute`: **Used inside `*Direct` functions** to implement caching logic.
|
|
||||||
- `executeTaskMasterCommand`: Fallback for executing CLI commands.
|
|
||||||
- **Caching**: To improve performance for frequently called read operations (like `get_tasks`, `get_task`, `next_task`), a caching layer using `lru-cache` is implemented.
|
|
||||||
- **Caching logic resides *within* the direct function wrappers** using the `getCachedOrExecute` utility from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
|
||||||
- Generate unique cache keys based on function arguments that define a distinct call (e.g., file path, filters).
|
|
||||||
- The `getCachedOrExecute` utility handles checking the cache, executing the core logic function on a cache miss, storing the result, and returning the data along with a `fromCache` flag.
|
|
||||||
- Cache statistics can be monitored using the `cache_stats` MCP tool.
|
|
||||||
- **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set_task_status`, `add_task`, `update_task`, `parse_prd`, `add_dependency` should *not* be cached as they change the underlying data.
|
|
||||||
|
|
||||||
## Resources and Resource Templates
|
## Resources and Resource Templates
|
||||||
|
|
||||||
Resources and resource templates are an important part of the FastMCP architecture that allow for exposing data to LLM clients without needing to execute tools.
|
Resources provide LLMs with static or dynamic data without executing tools.
|
||||||
|
|
||||||
### Resource Implementation
|
- **Implementation**: Use `@mcp.resource()` decorator pattern or `server.addResource`/`server.addResourceTemplate` in `mcp-server/src/core/resources/`.
|
||||||
|
- **Registration**: Register resources during server initialization in [`mcp-server/src/index.js`](mdc:mcp-server/src/index.js).
|
||||||
|
- **Best Practices**: Organize resources, validate parameters, use consistent URIs, handle errors. See [`fastmcp-core.txt`](docs/fastmcp-core.txt) for underlying SDK details.
|
||||||
|
|
||||||
- **Purpose**: Resources provide LLMs with static or dynamic data that can be referenced directly without executing a tool.
|
*(Self-correction: Removed detailed Resource implementation examples as they were less relevant to the current user focus on tool execution flow and project roots. Kept the overview.)*
|
||||||
- **Current Implementation**: In [`mcp-server/src/index.js`](mdc:mcp-server/src/index.js), resources are currently initialized as empty objects:
|
|
||||||
```javascript
|
|
||||||
this.server.addResource({});
|
|
||||||
this.server.addResourceTemplate({});
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Proper Implementation**: Resources should be implemented using the `@mcp.resource()` decorator pattern in a dedicated directory (e.g., `mcp-server/src/core/resources/`).
|
|
||||||
|
|
||||||
- **Resource Types for Task Master**:
|
|
||||||
- **Task Templates**: Predefined task structures that can be used as starting points
|
|
||||||
- **Workflow Definitions**: Reusable workflow patterns for common task sequences
|
|
||||||
- **Project Metadata**: Information about active projects and their attributes
|
|
||||||
- **User Preferences**: Stored user settings for task management
|
|
||||||
|
|
||||||
- **Resource Implementation Example**:
|
|
||||||
```javascript
|
|
||||||
// mcp-server/src/core/resources/task-templates.js
|
|
||||||
import { taskTemplates } from '../data/templates.js';
|
|
||||||
|
|
||||||
export function registerTaskTemplateResources(server) {
|
|
||||||
server.addResource({
|
|
||||||
name: "tasks://templates/{templateId}",
|
|
||||||
description: "Access predefined task templates",
|
|
||||||
parameters: {
|
|
||||||
templateId: {
|
|
||||||
type: "string",
|
|
||||||
description: "ID of the task template"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
execute: async ({ templateId }) => {
|
|
||||||
const template = taskTemplates[templateId];
|
|
||||||
if (!template) {
|
|
||||||
return {
|
|
||||||
status: 404,
|
|
||||||
content: { error: `Template ${templateId} not found` }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
content: template
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register all templates as a collection resource
|
|
||||||
server.addResource({
|
|
||||||
name: "tasks://templates",
|
|
||||||
description: "List all available task templates",
|
|
||||||
execute: async () => {
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
content: Object.keys(taskTemplates).map(id => ({
|
|
||||||
id,
|
|
||||||
name: taskTemplates[id].name,
|
|
||||||
description: taskTemplates[id].description
|
|
||||||
}))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Resource Templates Implementation
|
|
||||||
|
|
||||||
- **Purpose**: Resource templates allow for dynamic generation of resources based on patterns.
|
|
||||||
- **Implementation Example**:
|
|
||||||
```javascript
|
|
||||||
// mcp-server/src/core/resources/task-templates.js
|
|
||||||
export function registerTaskTemplateResourceTemplates(server) {
|
|
||||||
server.addResourceTemplate({
|
|
||||||
pattern: "tasks://create/{taskType}",
|
|
||||||
description: "Generate a task creation template based on task type",
|
|
||||||
parameters: {
|
|
||||||
taskType: {
|
|
||||||
type: "string",
|
|
||||||
description: "Type of task to create (e.g., 'feature', 'bug', 'docs')"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
execute: async ({ taskType }) => {
|
|
||||||
// Generate a dynamic template based on taskType
|
|
||||||
const template = generateTemplateForTaskType(taskType);
|
|
||||||
|
|
||||||
if (!template) {
|
|
||||||
return {
|
|
||||||
status: 404,
|
|
||||||
content: { error: `No template available for task type: ${taskType}` }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 200,
|
|
||||||
content: template
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Resource Registration in Server Initialization
|
|
||||||
|
|
||||||
Resources and resource templates should be registered during server initialization:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// mcp-server/src/index.js
|
|
||||||
import { registerTaskTemplateResources, registerTaskTemplateResourceTemplates } from './core/resources/task-templates.js';
|
|
||||||
import { registerWorkflowResources } from './core/resources/workflow-definitions.js';
|
|
||||||
import { registerProjectMetadataResources } from './core/resources/project-metadata.js';
|
|
||||||
|
|
||||||
class TaskMasterMCPServer {
|
|
||||||
constructor() {
|
|
||||||
// ... existing constructor code ...
|
|
||||||
|
|
||||||
this.server = new FastMCP(this.options);
|
|
||||||
this.initialized = false;
|
|
||||||
|
|
||||||
// Resource registration will be done in init()
|
|
||||||
|
|
||||||
// ... rest of constructor ...
|
|
||||||
}
|
|
||||||
|
|
||||||
async init() {
|
|
||||||
if (this.initialized) return;
|
|
||||||
|
|
||||||
// Register resources before tools
|
|
||||||
registerTaskTemplateResources(this.server);
|
|
||||||
registerTaskTemplateResourceTemplates(this.server);
|
|
||||||
registerWorkflowResources(this.server);
|
|
||||||
registerProjectMetadataResources(this.server);
|
|
||||||
|
|
||||||
// Register Task Master tools
|
|
||||||
registerTaskMasterTools(this.server);
|
|
||||||
|
|
||||||
this.initialized = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... rest of class ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Best Practices for Resources
|
|
||||||
|
|
||||||
1. **Organization**: Create a dedicated `resources` directory with separate modules for each resource category.
|
|
||||||
2. **Validation**: Validate input parameters and return appropriate error responses.
|
|
||||||
3. **Caching**: Consider caching resource responses if they are expensive to generate.
|
|
||||||
4. **Documentation**: Include clear descriptions for all resources and their parameters.
|
|
||||||
5. **URI Structure**: Use consistent URI patterns (`resource-type://path/to/resource`) for all resources.
|
|
||||||
6. **Error Handling**: Return standard HTTP-like status codes (200, 404, etc.) for resource responses.
|
|
||||||
7. **Resource Registration**: Register resources before tools during server initialization.
|
|
||||||
|
|
||||||
Resources enable LLMs to access contextual information without needing to execute tools, which can significantly improve performance and user experience. Properly implemented resources complement tools to create a comprehensive MCP server.
|
|
||||||
|
|
||||||
## Implementing MCP Support for a Command
|
## Implementing MCP Support for a Command
|
||||||
|
|
||||||
@@ -472,14 +170,13 @@ Follow these steps to add MCP support for an existing Task Master command (see [
|
|||||||
|
|
||||||
1. **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.
|
1. **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.
|
||||||
|
|
||||||
2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`:
|
2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:
|
||||||
- Create a new file (e.g., `your-command.js`) in the `direct-functions` directory using **kebab-case** for file naming.
|
- Create a new file (e.g., `your-command.js`) using **kebab-case** naming.
|
||||||
- Import necessary core functions from Task Master modules.
|
- Import necessary core functions and **`findTasksJsonPath` from `../utils/path-utils.js`**.
|
||||||
- Import utilities: **`findTasksJsonPath` from `../utils/path-utils.js`** and `getCachedOrExecute` from `../../tools/utils.js` if needed.
|
|
||||||
- Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:
|
- Implement `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix:
|
||||||
- **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This handles project root detection automatically.
|
- **Path Resolution**: Obtain the tasks file path using `const tasksPath = findTasksJsonPath(args, log);`. This handles project root detection automatically based on `args.projectRoot`.
|
||||||
- Parse other `args` and perform necessary validation.
|
- Parse other `args` and perform necessary validation.
|
||||||
- **If Caching**: Implement caching using `getCachedOrExecute` as described above.
|
- **If Caching**: Implement caching using `getCachedOrExecute` from `../../tools/utils.js`.
|
||||||
- **If Not Caching**: Directly call the core logic function within a try/catch block.
|
- **If Not Caching**: Directly call the core logic function within a try/catch block.
|
||||||
- Format the return as `{ success: true/false, data/error, fromCache: boolean }`.
|
- Format the return as `{ success: true/false, data/error, fromCache: boolean }`.
|
||||||
- Export the wrapper function.
|
- Export the wrapper function.
|
||||||
@@ -488,11 +185,14 @@ Follow these steps to add MCP support for an existing Task Master command (see [
|
|||||||
|
|
||||||
4. **Create MCP Tool (`mcp-server/src/tools/`)**:
|
4. **Create MCP Tool (`mcp-server/src/tools/`)**:
|
||||||
- Create a new file (e.g., `your-command.js`) using **kebab-case**.
|
- Create a new file (e.g., `your-command.js`) using **kebab-case**.
|
||||||
- Import `zod`, `handleApiResult`, `createErrorResponse`, and your `yourCommandDirect` function.
|
- Import `zod`, `handleApiResult`, `createErrorResponse`, **`getProjectRootFromSession`**, and your `yourCommandDirect` function.
|
||||||
- Implement `registerYourCommandTool(server)`.
|
- Implement `registerYourCommandTool(server)`.
|
||||||
- Define the tool `name` using **snake_case** (e.g., `your_command`).
|
- Define the tool `name` using **snake_case** (e.g., `your_command`).
|
||||||
- Define the `parameters` using `zod`. **Crucially, if the tool needs project context, include `projectRoot: z.string().optional().describe(...)` and potentially `file: z.string().optional().describe(...)`**. Make `projectRoot` optional.
|
- Define the `parameters` using `zod`. **Crucially, define `projectRoot` as optional**: `projectRoot: z.string().optional().describe(...)`. Include `file` if applicable.
|
||||||
- Implement the standard `async execute(args, { log, reportProgress, session })` method: call `yourCommandDirect(args, log)` and pass the result to `handleApiResult(result, log, 'Error Message')`.
|
- Implement the standard `async execute(args, { log, reportProgress, session })` method:
|
||||||
|
- Get `rootFolder` using `getProjectRootFromSession` (with fallback to `args.projectRoot`).
|
||||||
|
- Call `yourCommandDirect({ ...args, projectRoot: rootFolder }, log)`.
|
||||||
|
- Pass the result to `handleApiResult(result, log, 'Error Message')`.
|
||||||
|
|
||||||
5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.
|
5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.
|
||||||
|
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ Integrating Task Master commands with the MCP server (for use by tools like Curs
|
|||||||
- Create a new file (e.g., `your-command.js`) in `mcp-server/src/core/direct-functions/` using **kebab-case** naming.
|
- Create a new file (e.g., `your-command.js`) in `mcp-server/src/core/direct-functions/` using **kebab-case** naming.
|
||||||
- Import the core logic function and necessary MCP utilities like **`findTasksJsonPath` from `../utils/path-utils.js`** and potentially `getCachedOrExecute` from `../../tools/utils.js`.
|
- Import the core logic function and necessary MCP utilities like **`findTasksJsonPath` from `../utils/path-utils.js`** and potentially `getCachedOrExecute` from `../../tools/utils.js`.
|
||||||
- Implement an `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix.
|
- Implement an `async function yourCommandDirect(args, log)` using **camelCase** with `Direct` suffix.
|
||||||
- **Path Finding**: Inside this function, obtain the `tasksPath` by calling `const tasksPath = findTasksJsonPath(args, log);`. Pass the *entire `args` object* received by the tool and the `log` object.
|
- **Path Finding**: Inside this function, obtain the `tasksPath` by calling `const tasksPath = findTasksJsonPath(args, log);`. This relies on `args.projectRoot` (derived from the session) being passed correctly.
|
||||||
- Perform validation on other arguments received in `args`.
|
- Perform validation on other arguments received in `args`.
|
||||||
- **Implement Caching (if applicable)**:
|
- **Implement Caching (if applicable)**:
|
||||||
- **Use Case**: Apply caching primarily for read-only operations that benefit from repeated calls (e.g., `get_tasks`, `get_task`, `next_task`). Avoid caching for operations that modify state (`set_task_status`, `add_task`, `parse_prd`, `update_task`, `add_dependency`, etc.).
|
- **Use Case**: Apply caching primarily for read-only operations that benefit from repeated calls (e.g., `get_tasks`, `get_task`, `next_task`). Avoid caching for operations that modify state (`set_task_status`, `add_task`, `parse_prd`, `update_task`, `add_dependency`, etc.).
|
||||||
@@ -338,14 +338,14 @@ Integrating Task Master commands with the MCP server (for use by tools like Curs
|
|||||||
3. **Export from `task-master-core.js`**: Import your new `*Direct` function into [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), re-export it, and add it to the `directFunctions` map.
|
3. **Export from `task-master-core.js`**: Import your new `*Direct` function into [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), re-export it, and add it to the `directFunctions` map.
|
||||||
4. **MCP Tool File (`mcp-server/src/tools/`)**:
|
4. **MCP Tool File (`mcp-server/src/tools/`)**:
|
||||||
- Create a new file (e.g., `your-command.js`) using **kebab-case** naming.
|
- Create a new file (e.g., `your-command.js`) using **kebab-case** naming.
|
||||||
- Import `zod` (for schema), `handleApiResult`, `createErrorResponse` from `./utils.js`, and your `yourCommandDirect` function from `../core/task-master-core.js`.
|
- Import `zod` (for schema), `handleApiResult`, `createErrorResponse`, **`getProjectRootFromSession`** from `./utils.js`, and your `yourCommandDirect` function from `../core/task-master-core.js`.
|
||||||
- Implement `registerYourCommandTool(server)` using **camelCase** with `Tool` suffix, which calls `server.addTool`.
|
- Implement `registerYourCommandTool(server)` using **camelCase** with `Tool` suffix, which calls `server.addTool`.
|
||||||
- Define the tool's `name` using **snake_case** (e.g., `your_command`), `description`, and `parameters` using `zod`. **Crucially, define `projectRoot` as optional**: `projectRoot: z.string().optional().describe(...)`. Include `file: z.string().optional().describe(...)` if applicable.
|
- Define the tool's `name` using **snake_case** (e.g., `your_command`), `description`, and `parameters` using `zod`. **Crucially, define `projectRoot` as optional**: `projectRoot: z.string().optional().describe(...)`. Include `file: z.string().optional().describe(...)` if applicable.
|
||||||
- Define the standard `async execute(args, log)` method:
|
- Define the standard `async execute(args, { log, reportProgress, session })` method:
|
||||||
```javascript
|
```javascript
|
||||||
// In mcp-server/src/tools/your-command.js
|
// In mcp-server/src/tools/your-command.js
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { handleApiResult, createErrorResponse } from "./utils.js";
|
import { handleApiResult, createErrorResponse, getProjectRootFromSession } from "./utils.js";
|
||||||
import { yourCommandDirect } from "../core/task-master-core.js"; // Adjust path as needed
|
import { yourCommandDirect } from "../core/task-master-core.js"; // Adjust path as needed
|
||||||
|
|
||||||
export function registerYourCommandTool(server) {
|
export function registerYourCommandTool(server) {
|
||||||
@@ -358,14 +358,25 @@ Integrating Task Master commands with the MCP server (for use by tools like Curs
|
|||||||
file: z.string().optional().describe("Optional tasks file path relative to project root"),
|
file: z.string().optional().describe("Optional tasks file path relative to project root"),
|
||||||
/* other parameters */
|
/* other parameters */
|
||||||
}),
|
}),
|
||||||
async execute(args, log) {
|
execute: async (args, { log, reportProgress, session }) => { // Destructure context
|
||||||
try {
|
try {
|
||||||
log.info(`Executing your_command with args: ${JSON.stringify(args)}`);
|
log.info(`Executing your_command with args: ${JSON.stringify(args)}`);
|
||||||
// 1. Call the direct function wrapper
|
|
||||||
const result = await yourCommandDirect(args, log);
|
|
||||||
|
|
||||||
// 2. Pass the result to handleApiResult for formatting
|
// 1. Get project root from session (or args fallback)
|
||||||
return handleApiResult(result, log, 'Error executing your_command'); // Provide a default error message
|
let rootFolder = getProjectRootFromSession(session, log);
|
||||||
|
if (!rootFolder && args.projectRoot) {
|
||||||
|
rootFolder = args.projectRoot;
|
||||||
|
log.info(`Using project root from args as fallback: ${rootFolder}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Call the direct function wrapper, passing the resolved root
|
||||||
|
const result = await yourCommandDirect({
|
||||||
|
...args,
|
||||||
|
projectRoot: rootFolder // Pass the resolved root
|
||||||
|
}, log);
|
||||||
|
|
||||||
|
// 3. Pass the result to handleApiResult for formatting
|
||||||
|
return handleApiResult(result, log, 'Error executing your_command'); // Provide default error
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Catch unexpected errors from the direct call or handleApiResult itself
|
// Catch unexpected errors from the direct call or handleApiResult itself
|
||||||
log.error(`Unexpected error in your_command tool execute: ${error.message}`);
|
log.error(`Unexpected error in your_command tool execute: ${error.message}`);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ alwaysApply: false
|
|||||||
|
|
||||||
- **Location**:
|
- **Location**:
|
||||||
- **Core CLI Utilities**: Place utilities used primarily by the core `task-master` CLI logic and command modules (`scripts/modules/*`) into [`scripts/modules/utils.js`](mdc:scripts/modules/utils.js).
|
- **Core CLI Utilities**: Place utilities used primarily by the core `task-master` CLI logic and command modules (`scripts/modules/*`) into [`scripts/modules/utils.js`](mdc:scripts/modules/utils.js).
|
||||||
- **MCP Server Utilities**: Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/`.
|
- **MCP Server Utilities**: Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within `mcp-server/src/`.
|
||||||
- Path/Core Logic Helpers: [`mcp-server/src/core/utils/`](mdc:mcp-server/src/core/utils/) (e.g., `path-utils.js`).
|
- Path/Core Logic Helpers: [`mcp-server/src/core/utils/`](mdc:mcp-server/src/core/utils/) (e.g., `path-utils.js`).
|
||||||
- Tool Execution/Response Helpers: [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
- Tool Execution/Response Helpers: [`mcp-server/src/tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
||||||
|
|
||||||
@@ -288,30 +288,29 @@ alwaysApply: false
|
|||||||
|
|
||||||
### Project Root and Task File Path Detection (`path-utils.js`)
|
### Project Root and Task File Path Detection (`path-utils.js`)
|
||||||
|
|
||||||
- **Purpose**: This module (`mcp-server/src/core/utils/path-utils.js`) provides the **primary mechanism for locating the user's project root and `tasks.json` file**, specifically for the MCP server context.
|
- **Purpose**: This module ([`mcp-server/src/core/utils/path-utils.js`](mdc:mcp-server/src/core/utils/path-utils.js)) provides the mechanism for locating the user's `tasks.json` file, used by direct functions.
|
||||||
- **`findTasksJsonPath(args, log)`**:
|
- **`findTasksJsonPath(args, log)`**:
|
||||||
- ✅ **DO**: Call this function from within **direct function wrappers** (e.g., `listTasksDirect` in `mcp-server/src/core/direct-functions/`) to get the absolute path to the relevant `tasks.json`.
|
- ✅ **DO**: Call this function from within **direct function wrappers** (e.g., `listTasksDirect` in `mcp-server/src/core/direct-functions/`) to get the absolute path to the relevant `tasks.json`.
|
||||||
- Pass the *entire `args` object* received by the MCP tool and the `log` object.
|
- Pass the *entire `args` object* received by the MCP tool (which should include `projectRoot` derived from the session) and the `log` object.
|
||||||
- Implements a **hierarchical precedence system** for finding the project:
|
- Implements a **simplified precedence system** for finding the `tasks.json` path:
|
||||||
1. `TASK_MASTER_PROJECT_ROOT` environment variable.
|
1. Explicit `projectRoot` passed in `args` (Expected from MCP tools).
|
||||||
2. Explicit `projectRoot` passed in `args`.
|
2. Cached `lastFoundProjectRoot` (CLI fallback).
|
||||||
3. Cached `lastFoundProjectRoot` from a previous successful search.
|
3. Search upwards from `process.cwd()` (CLI fallback).
|
||||||
4. Search upwards from `process.cwd()` for `tasks.json` or project markers (like `.git`, `package.json`).
|
|
||||||
5. Fallback to checking the Taskmaster package directory (for development).
|
|
||||||
- Throws a specific error if the `tasks.json` file cannot be located.
|
- Throws a specific error if the `tasks.json` file cannot be located.
|
||||||
- Updates the `lastFoundProjectRoot` cache on success.
|
- Updates the `lastFoundProjectRoot` cache on success.
|
||||||
- **`PROJECT_MARKERS`**: An exported array of common file/directory names used to identify a likely project root during the search.
|
- **`PROJECT_MARKERS`**: An exported array of common file/directory names used to identify a likely project root during the CLI fallback search.
|
||||||
- **`getPackagePath()`**: Utility to find the installation path of the `task-master-ai` package itself.
|
- **`getPackagePath()`**: Utility to find the installation path of the `task-master-ai` package itself (potentially removable).
|
||||||
|
|
||||||
## MCP Server Tool Utilities (`mcp-server/src/tools/utils.js`)
|
## MCP Server Tool Utilities (`mcp-server/src/tools/utils.js`)
|
||||||
|
|
||||||
- **Purpose**: These utilities specifically support the MCP server tools (`mcp-server/src/tools/*.js`), handling MCP communication patterns, response formatting, caching integration, and the CLI fallback mechanism.
|
- **Purpose**: These utilities specifically support the MCP server tools ([`mcp-server/src/tools/*.js`](mdc:mcp-server/src/tools/*.js)), handling MCP communication patterns, response formatting, caching integration, and the CLI fallback mechanism.
|
||||||
- **Refer to [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)** for detailed usage patterns within the MCP tool `execute` methods and direct function wrappers.
|
- **Refer to [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)** for detailed usage patterns within the MCP tool `execute` methods and direct function wrappers.
|
||||||
|
|
||||||
- **`getProjectRoot(projectRootRaw, log)`**:
|
- **`getProjectRootFromSession(session, log)`**:
|
||||||
- Primarily a helper for `executeTaskMasterCommand` or other specific cases where only the root is needed, *not* the full `tasks.json` path.
|
- ✅ **DO**: Call this utility **within the MCP tool's `execute` method** to extract the project root path from the `session` object.
|
||||||
- Normalizes a potentially relative path and applies defaults.
|
- Decodes the `file://` URI and handles potential errors.
|
||||||
- ❌ **DON'T**: Use this as the primary way to find `tasks.json`. Use `findTasksJsonPath` from `path-utils.js` for that purpose within direct functions.
|
- Returns the project path string or `null`.
|
||||||
|
- The returned path should then be passed in the `args` object when calling the corresponding `*Direct` function (e.g., `yourDirectFunction({ ...args, projectRoot: rootFolder }, log)`).
|
||||||
|
|
||||||
- **`handleApiResult(result, log, errorPrefix, processFunction)`**:
|
- **`handleApiResult(result, log, errorPrefix, processFunction)`**:
|
||||||
- ✅ **DO**: Call this from the MCP tool's `execute` method after receiving the result from the `*Direct` function wrapper.
|
- ✅ **DO**: Call this from the MCP tool's `execute` method after receiving the result from the `*Direct` function wrapper.
|
||||||
@@ -381,6 +380,7 @@ export {
|
|||||||
// Example export from mcp-server/src/tools/utils.js
|
// Example export from mcp-server/src/tools/utils.js
|
||||||
export {
|
export {
|
||||||
getProjectRoot,
|
getProjectRoot,
|
||||||
|
getProjectRootFromSession,
|
||||||
handleApiResult,
|
handleApiResult,
|
||||||
executeTaskMasterCommand,
|
executeTaskMasterCommand,
|
||||||
processMCPResponseData,
|
processMCPResponseData,
|
||||||
|
|||||||
Reference in New Issue
Block a user