chore: task management, adjust readmes, adjust cursor rules, add mcp_integration.md to docs
This commit is contained in:
269
docs/MCP_INTEGRATION.md
Normal file
269
docs/MCP_INTEGRATION.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# Task Master MCP Integration
|
||||
|
||||
This document outlines how Task Master CLI functionality is integrated with MCP (Master Control Program) architecture to provide both CLI and programmatic API access to features.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The MCP integration uses a layered approach:
|
||||
|
||||
1. **Core Functions** - In `scripts/modules/` contain the main business logic
|
||||
2. **Source Parameter** - Core functions check the `source` parameter to determine behavior
|
||||
3. **Task Master Core** - In `mcp-server/src/core/task-master-core.js` provides direct function imports
|
||||
4. **MCP Tools** - In `mcp-server/src/tools/` register the functions with the MCP server
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ CLI User │ │ MCP User │
|
||||
└────────┬────────┘ └────────┬────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌────────────────┐ ┌────────────────────┐
|
||||
│ commands.js │ │ MCP Tool API │
|
||||
└────────┬───────┘ └──────────┬─────────┘
|
||||
│ │
|
||||
│ │
|
||||
▼ ▼
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ Core Modules (task-manager.js, etc.) │
|
||||
│ │
|
||||
└───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Core Function Pattern
|
||||
|
||||
Core functions should follow this pattern to support both CLI and MCP use:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* Example function with source parameter support
|
||||
* @param {Object} options - Additional options including source
|
||||
* @returns {Object|undefined} - Returns data when source is 'mcp'
|
||||
*/
|
||||
function exampleFunction(param1, param2, options = {}) {
|
||||
try {
|
||||
// Skip UI for MCP
|
||||
if (options.source !== 'mcp') {
|
||||
displayBanner();
|
||||
console.log(chalk.blue('Processing operation...'));
|
||||
}
|
||||
|
||||
// Do the core business logic
|
||||
const result = doSomething(param1, param2);
|
||||
|
||||
// For MCP, return structured data
|
||||
if (options.source === 'mcp') {
|
||||
return {
|
||||
success: true,
|
||||
data: result
|
||||
};
|
||||
}
|
||||
|
||||
// For CLI, display output
|
||||
console.log(chalk.green('Operation completed successfully!'));
|
||||
} catch (error) {
|
||||
// Handle errors based on source
|
||||
if (options.source === 'mcp') {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
|
||||
// CLI error handling
|
||||
console.error(chalk.red(`Error: ${error.message}`));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Source-Adapter Utilities
|
||||
|
||||
For convenience, you can use the source adapter helpers in `scripts/modules/source-adapter.js`:
|
||||
|
||||
```javascript
|
||||
import { adaptForMcp, sourceSplitFunction } from './source-adapter.js';
|
||||
|
||||
// Simple adaptation - just adds source parameter support
|
||||
export const simpleFunction = adaptForMcp(originalFunction);
|
||||
|
||||
// Split implementation - completely different code paths for CLI vs MCP
|
||||
export const complexFunction = sourceSplitFunction(
|
||||
// CLI version with UI
|
||||
function(param1, param2) {
|
||||
displayBanner();
|
||||
console.log(`Processing ${param1}...`);
|
||||
// ... CLI implementation
|
||||
},
|
||||
// MCP version with structured return
|
||||
function(param1, param2, options = {}) {
|
||||
// ... MCP implementation
|
||||
return { success: true, data };
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## Adding New Features
|
||||
|
||||
When adding new features, follow these steps to ensure CLI and MCP compatibility:
|
||||
|
||||
1. **Implement Core Logic** in the appropriate module file
|
||||
2. **Add Source Parameter Support** using the pattern above
|
||||
3. **Add to task-master-core.js** to make it available for direct import
|
||||
4. **Update Command Map** in `mcp-server/src/tools/utils.js`
|
||||
5. **Create Tool Implementation** in `mcp-server/src/tools/`
|
||||
6. **Register the Tool** in `mcp-server/src/tools/index.js`
|
||||
|
||||
### Core Function Implementation
|
||||
|
||||
```javascript
|
||||
// In scripts/modules/task-manager.js
|
||||
export async function newFeature(param1, param2, options = {}) {
|
||||
try {
|
||||
// Source-specific UI
|
||||
if (options.source !== 'mcp') {
|
||||
displayBanner();
|
||||
console.log(chalk.blue('Running new feature...'));
|
||||
}
|
||||
|
||||
// Shared core logic
|
||||
const result = processFeature(param1, param2);
|
||||
|
||||
// Source-specific return handling
|
||||
if (options.source === 'mcp') {
|
||||
return {
|
||||
success: true,
|
||||
data: result
|
||||
};
|
||||
}
|
||||
|
||||
// CLI output
|
||||
console.log(chalk.green('Feature completed successfully!'));
|
||||
displayOutput(result);
|
||||
} catch (error) {
|
||||
// Error handling based on source
|
||||
if (options.source === 'mcp') {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
|
||||
console.error(chalk.red(`Error: ${error.message}`));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Task Master Core Update
|
||||
|
||||
```javascript
|
||||
// In mcp-server/src/core/task-master-core.js
|
||||
import { newFeature } from '../../../scripts/modules/task-manager.js';
|
||||
|
||||
// Add to exports
|
||||
export default {
|
||||
// ... existing functions
|
||||
|
||||
async newFeature(args = {}, options = {}) {
|
||||
const { param1, param2 } = args;
|
||||
return executeFunction(newFeature, [param1, param2], options);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Command Map Update
|
||||
|
||||
```javascript
|
||||
// In mcp-server/src/tools/utils.js
|
||||
const commandMap = {
|
||||
// ... existing mappings
|
||||
'new-feature': 'newFeature'
|
||||
};
|
||||
```
|
||||
|
||||
### Tool Implementation
|
||||
|
||||
```javascript
|
||||
// In mcp-server/src/tools/newFeature.js
|
||||
import { z } from "zod";
|
||||
import {
|
||||
executeTaskMasterCommand,
|
||||
createContentResponse,
|
||||
createErrorResponse,
|
||||
} from "./utils.js";
|
||||
|
||||
export function registerNewFeatureTool(server) {
|
||||
server.addTool({
|
||||
name: "newFeature",
|
||||
description: "Run the new feature",
|
||||
parameters: z.object({
|
||||
param1: z.string().describe("First parameter"),
|
||||
param2: z.number().optional().describe("Second parameter"),
|
||||
file: z.string().optional().describe("Path to the tasks file"),
|
||||
projectRoot: z.string().describe("Root directory of the project")
|
||||
}),
|
||||
execute: async (args, { log }) => {
|
||||
try {
|
||||
log.info(`Running new feature with args: ${JSON.stringify(args)}`);
|
||||
|
||||
const cmdArgs = [];
|
||||
if (args.param1) cmdArgs.push(`--param1=${args.param1}`);
|
||||
if (args.param2) cmdArgs.push(`--param2=${args.param2}`);
|
||||
if (args.file) cmdArgs.push(`--file=${args.file}`);
|
||||
|
||||
const projectRoot = args.projectRoot;
|
||||
|
||||
// Execute the command
|
||||
const result = await executeTaskMasterCommand(
|
||||
"new-feature",
|
||||
log,
|
||||
cmdArgs,
|
||||
projectRoot
|
||||
);
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error(result.error);
|
||||
}
|
||||
|
||||
return createContentResponse(result.stdout);
|
||||
} catch (error) {
|
||||
log.error(`Error in new feature: ${error.message}`);
|
||||
return createErrorResponse(`Error in new feature: ${error.message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Tool Registration
|
||||
|
||||
```javascript
|
||||
// In mcp-server/src/tools/index.js
|
||||
import { registerNewFeatureTool } from "./newFeature.js";
|
||||
|
||||
export function registerTaskMasterTools(server) {
|
||||
// ... existing registrations
|
||||
registerNewFeatureTool(server);
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Always test your MCP-compatible features with both CLI and MCP interfaces:
|
||||
|
||||
```javascript
|
||||
// Test CLI usage
|
||||
node scripts/dev.js new-feature --param1=test --param2=123
|
||||
|
||||
// Test MCP usage
|
||||
node mcp-server/tests/test-command.js newFeature
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Keep Core Logic DRY** - Share as much logic as possible between CLI and MCP
|
||||
2. **Structured Data for MCP** - Return clean JSON objects from MCP source functions
|
||||
3. **Consistent Error Handling** - Standardize error formats for both interfaces
|
||||
4. **Documentation** - Update MCP tool documentation when adding new features
|
||||
5. **Testing** - Test both CLI and MCP interfaces for any new or modified feature
|
||||
Reference in New Issue
Block a user