100 lines
8.5 KiB
Plaintext
100 lines
8.5 KiB
Plaintext
---
|
|
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": { ... } }`).
|