--- description: Guidelines for implementing and interacting with the Task Master MCP Server globs: mcp-server/src/**/*, scripts/modules/**/* alwaysApply: false --- # Task Master MCP Server Guidelines This document outlines the architecture and implementation patterns for the Task Master Model Context Protocol (MCP) server, designed for integration with tools like Cursor. ## Architecture Overview (See also: [`architecture.mdc`](mdc:.cursor/rules/architecture.mdc)) The MCP server acts as a bridge between external tools (like Cursor) and the core Task Master CLI logic. It leverages FastMCP for the server framework. - **Flow**: `External Tool (Cursor)` <-> `FastMCP Server` <-> `MCP Tools` (`mcp-server/src/tools/*.js`) <-> `Core Logic Wrappers` (`mcp-server/src/core/task-master-core.js`) <-> `Core Modules` (`scripts/modules/*.js`) - **Goal**: Provide a performant and reliable way for external tools to interact with Task Master functionality without directly invoking the CLI for every operation. ## Key Principles - **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers defined in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)). - **Standard Tool Execution Pattern**: - The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should: 1. Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`) from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), passing necessary arguments and the logger. 2. Receive the result object (typically `{ success, data/error, fromCache }`). 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. - **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)): - Use `findTasksJsonPath` (in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) *within direct function wrappers* to locate the `tasks.json` file consistently. - **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation: - `getProjectRoot`: Normalizes project paths. - `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** in `task-master-core.js` to implement caching logic. - `executeTaskMasterCommand`: Fallback for executing CLI commands. - **Caching**: To improve performance for frequently called read operations (like `listTasks`, `showTask`, `nextTask`), a caching layer using `lru-cache` is implemented. - **Caching logic resides *within* the direct function wrappers** in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) 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 `cacheStats` MCP tool (implemented via `getCacheStatsDirect`). - **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set-status`, `add-task`, `update-task`, `parse-prd`, `add-dependency` should *not* be cached as they change the underlying data. ## Implementing MCP Support for a Command Follow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail): 1. **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`. 2. **Create Direct Wrapper (`task-master-core.js`)**: - Create an `async function yourCommandDirect(args, log)` in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). - Inside the wrapper: - Import necessary core functions and utilities (`findTasksJsonPath`, `getCachedOrExecute` if caching). - Parse `args` and determine necessary inputs (e.g., `tasksPath` via `findTasksJsonPath`). - **If Caching**: - Generate a unique `cacheKey` based on arguments defining the operation. - Define an `async` function `coreActionFn` containing the actual call to the core logic, formatting its return as `{ success: true/false, data/error }`. - Call `const result = await getCachedOrExecute({ cacheKey, actionFn: coreActionFn, log });`. - `return result;` (which includes the `fromCache` flag). - **If Not Caching**: - Directly call the core logic function within a try/catch block. - Format the return as `{ success: true/false, data/error, fromCache: false }`. - Export the wrapper function and add it to the `directFunctions` map. 3. **Create MCP Tool (`mcp-server/src/tools/`)**: - Create a new file (e.g., `yourCommand.js`). - Import `z` for schema definition. - Import `handleApiResult` from [`./utils.js`](mdc:mcp-server/src/tools/utils.js). - Import the `yourCommandDirect` wrapper function from `../core/task-master-core.js`. - Implement `registerYourCommandTool(server)`: - Call `server.addTool`. - Define `name`, `description`, and `parameters` using `zod` (include optional `projectRoot`, `file` if needed). - Define the `async execute(args, log)` function: ```javascript async execute(args, log) { try { log.info(`Executing Your Command with args: ${JSON.stringify(args)}`); // Call the direct function wrapper const result = await yourCommandDirect(args, log); // Let handleApiResult format the final MCP response return handleApiResult(result, log, 'Error during Your Command'); // Optionally pass a custom processor to handleApiResult if default filtering isn't sufficient: // return handleApiResult(result, log, 'Error...', customDataProcessor); } catch (error) { // Catch unexpected errors during the direct call itself log.error(`Unexpected error in tool execute: ${error.message}`); // Use createErrorResponse for unexpected errors return createErrorResponse(`Tool execution failed: ${error.message}`); } } ``` 4. **Register Tool**: Import and call `registerYourCommandTool` in [`mcp-server/src/tools/index.js`](mdc:mcp-server/src/tools/index.js). 5. **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`. ## Handling Responses - MCP tools should return the object generated by `handleApiResult`. - `handleApiResult` uses `createContentResponse` or `createErrorResponse` internally. - `handleApiResult` also uses `processMCPResponseData` by default to filter potentially large fields (`details`, `testStrategy`) from task data. Provide a custom processor function to `handleApiResult` if different filtering is needed. - The final JSON response sent to the MCP client will include the `fromCache` boolean flag (obtained from the `*Direct` function's result) alongside the actual data (e.g., `{ "fromCache": true, "data": { ... } }` or `{ "fromCache": false, "data": { ... } }`). ## Parameter Type Handling - **Prefer Direct Function Calls**: For optimal performance and error handling, MCP tools should utilize direct function wrappers defined in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js). These wrappers call the underlying logic from the core modules (e.g., [`task-manager.js`](mdc:scripts/modules/task-manager.js)). - **Standard Tool Execution Pattern**: - The `execute` method within each MCP tool (in `mcp-server/src/tools/*.js`) should: 1. Call the corresponding `*Direct` function wrapper (e.g., `listTasksDirect`) from [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js), passing necessary arguments and the logger. 2. Receive the result object (typically `{ success, data/error, fromCache }`). 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. - **Centralized Utilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)): - Use `findTasksJsonPath` (in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) *within direct function wrappers* to locate the `tasks.json` file consistently. - **Leverage MCP Utilities**: The file [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) contains essential helpers for MCP tool implementation: - `getProjectRoot`: Normalizes project paths. - `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** in `task-master-core.js` to implement caching logic. - `executeTaskMasterCommand`: Fallback for executing CLI commands. - **Caching**: To improve performance for frequently called read operations (like `listTasks`, `showTask`, `nextTask`), a caching layer using `lru-cache` is implemented. - **Caching logic resides *within* the direct function wrappers** in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) 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 `cacheStats` MCP tool (implemented via `getCacheStatsDirect`). - **Caching should generally be applied to read-only operations** that don't modify the `tasks.json` state. Commands like `set-status`, `add-task`, `update-task`, `parse-prd`, `add-dependency` should *not* be cached as they change the underlying data. **MCP Tool Implementation Checklist**: 1. **Core Logic Verification**: - [ ] Confirm the core function is properly exported from its module (e.g., `task-manager.js`) - [ ] Identify all required parameters and their types 2. **Direct Function Wrapper**: - [ ] Create the `*Direct` function in `task-master-core.js` - [ ] Handle all parameter validations and type conversions - [ ] Implement path resolving for relative paths - [ ] Add appropriate error handling with standardized error codes - [ ] Add to `directFunctions` map 3. **MCP Tool Implementation**: - [ ] Create new file in `mcp-server/src/tools/` with kebab-case naming - [ ] Define zod schema for all parameters - [ ] Implement the `execute` method following the standard pattern - [ ] Register tool in `mcp-server/src/tools/index.js` 4. **Testing**: - [ ] Write unit tests for the direct function wrapper - [ ] Write integration tests for the MCP tool ## Standard Error Codes - **Standard Error Codes**: Use consistent error codes across direct function wrappers - `INPUT_VALIDATION_ERROR`: For missing or invalid required parameters - `FILE_NOT_FOUND_ERROR`: For file system path issues - `CORE_FUNCTION_ERROR`: For errors thrown by the core function - `UNEXPECTED_ERROR`: For all other unexpected errors - **Error Object Structure**: ```javascript { success: false, error: { code: 'ERROR_CODE', message: 'Human-readable error message' }, fromCache: false } ``` - **MCP Tool Logging Pattern**: - ✅ DO: Log the start of execution with arguments (sanitized if sensitive) - ✅ DO: Log successful completion with result summary - ✅ DO: Log all error conditions with appropriate log levels - ✅ DO: Include the cache status in result logs - ❌ DON'T: Log entire large data structures or sensitive information - The MCP server integrates with Task Master core functions through three layers: 1. Tool Definitions (`mcp-server/src/tools/*.js`) - Define parameters and execute methods 2. Direct Function Wrappers (`task-master-core.js`) - Handle validation, path resolution, and caching 3. Core Logic Functions (various modules) - Implement actual functionality - This layered approach provides: - Clear separation of concerns - Consistent parameter validation - Centralized error handling - Performance optimization through caching (for read operations) - Standardized response formatting