From c600b96bff76a10d16eade8b0aec050b6d27ba60 Mon Sep 17 00:00:00 2001 From: Eyal Toledano Date: Sun, 30 Mar 2025 02:38:51 -0400 Subject: [PATCH] chore: documentation update and cursor rules update. --- .cursor/rules/architecture.mdc | 1 + .cursor/rules/mcp.mdc | 34 ++++++++++++++++++++++++---------- .cursor/rules/new_features.mdc | 3 ++- .cursor/rules/utilities.mdc | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/.cursor/rules/architecture.mdc b/.cursor/rules/architecture.mdc index eb414111..b05b9d35 100644 --- a/.cursor/rules/architecture.mdc +++ b/.cursor/rules/architecture.mdc @@ -108,6 +108,7 @@ alwaysApply: false - Handles MCP requests and translates them into calls to the Task Master core logic. - Prefers direct function calls to core modules via [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) for performance. - Uses CLI execution via `executeTaskMasterCommand` as a fallback. + - **Implements Caching**: Utilizes a caching layer (`ContextManager` with `lru-cache`) invoked via `getCachedOrExecute` within direct function wrappers ([`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) to optimize performance for specific read operations (e.g., listing tasks). - Standardizes response formatting for MCP clients using utilities in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js). - **Key Components**: - `mcp-server/src/server.js`: Main server setup and initialization. diff --git a/.cursor/rules/mcp.mdc b/.cursor/rules/mcp.mdc index 0cf6f633..0789ddcc 100644 --- a/.cursor/rules/mcp.mdc +++ b/.cursor/rules/mcp.mdc @@ -29,22 +29,35 @@ The MCP server acts as a bridge between external tools (like Cursor) and the cor - `processMCPResponseData`: Filters/cleans data for MCP responses (e.g., removing `details`, `testStrategy`). This is the default processor used by `executeMCPToolAction`. - `executeMCPToolAction`: The primary wrapper function for tool execution logic. - `executeTaskMasterCommand`: Fallback for executing CLI commands. +- **Caching**: To improve performance for frequently called read operations (like `listTasks`), a caching layer using `lru-cache` is implemented. + - Caching logic should be added *inside* 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. + - Responses will include a `fromCache` flag. + - Cache statistics can be monitored using the `cacheStats` MCP tool (implemented via `getCacheStatsDirect`). ## 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**: In [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js): - - Import the core function. - - Create an `async function yourCommandDirect(args, log)` wrapper. - - Inside the wrapper: - - Use `findTasksJsonPath(args, log)` if the command needs the tasks file path. - - Extract and validate arguments from `args`. - - Call the imported core logic function. - - Handle errors using `try/catch`. - - Return a standardized object: `{ success: true, data: result }` or `{ success: false, error: { code: '...', message: '...' } }`. - - Export the wrapper function and add it to the `directFunctions` map. + 2. **Create Direct Wrapper**: In [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js): + - Import the core function. + - Import `getCachedOrExecute` from `../tools/utils.js`. + - Create an `async function yourCommandDirect(args, log)` wrapper. + - Inside the wrapper: + - Determine arguments needed for both the core logic and the cache key (e.g., `tasksPath`, filters). Use `findTasksJsonPath(args, log)` if needed. + - **Generate a unique `cacheKey`** based on the arguments that define a distinct operation (e.g., `\`yourCommand:${tasksPath}:${filter}\``). + - **Define the `coreActionFn`**: An `async` function that contains the actual call to the imported core logic function, handling its specific errors and returning `{ success: true/false, data/error }`. + - **Call `getCachedOrExecute`**: + ```javascript + const result = await getCachedOrExecute({ + cacheKey, + actionFn: coreActionFn, // The function wrapping the core logic call + log + }); + return result; // Returns { success, data/error, fromCache } + ``` + - Export the wrapper function and add it to the `directFunctions` map. 3. **Create MCP Tool**: In `mcp-server/src/tools/`: - Create a new file (e.g., `yourCommand.js`). - Import `z` for parameter schema definition. @@ -71,3 +84,4 @@ Follow these steps to add MCP support for an existing Task Master command (see [ - MCP tools should return data formatted by `createContentResponse` (which stringifies objects) or `createErrorResponse`. - The `processMCPResponseData` utility automatically removes potentially large fields like `details` and `testStrategy` from task objects before they are returned. This is the default behavior when using `executeMCPToolAction`. If specific fields need to be preserved or different fields removed, a custom `processResult` function can be passed to `executeMCPToolAction`. +- The `handleApiResult` utility (used by `executeMCPToolAction`) now expects the result object from the direct function wrapper to include a `fromCache` boolean flag. This flag is included in the final JSON response sent to the MCP client, nested alongside the actual data (e.g., `{ "fromCache": true, "data": { ... } }`). diff --git a/.cursor/rules/new_features.mdc b/.cursor/rules/new_features.mdc index afde612a..51037d35 100644 --- a/.cursor/rules/new_features.mdc +++ b/.cursor/rules/new_features.mdc @@ -325,7 +325,8 @@ Integrating Task Master commands with the MCP server (for use by tools like Curs - This function imports and calls the core logic. - It uses utilities like `findTasksJsonPath` if needed. - It handles argument parsing and validation specific to the direct call. - - It returns a standard `{ success: true/false, data/error }` object. + - **Implement Caching (if applicable)**: For read operations that benefit from caching, use the `getCachedOrExecute` utility here to wrap the core logic call. Generate a unique cache key based on relevant arguments. + - It returns a standard `{ success: true/false, data/error, fromCache: boolean }` object. - Export the function and add it to the `directFunctions` map. 3. **MCP Tool File**: - Create a new file in `mcp-server/src/tools/` (e.g., `yourCommand.js`). diff --git a/.cursor/rules/utilities.mdc b/.cursor/rules/utilities.mdc index a6982e43..7368be15 100644 --- a/.cursor/rules/utilities.mdc +++ b/.cursor/rules/utilities.mdc @@ -325,6 +325,20 @@ alwaysApply: false - ✅ **DO**: Use this (usually via `handleApiResult` or `executeMCPToolAction`) to format error responses for MCP. - Wraps the `errorMessage` in the standard FastMCP error structure, including `isError: true`. +- **`getCachedOrExecute({ cacheKey, actionFn, log })`**: + - ✅ **DO**: Use this utility *inside direct function wrappers* (like `listTasksDirect` in `task-master-core.js`) to implement caching for MCP operations. + - Checks the `ContextManager` cache using `cacheKey`. + - If a hit occurs, returns the cached result directly. + - If a miss occurs, it executes the provided `actionFn` (which should be an async function returning `{ success, data/error }`). + - If `actionFn` succeeds, its result is stored in the cache under `cacheKey`. + - Returns the result (either cached or fresh) wrapped in the standard structure `{ success, data/error, fromCache: boolean }`. + +- **`executeMCPToolAction({ actionFn, args, log, actionName, processResult })`**: + - Update: While this function *can* technically coordinate caching if provided a `cacheKeyGenerator`, the current preferred pattern involves implementing caching *within* the `actionFn` (the direct wrapper) using `getCachedOrExecute`. `executeMCPToolAction` primarily orchestrates the call to `actionFn` and handles processing its result (including the `fromCache` flag) via `handleApiResult`. + +- **`handleApiResult(result, log, errorPrefix, processFunction)`**: + - Update: Now expects the `result` object to potentially contain a `fromCache` boolean flag. If present, this flag is included in the final response payload generated by `createContentResponse` (e.g., `{ fromCache: true, data: ... }`). + ## Export Organization - **Grouping Related Functions**: