7.8 KiB
7.8 KiB
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:
- Core Functions - In
scripts/modules/contain the main business logic - Source Parameter - Core functions check the
sourceparameter to determine behavior - Task Master Core - In
mcp-server/src/core/task-master-core.jsprovides direct function imports - 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:
/**
* 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:
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:
- Implement Core Logic in the appropriate module file
- Add Source Parameter Support using the pattern above
- Add to task-master-core.js to make it available for direct import
- Update Command Map in
mcp-server/src/tools/utils.js - Create Tool Implementation in
mcp-server/src/tools/ - Register the Tool in
mcp-server/src/tools/index.js
Core Function Implementation
// 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
// 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
// In mcp-server/src/tools/utils.js
const commandMap = {
// ... existing mappings
'new-feature': 'newFeature'
};
Tool Implementation
// 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
// 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:
// 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
- Keep Core Logic DRY - Share as much logic as possible between CLI and MCP
- Structured Data for MCP - Return clean JSON objects from MCP source functions
- Consistent Error Handling - Standardize error formats for both interfaces
- Documentation - Update MCP tool documentation when adding new features
- Testing - Test both CLI and MCP interfaces for any new or modified feature