--- 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 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. - Import necessary core functions from Task Master modules (e.g., `../../../../scripts/modules/task-manager.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: - 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 call to the core logic. - Call `const result = await getCachedOrExecute({ cacheKey, actionFn: coreActionFn, log });`. - **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 }`. - Export the wrapper function. 3. **Update `task-master-core.js` with Import/Export**: - Import your direct function: `import { yourCommandDirect } from './direct-functions/your-command.js';` - Re-export it in the exports section. - Add it to the `directFunctions` map: `yourCommand: yourCommandDirect`. 4. **Create MCP Tool (`mcp-server/src/tools/`)**: - Create a new file (e.g., `your-command.js`) using **kebab-case**. - Import `z` for schema definition. - Import `handleApiResult` from `./utils.js`. - Import the `yourCommandDirect` wrapper function from `../core/task-master-core.js`. - Implement `registerYourCommandTool(server)` using **camelCase** with `Tool` suffix. - Define the tool `name` using **snake_case** (e.g., `your_command`). 5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`. 6. **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 ## MCP Naming Conventions - **Files and Directories**: - ✅ DO: Use **kebab-case** for all file names: `list-tasks.js`, `set-task-status.js` - ✅ DO: Use consistent directory structure: `mcp-server/src/tools/` for tool definitions, `mcp-server/src/core/direct-functions/` for direct function implementations - **JavaScript Functions**: - ✅ DO: Use **camelCase** with `Direct` suffix for direct function implementations: `listTasksDirect`, `setTaskStatusDirect` - ✅ DO: Use **camelCase** with `Tool` suffix for tool registration functions: `registerListTasksTool`, `registerSetTaskStatusTool` - ✅ DO: Use consistent action function naming inside direct functions: `coreActionFn` or similar descriptive name - **MCP Tool Names**: - ✅ DO: Use **snake_case** for tool names exposed to MCP clients: `list_tasks`, `set_task_status`, `parse_prd_document` - ✅ DO: Include the core action in the tool name without redundant words: Use `list_tasks` instead of `list_all_tasks` - **Examples**: - File: `list-tasks.js` - Direct Function: `listTasksDirect` - Tool Registration: `registerListTasksTool` - MCP Tool Name: `list_tasks` - **Mapping**: - The `directFunctions` map in `task-master-core.js` maps the core function name (in camelCase) to its direct implementation: ```javascript export const directFunctions = { list: listTasksDirect, setStatus: setTaskStatusDirect, // Add more functions as implemented }; ```