docs: document MCP server naming conventions and implement set-status
- Update architecture.mdc with file/function naming standards for MCP server components - Update mcp.mdc with detailed naming conventions section - Update task 23 to include naming convention details - Update changeset to capture documentation changes - Rename MCP tool files to follow kebab-case convention - Implement set-task-status MCP command
This commit is contained in:
@@ -7,3 +7,4 @@
|
|||||||
- Implement update-subtask MCP command for appending information to specific subtasks
|
- Implement update-subtask MCP command for appending information to specific subtasks
|
||||||
- Implement generate MCP command for creating individual task files from tasks.json
|
- Implement generate MCP command for creating individual task files from tasks.json
|
||||||
- Implement set-status MCP command for updating task status
|
- Implement set-status MCP command for updating task status
|
||||||
|
- 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)
|
||||||
|
|||||||
@@ -119,6 +119,11 @@ alwaysApply: false
|
|||||||
- `mcp-server/src/core/direct-functions/`: Directory containing individual files for each direct function wrapper (`*Direct`). These files contain the primary logic, including path resolution, core function calls, and caching.
|
- `mcp-server/src/core/direct-functions/`: Directory containing individual files for each direct function wrapper (`*Direct`). These files contain the primary logic, including path resolution, core function calls, and caching.
|
||||||
- [`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 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 utility functions.
|
||||||
- `mcp-server/src/tools/utils.js`: Provides utilities like `handleApiResult`, `processMCPResponseData`, and `getCachedOrExecute`.
|
- `mcp-server/src/tools/utils.js`: Provides utilities like `handleApiResult`, `processMCPResponseData`, and `getCachedOrExecute`.
|
||||||
|
- **Naming Conventions**:
|
||||||
|
- **Files** use **kebab-case**: `list-tasks.js`, `set-task-status.js`, `parse-prd.js`
|
||||||
|
- **Direct Functions** use **camelCase** with `Direct` suffix: `listTasksDirect`, `setTaskStatusDirect`, `parsePRDDirect`
|
||||||
|
- **Tool Registration Functions** use **camelCase** with `Tool` suffix: `registerListTasksTool`, `registerSetTaskStatusTool`
|
||||||
|
- **MCP Tool Names** use **snake_case**: `list_tasks`, `set_task_status`, `parse_prd_document`
|
||||||
|
|
||||||
- **Data Flow and Module Dependencies**:
|
- **Data Flow and Module Dependencies**:
|
||||||
|
|
||||||
|
|||||||
@@ -46,50 +46,38 @@ The MCP server acts as a bridge between external tools (like Cursor) and the cor
|
|||||||
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):
|
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/`.
|
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).
|
2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:
|
||||||
- Inside the wrapper:
|
- Create a new file (e.g., `your-command.js`) in the `direct-functions` directory using **kebab-case** for file naming.
|
||||||
- Import necessary core functions and utilities (`findTasksJsonPath`, `getCachedOrExecute` if caching).
|
- 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`).
|
- Parse `args` and determine necessary inputs (e.g., `tasksPath` via `findTasksJsonPath`).
|
||||||
- **If Caching**:
|
- **If Caching**:
|
||||||
- Generate a unique `cacheKey` based on arguments defining the operation.
|
- 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 }`.
|
- Define an `async` function `coreActionFn` containing the call to the core logic.
|
||||||
- Call `const result = await getCachedOrExecute({ cacheKey, actionFn: coreActionFn, log });`.
|
- Call `const result = await getCachedOrExecute({ cacheKey, actionFn: coreActionFn, log });`.
|
||||||
- `return result;` (which includes the `fromCache` flag).
|
|
||||||
- **If Not Caching**:
|
- **If Not Caching**:
|
||||||
- Directly call the core logic function within a try/catch block.
|
- Directly call the core logic function within a try/catch block.
|
||||||
- Format the return as `{ success: true/false, data/error, fromCache: false }`.
|
- Format the return as `{ success: true/false, data/error, fromCache: boolean }`.
|
||||||
- Export the wrapper function and add it to the `directFunctions` map.
|
- Export the wrapper function.
|
||||||
3. **Create MCP Tool (`mcp-server/src/tools/`)**:
|
|
||||||
- Create a new file (e.g., `yourCommand.js`).
|
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 `z` for schema definition.
|
||||||
- Import `handleApiResult` from [`./utils.js`](mdc:mcp-server/src/tools/utils.js).
|
- Import `handleApiResult` from `./utils.js`.
|
||||||
- Import the `yourCommandDirect` wrapper function from `../core/task-master-core.js`.
|
- Import the `yourCommandDirect` wrapper function from `../core/task-master-core.js`.
|
||||||
- Implement `registerYourCommandTool(server)`:
|
- Implement `registerYourCommandTool(server)` using **camelCase** with `Tool` suffix.
|
||||||
- Call `server.addTool`.
|
- Define the tool `name` using **snake_case** (e.g., `your_command`).
|
||||||
- Define `name`, `description`, and `parameters` using `zod` (include optional `projectRoot`, `file` if needed).
|
|
||||||
- Define the `async execute(args, log)` function:
|
5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.
|
||||||
```javascript
|
|
||||||
async execute(args, log) {
|
6. **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`.
|
||||||
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
|
## Handling Responses
|
||||||
|
|
||||||
@@ -185,3 +173,34 @@ Follow these steps to add MCP support for an existing Task Master command (see [
|
|||||||
- Centralized error handling
|
- Centralized error handling
|
||||||
- Performance optimization through caching (for read operations)
|
- Performance optimization through caching (for read operations)
|
||||||
- Standardized response formatting
|
- 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
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* tools/addTask.js
|
|
||||||
* Tool to add a new task using AI
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { z } from "zod";
|
|
||||||
import {
|
|
||||||
executeTaskMasterCommand,
|
|
||||||
createContentResponse,
|
|
||||||
createErrorResponse,
|
|
||||||
} from "./utils.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the addTask tool with the MCP server
|
|
||||||
* @param {FastMCP} server - FastMCP server instance
|
|
||||||
*/
|
|
||||||
export function registerAddTaskTool(server) {
|
|
||||||
server.addTool({
|
|
||||||
name: "addTask",
|
|
||||||
description: "Add a new task using AI",
|
|
||||||
parameters: z.object({
|
|
||||||
prompt: z.string().describe("Description of the task to add"),
|
|
||||||
dependencies: z
|
|
||||||
.string()
|
|
||||||
.optional()
|
|
||||||
.describe("Comma-separated list of task IDs this task depends on"),
|
|
||||||
priority: z
|
|
||||||
.string()
|
|
||||||
.optional()
|
|
||||||
.describe("Task priority (high, medium, low)"),
|
|
||||||
file: z.string().optional().describe("Path to the tasks file"),
|
|
||||||
projectRoot: z
|
|
||||||
.string()
|
|
||||||
.describe(
|
|
||||||
"Root directory of the project (default: current working directory)"
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
execute: async (args, { log }) => {
|
|
||||||
try {
|
|
||||||
log.info(`Adding new task: ${args.prompt}`);
|
|
||||||
|
|
||||||
const cmdArgs = [`--prompt="${args.prompt}"`];
|
|
||||||
if (args.dependencies)
|
|
||||||
cmdArgs.push(`--dependencies=${args.dependencies}`);
|
|
||||||
if (args.priority) cmdArgs.push(`--priority=${args.priority}`);
|
|
||||||
if (args.file) cmdArgs.push(`--file=${args.file}`);
|
|
||||||
|
|
||||||
const result = executeTaskMasterCommand(
|
|
||||||
"add-task",
|
|
||||||
log,
|
|
||||||
cmdArgs,
|
|
||||||
projectRoot
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!result.success) {
|
|
||||||
throw new Error(result.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createContentResponse(result.stdout);
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error adding task: ${error.message}`);
|
|
||||||
return createErrorResponse(`Error adding task: ${error.message}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* tools/expandTask.js
|
|
||||||
* Tool to break down a task into detailed subtasks
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { z } from "zod";
|
|
||||||
import {
|
|
||||||
executeTaskMasterCommand,
|
|
||||||
createContentResponse,
|
|
||||||
createErrorResponse,
|
|
||||||
} from "./utils.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the expandTask tool with the MCP server
|
|
||||||
* @param {Object} server - FastMCP server instance
|
|
||||||
*/
|
|
||||||
export function registerExpandTaskTool(server) {
|
|
||||||
server.addTool({
|
|
||||||
name: "expandTask",
|
|
||||||
description: "Break down a task into detailed subtasks",
|
|
||||||
parameters: z.object({
|
|
||||||
id: z.string().describe("Task ID to expand"),
|
|
||||||
num: z.number().optional().describe("Number of subtasks to generate"),
|
|
||||||
research: z
|
|
||||||
.boolean()
|
|
||||||
.optional()
|
|
||||||
.describe(
|
|
||||||
"Enable Perplexity AI for research-backed subtask generation"
|
|
||||||
),
|
|
||||||
prompt: z
|
|
||||||
.string()
|
|
||||||
.optional()
|
|
||||||
.describe("Additional context to guide subtask generation"),
|
|
||||||
force: z
|
|
||||||
.boolean()
|
|
||||||
.optional()
|
|
||||||
.describe(
|
|
||||||
"Force regeneration of subtasks for tasks that already have them"
|
|
||||||
),
|
|
||||||
file: z.string().optional().describe("Path to the tasks file"),
|
|
||||||
projectRoot: z
|
|
||||||
.string()
|
|
||||||
.describe(
|
|
||||||
"Root directory of the project (default: current working directory)"
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
execute: async (args, { log }) => {
|
|
||||||
try {
|
|
||||||
log.info(`Expanding task ${args.id}`);
|
|
||||||
|
|
||||||
const cmdArgs = [`--id=${args.id}`];
|
|
||||||
if (args.num) cmdArgs.push(`--num=${args.num}`);
|
|
||||||
if (args.research) cmdArgs.push("--research");
|
|
||||||
if (args.prompt) cmdArgs.push(`--prompt="${args.prompt}"`);
|
|
||||||
if (args.force) cmdArgs.push("--force");
|
|
||||||
if (args.file) cmdArgs.push(`--file=${args.file}`);
|
|
||||||
|
|
||||||
const projectRoot = args.projectRoot;
|
|
||||||
|
|
||||||
const result = executeTaskMasterCommand(
|
|
||||||
"expand",
|
|
||||||
log,
|
|
||||||
cmdArgs,
|
|
||||||
projectRoot
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!result.success) {
|
|
||||||
throw new Error(result.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createContentResponse(result.stdout);
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error expanding task: ${error.message}`);
|
|
||||||
return createErrorResponse(`Error expanding task: ${error.message}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -4,13 +4,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import logger from "../logger.js";
|
import logger from "../logger.js";
|
||||||
import { registerListTasksTool } from "./listTasks.js";
|
import { registerListTasksTool } from "./list-tasks.js";
|
||||||
import { registerShowTaskTool } from "./showTask.js";
|
import { registerSetTaskStatusTool } from "./set-task-status.js";
|
||||||
import { registerSetTaskStatusTool } from "./setTaskStatus.js";
|
import { registerParsePRDTool } from "./parse-prd.js";
|
||||||
import { registerExpandTaskTool } from "./expandTask.js";
|
|
||||||
import { registerNextTaskTool } from "./nextTask.js";
|
|
||||||
import { registerAddTaskTool } from "./addTask.js";
|
|
||||||
import { registerParsePRDTool } from "./parsePRD.js";
|
|
||||||
import { registerUpdateTool } from "./update.js";
|
import { registerUpdateTool } from "./update.js";
|
||||||
import { registerUpdateTaskTool } from "./update-task.js";
|
import { registerUpdateTaskTool } from "./update-task.js";
|
||||||
import { registerUpdateSubtaskTool } from "./update-subtask.js";
|
import { registerUpdateSubtaskTool } from "./update-subtask.js";
|
||||||
@@ -22,11 +18,7 @@ import { registerGenerateTool } from "./generate.js";
|
|||||||
*/
|
*/
|
||||||
export function registerTaskMasterTools(server) {
|
export function registerTaskMasterTools(server) {
|
||||||
registerListTasksTool(server);
|
registerListTasksTool(server);
|
||||||
registerShowTaskTool(server);
|
|
||||||
registerSetTaskStatusTool(server);
|
registerSetTaskStatusTool(server);
|
||||||
registerExpandTaskTool(server);
|
|
||||||
registerNextTaskTool(server);
|
|
||||||
registerAddTaskTool(server);
|
|
||||||
registerParsePRDTool(server);
|
registerParsePRDTool(server);
|
||||||
registerUpdateTool(server);
|
registerUpdateTool(server);
|
||||||
registerUpdateTaskTool(server);
|
registerUpdateTaskTool(server);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { listTasksDirect } from "../core/task-master-core.js";
|
|||||||
*/
|
*/
|
||||||
export function registerListTasksTool(server) {
|
export function registerListTasksTool(server) {
|
||||||
server.addTool({
|
server.addTool({
|
||||||
name: "listTasks",
|
name: "list-tasks",
|
||||||
description: "List all tasks from Task Master",
|
description: "List all tasks from Task Master",
|
||||||
parameters: z.object({
|
parameters: z.object({
|
||||||
status: z.string().optional().describe("Filter tasks by status"),
|
status: z.string().optional().describe("Filter tasks by status"),
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* tools/nextTask.js
|
|
||||||
* Tool to show the next task to work on based on dependencies and status
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { z } from "zod";
|
|
||||||
import {
|
|
||||||
executeTaskMasterCommand,
|
|
||||||
createContentResponse,
|
|
||||||
createErrorResponse,
|
|
||||||
} from "./utils.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the nextTask tool with the MCP server
|
|
||||||
* @param {Object} server - FastMCP server instance
|
|
||||||
*/
|
|
||||||
export function registerNextTaskTool(server) {
|
|
||||||
server.addTool({
|
|
||||||
name: "nextTask",
|
|
||||||
description:
|
|
||||||
"Show the next task to work on based on dependencies and status",
|
|
||||||
parameters: z.object({
|
|
||||||
file: z.string().optional().describe("Path to the tasks file"),
|
|
||||||
projectRoot: z
|
|
||||||
.string()
|
|
||||||
.describe(
|
|
||||||
"Root directory of the project (default: current working directory)"
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
execute: async (args, { log }) => {
|
|
||||||
try {
|
|
||||||
log.info(`Finding next task to work on`);
|
|
||||||
|
|
||||||
const cmdArgs = [];
|
|
||||||
if (args.file) cmdArgs.push(`--file=${args.file}`);
|
|
||||||
|
|
||||||
const projectRoot = args.projectRoot;
|
|
||||||
|
|
||||||
const result = executeTaskMasterCommand(
|
|
||||||
"next",
|
|
||||||
log,
|
|
||||||
cmdArgs,
|
|
||||||
projectRoot
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!result.success) {
|
|
||||||
throw new Error(result.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createContentResponse(result.stdout);
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error finding next task: ${error.message}`);
|
|
||||||
return createErrorResponse(`Error finding next task: ${error.message}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@ import { parsePRDDirect } from "../core/task-master-core.js";
|
|||||||
*/
|
*/
|
||||||
export function registerParsePRDTool(server) {
|
export function registerParsePRDTool(server) {
|
||||||
server.addTool({
|
server.addTool({
|
||||||
name: "parsePRD",
|
name: "parse_prd_document",
|
||||||
description: "Parse PRD document and generate tasks",
|
description: "Parse PRD document and generate tasks",
|
||||||
parameters: z.object({
|
parameters: z.object({
|
||||||
input: z.string().describe("Path to the PRD document file"),
|
input: z.string().describe("Path to the PRD document file"),
|
||||||
@@ -16,7 +16,7 @@ import { setTaskStatusDirect } from "../core/task-master-core.js";
|
|||||||
*/
|
*/
|
||||||
export function registerSetTaskStatusTool(server) {
|
export function registerSetTaskStatusTool(server) {
|
||||||
server.addTool({
|
server.addTool({
|
||||||
name: "setTaskStatus",
|
name: "set_task_status",
|
||||||
description: "Set the status of a task",
|
description: "Set the status of a task",
|
||||||
parameters: z.object({
|
parameters: z.object({
|
||||||
id: z
|
id: z
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* tools/showTask.js
|
|
||||||
* Tool to show detailed information about a specific task
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { z } from "zod";
|
|
||||||
import {
|
|
||||||
executeTaskMasterCommand,
|
|
||||||
createErrorResponse,
|
|
||||||
handleApiResult
|
|
||||||
} from "./utils.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the showTask tool with the MCP server
|
|
||||||
* @param {Object} server - FastMCP server instance
|
|
||||||
*/
|
|
||||||
export function registerShowTaskTool(server) {
|
|
||||||
server.addTool({
|
|
||||||
name: "showTask",
|
|
||||||
description: "Show detailed information about a specific task",
|
|
||||||
parameters: z.object({
|
|
||||||
id: z.string().describe("Task ID to show"),
|
|
||||||
file: z.string().optional().describe("Path to the tasks file"),
|
|
||||||
projectRoot: z
|
|
||||||
.string()
|
|
||||||
.optional()
|
|
||||||
.describe(
|
|
||||||
"Root directory of the project (default: current working directory)"
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
execute: async (args, { log }) => {
|
|
||||||
try {
|
|
||||||
log.info(`Showing task details for ID: ${args.id}`);
|
|
||||||
|
|
||||||
// Prepare arguments for CLI command
|
|
||||||
const cmdArgs = [`--id=${args.id}`];
|
|
||||||
if (args.file) cmdArgs.push(`--file=${args.file}`);
|
|
||||||
|
|
||||||
// Execute the command - function now handles project root internally
|
|
||||||
const result = executeTaskMasterCommand(
|
|
||||||
"show",
|
|
||||||
log,
|
|
||||||
cmdArgs,
|
|
||||||
args.projectRoot // Pass raw project root, function will normalize it
|
|
||||||
);
|
|
||||||
|
|
||||||
// Process CLI result into API result format for handleApiResult
|
|
||||||
if (result.success) {
|
|
||||||
try {
|
|
||||||
// Try to parse response as JSON
|
|
||||||
const data = JSON.parse(result.stdout);
|
|
||||||
// Return equivalent of a successful API call with data
|
|
||||||
return handleApiResult({ success: true, data }, log, 'Error showing task');
|
|
||||||
} catch (e) {
|
|
||||||
// If parsing fails, still return success but with raw string data
|
|
||||||
return handleApiResult(
|
|
||||||
{ success: true, data: result.stdout },
|
|
||||||
log,
|
|
||||||
'Error showing task',
|
|
||||||
// Skip data processing for string data
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Return equivalent of a failed API call
|
|
||||||
return handleApiResult(
|
|
||||||
{ success: false, error: { message: result.error } },
|
|
||||||
log,
|
|
||||||
'Error showing task'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error showing task: ${error.message}`);
|
|
||||||
return createErrorResponse(error.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -17,6 +17,7 @@ This task involves completing the Model Context Protocol (MCP) server implementa
|
|||||||
8. Identify and address missing components or functionalities to meet FastMCP best practices, such as robust error handling, monitoring endpoints, and concurrency support.
|
8. Identify and address missing components or functionalities to meet FastMCP best practices, such as robust error handling, monitoring endpoints, and concurrency support.
|
||||||
9. Update documentation to include examples of using the MCP server with FastMCP, detailed setup instructions, and client integration guides.
|
9. Update documentation to include examples of using the MCP server with FastMCP, detailed setup instructions, and client integration guides.
|
||||||
10. Organize direct function implementations in a modular structure within the mcp-server/src/core/direct-functions/ directory for improved maintainability and organization.
|
10. Organize direct function implementations in a modular structure within the mcp-server/src/core/direct-functions/ directory for improved maintainability and organization.
|
||||||
|
11. Follow consistent naming conventions: file names use kebab-case (like-this.js), direct functions use camelCase with Direct suffix (functionNameDirect), tool registration functions use camelCase with Tool suffix (registerToolNameTool), and MCP tool names exposed to clients use snake_case (tool_name).
|
||||||
|
|
||||||
The implementation must ensure compatibility with existing MCP clients and follow RESTful API design principles, while supporting concurrent requests and maintaining robust error handling.
|
The implementation must ensure compatibility with existing MCP clients and follow RESTful API design principles, while supporting concurrent requests and maintaining robust error handling.
|
||||||
|
|
||||||
@@ -529,7 +530,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerShowTaskTool(server) with server.addTool
|
- Implement registerShowTaskTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'show_task'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -562,7 +563,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerNextTaskTool(server) with server.addTool
|
- Implement registerNextTaskTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'next_task'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -595,7 +596,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerExpandTaskTool(server) with server.addTool
|
- Implement registerExpandTaskTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'expand_task'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -628,7 +629,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerAddTaskTool(server) with server.addTool
|
- Implement registerAddTaskTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'add_task'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -661,7 +662,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerAddSubtaskTool(server) with server.addTool
|
- Implement registerAddSubtaskTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'add_subtask'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -694,7 +695,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerRemoveSubtaskTool(server) with server.addTool
|
- Implement registerRemoveSubtaskTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'remove_subtask'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -727,7 +728,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerAnalyzeTool(server) with server.addTool
|
- Implement registerAnalyzeTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'analyze'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -760,7 +761,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerClearSubtasksTool(server) with server.addTool
|
- Implement registerClearSubtasksTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'clear_subtasks'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -793,7 +794,7 @@ Following MCP implementation standards:
|
|||||||
- Implement registerExpandAllTool(server) with server.addTool
|
- Implement registerExpandAllTool(server) with server.addTool
|
||||||
- Use executeMCPToolAction in execute method
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
4. Register in tools/index.js
|
4. Register in tools/index.js with tool name 'expand_all'
|
||||||
|
|
||||||
5. Add to .cursor/mcp.json with appropriate schema
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
@@ -827,3 +828,17 @@ Following MCP implementation standards:
|
|||||||
7. Ensure all MCP tools reference the functions through task-master-core.js
|
7. Ensure all MCP tools reference the functions through task-master-core.js
|
||||||
8. Verify backward compatibility with existing code
|
8. Verify backward compatibility with existing code
|
||||||
|
|
||||||
|
## 33. Implement Naming Convention Standards [pending]
|
||||||
|
### Dependencies: None
|
||||||
|
### Description: Update all MCP server components to follow the standardized naming conventions for files, functions, and tools.
|
||||||
|
### Details:
|
||||||
|
1. Audit all existing MCP server files and update file names to use kebab-case (like-this.js)
|
||||||
|
2. Refactor direct function names to use camelCase with Direct suffix (functionNameDirect)
|
||||||
|
3. Update tool registration functions to use camelCase with Tool suffix (registerToolNameTool)
|
||||||
|
4. Ensure all MCP tool names exposed to clients use snake_case (tool_name)
|
||||||
|
5. Create a naming convention documentation file for future reference
|
||||||
|
6. Update imports/exports in all files to reflect the new naming conventions
|
||||||
|
7. Verify that all tools are properly registered with the correct naming pattern
|
||||||
|
8. Update tests to reflect the new naming conventions
|
||||||
|
9. Create a linting rule to enforce naming conventions in future development
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user