Skip to main content
Glama

mcp-github-project-manager

ParsePRDTool.ts16.4 kB
import { z } from 'zod'; import { ToolDefinition, ToolSchema } from '../ToolValidator'; import { TaskGenerationService } from '../../../services/TaskGenerationService'; import { PRDGenerationService } from '../../../services/PRDGenerationService'; import { RequirementsTraceabilityService } from '../../../services/RequirementsTraceabilityService'; import { MCPResponse } from '../../../domain/mcp-types'; import { ToolResultFormatter } from '../ToolResultFormatter'; // Schema for parse_prd tool const parsePRDSchema = z.object({ prdContent: z.string().min(100).describe('The PRD content to parse (markdown, text, or JSON)'), maxTasks: z.number().min(1).max(100).default(30).describe('Maximum number of tasks to generate'), includeSubtasks: z.boolean().default(true).describe('Whether to break down complex tasks into subtasks'), autoEstimate: z.boolean().default(true).describe('Whether to automatically estimate effort and complexity'), autoPrioritize: z.boolean().default(true).describe('Whether to automatically prioritize tasks'), autoDetectDependencies: z.boolean().default(true).describe('Whether to automatically detect task dependencies'), targetComplexity: z.number().min(1).max(10).optional().describe('Target maximum complexity for individual tasks'), teamSkills: z.array(z.string()).optional().describe('Team skills to consider for task assignment'), projectType: z.string().optional().describe('Type of project (web-app, mobile-app, api, etc.)'), createLifecycle: z.boolean().default(true).describe('Whether to create lifecycle tracking for tasks'), createTraceabilityMatrix: z.boolean().default(true).describe('Whether to create comprehensive requirements traceability matrix'), includeUseCases: z.boolean().default(true).describe('Whether to generate use cases from features'), projectId: z.string().optional().describe('Project ID for traceability matrix'), enhancedGeneration: z.boolean().default(true).describe('Whether to use enhanced task generation with context'), contextLevel: z.enum(['minimal', 'standard', 'full']).default('standard').describe('Level of contextual information to include'), includeBusinessContext: z.boolean().default(false).describe('Whether to include AI-generated business context (requires AI)'), includeTechnicalContext: z.boolean().default(false).describe('Whether to include AI-generated technical context (requires AI)'), includeImplementationGuidance: z.boolean().default(false).describe('Whether to include AI-generated implementation guidance (requires AI)') }); export type ParsePRDArgs = z.infer<typeof parsePRDSchema>; /** * Implementation function for parse_prd tool (similar to claude-task-master) */ async function executeParsePRD(args: ParsePRDArgs): Promise<MCPResponse> { const taskService = new TaskGenerationService(); const prdService = new PRDGenerationService(); const traceabilityService = new RequirementsTraceabilityService(); try { // First, try to extract features from the PRD const features = await prdService.extractFeaturesFromPRD(args.prdContent); // Generate tasks from the PRD content using enhanced generation if enabled const tasks = args.enhancedGeneration ? await taskService.generateEnhancedTasksFromPRD({ prd: args.prdContent, maxTasks: args.maxTasks, includeSubtasks: args.includeSubtasks, autoEstimate: args.autoEstimate, autoPrioritize: args.autoPrioritize, projectId: args.projectId, enhancedConfig: { enableEnhancedGeneration: args.enhancedGeneration, createTraceabilityMatrix: args.createTraceabilityMatrix, generateUseCases: args.includeUseCases, createLifecycleTracking: args.createLifecycle, contextLevel: args.contextLevel, includeBusinessContext: args.includeBusinessContext, includeTechnicalContext: args.includeTechnicalContext, includeImplementationGuidance: args.includeImplementationGuidance, enforceTraceability: args.createTraceabilityMatrix, requireBusinessJustification: args.includeBusinessContext, trackRequirementCoverage: args.createTraceabilityMatrix } }) : await taskService.generateTasksFromPRD({ prd: args.prdContent, maxTasks: args.maxTasks, includeSubtasks: args.includeSubtasks, autoEstimate: args.autoEstimate, autoPrioritize: args.autoPrioritize }); // Filter tasks by target complexity if specified let filteredTasks = tasks; if (args.targetComplexity) { filteredTasks = tasks.filter(task => task.complexity <= args.targetComplexity!); } // Create traceability matrix if requested let traceabilityMatrix; if (args.createTraceabilityMatrix) { // Create mock PRD for traceability const mockPRD = { id: args.projectId || `prd-${Date.now()}`, title: 'Parsed PRD', overview: args.prdContent.substring(0, 500), objectives: ['Deliver high-quality software solution'], successMetrics: ['User satisfaction > 90%'], features, author: 'system', createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), aiGenerated: true, aiMetadata: { generatedBy: 'parse-prd-tool', generatedAt: new Date().toISOString(), prompt: 'Parse PRD content', confidence: 0.8, version: '1.0.0' } }; traceabilityMatrix = traceabilityService.createTraceabilityMatrix( args.projectId || 'parsed-project', mockPRD as any, features, filteredTasks ); } // Calculate project metrics const metrics = calculateProjectMetrics(filteredTasks, features); // Generate task recommendations const recommendations = await generateTaskRecommendations(filteredTasks, args); // Format response with traceability const summary = formatPRDParsingResult( filteredTasks, features, metrics, recommendations, args, traceabilityMatrix ); return ToolResultFormatter.formatSuccess('parse_prd', { summary, tasks: filteredTasks, features, metrics, recommendations, traceabilityMatrix, totalTasks: filteredTasks.length, totalFeatures: features.length, totalBusinessRequirements: traceabilityMatrix?.businessRequirements.length || 0, totalUseCases: traceabilityMatrix?.useCases.length || 0 }); } catch (error) { process.stderr.write(`Error in parse_prd tool: ${error}\n`); return ToolResultFormatter.formatSuccess('parse_prd', { error: `Failed to parse PRD: ${error instanceof Error ? error.message : 'Unknown error'}`, success: false }); } } /** * Calculate project metrics from tasks and features */ function calculateProjectMetrics(tasks: any[], features: any[]) { const totalEffort = tasks.reduce((sum, task) => sum + task.estimatedHours, 0); const avgComplexity = tasks.reduce((sum, task) => sum + task.complexity, 0) / tasks.length; const tasksByPriority = tasks.reduce((acc, task) => { acc[task.priority] = (acc[task.priority] || 0) + 1; return acc; }, {}); const tasksByComplexity = tasks.reduce((acc, task) => { const level = task.complexity <= 3 ? 'low' : task.complexity <= 7 ? 'medium' : 'high'; acc[level] = (acc[level] || 0) + 1; return acc; }, {}); const featuresByPriority = features.reduce((acc, feature) => { acc[feature.priority] = (acc[feature.priority] || 0) + 1; return acc; }, {}); return { totalEffort, avgComplexity: Math.round(avgComplexity * 10) / 10, estimatedDuration: Math.ceil(totalEffort / 40), // Assuming 40 hours per week tasksByPriority, tasksByComplexity, featuresByPriority, riskLevel: avgComplexity > 7 ? 'high' : avgComplexity > 5 ? 'medium' : 'low' }; } /** * Generate task recommendations */ async function generateTaskRecommendations(tasks: any[], args: ParsePRDArgs) { // Get high-priority tasks const highPriorityTasks = tasks .filter(task => task.priority === 'critical' || task.priority === 'high') .slice(0, 5); // Get setup/infrastructure tasks const setupTasks = tasks .filter(task => task.title.toLowerCase().includes('setup') || task.title.toLowerCase().includes('infrastructure') || task.title.toLowerCase().includes('configuration') ) .slice(0, 3); // Get complex tasks that might need breakdown const complexTasks = tasks .filter(task => task.complexity >= 8) .slice(0, 3); return { startWithTasks: setupTasks.length > 0 ? setupTasks : highPriorityTasks.slice(0, 3), highPriorityTasks, complexTasksNeedingBreakdown: complexTasks, recommendedFirstSprint: tasks .filter(task => task.priority === 'critical' || task.priority === 'high') .filter(task => task.complexity <= 6) .slice(0, 8) }; } /** * Format PRD parsing result summary */ function formatPRDParsingResult( tasks: any[], features: any[], metrics: any, recommendations: any, args: ParsePRDArgs, traceabilityMatrix?: any ): string { const sections = [ '# PRD Parsing Complete', '', '## Summary', `**Total Tasks Generated:** ${tasks.length}`, `**Features Identified:** ${features.length}`, `**Total Estimated Effort:** ${metrics.totalEffort} hours`, `**Estimated Duration:** ${metrics.estimatedDuration} weeks`, `**Average Complexity:** ${metrics.avgComplexity}/10`, `**Risk Level:** ${metrics.riskLevel}`, '' ]; // Add traceability information if available if (traceabilityMatrix) { sections.push( '## Requirements Traceability', `**Business Requirements:** ${traceabilityMatrix.businessRequirements.length}`, `**Use Cases Generated:** ${traceabilityMatrix.useCases.length}`, `**Traceability Links:** ${traceabilityMatrix.traceabilityLinks.length}`, `**Tasks with Traceability:** ${traceabilityMatrix.coverage.tasksWithTraceability}/${tasks.length} (${Math.round((traceabilityMatrix.coverage.tasksWithTraceability/tasks.length)*100)}%)`, '' ); // Show coverage issues if (traceabilityMatrix.coverage.orphanedTasks.length > 0) { sections.push( `**⚠️ Orphaned Tasks:** ${traceabilityMatrix.coverage.orphanedTasks.length} tasks have no requirements traceability`, '' ); } if (traceabilityMatrix.coverage.unimplementedRequirements.length > 0) { sections.push( `**⚠️ Unimplemented Requirements:** ${traceabilityMatrix.coverage.unimplementedRequirements.length} requirements have no implementing tasks`, '' ); } } // Task breakdown sections.push( '## Task Breakdown', '', '**By Priority:**', ...Object.entries(metrics.tasksByPriority).map(([priority, count]) => `- ${priority}: ${count} task${(count as number) > 1 ? 's' : ''}` ), '', '**By Complexity:**', ...Object.entries(metrics.tasksByComplexity).map(([level, count]) => `- ${level}: ${count} task${(count as number) > 1 ? 's' : ''}` ), '' ); // Feature breakdown if (features.length > 0) { sections.push( '## Features Identified', `**Total Features:** ${features.length}`, '', '**By Priority:**', ...Object.entries(metrics.featuresByPriority).map(([priority, count]) => `- ${priority}: ${count} feature${(count as number) > 1 ? 's' : ''}` ), '', '**Top Features:**', ...features.slice(0, 5).map((feature: any) => `- ${feature.title} (${feature.priority}, complexity: ${feature.estimatedComplexity}/10)` ), '' ); } // Recommendations sections.push('## AI Recommendations'); if (recommendations.startWithTasks.length > 0) { sections.push( '', '**Start With These Tasks:**', ...recommendations.startWithTasks.map((task: any) => `- ${task.title} (${task.priority}, ${task.estimatedHours}h)` ), '' ); } if (recommendations.complexTasksNeedingBreakdown.length > 0) { sections.push( '**Complex Tasks Needing Breakdown:**', ...recommendations.complexTasksNeedingBreakdown.map((task: any) => `- ${task.title} (complexity: ${task.complexity}/10)` ), '' ); } if (recommendations.recommendedFirstSprint.length > 0) { const sprintEffort = recommendations.recommendedFirstSprint.reduce((sum: number, task: any) => sum + task.estimatedHours, 0); sections.push( '**Recommended First Sprint:**', `- ${recommendations.recommendedFirstSprint.length} tasks`, `- ${sprintEffort} hours total effort`, `- Focus on high-priority, manageable complexity tasks`, '' ); } // Project insights sections.push( '## Project Insights', '' ); if (metrics.riskLevel === 'high') { sections.push( '⚠️ **High Risk Project**', '- Many complex tasks detected', '- Consider breaking down complex tasks further', '- Plan for additional time and resources', '' ); } else if (metrics.riskLevel === 'medium') { sections.push( '⚡ **Medium Risk Project**', '- Balanced complexity distribution', '- Some complex tasks may need attention', '- Good candidate for agile development', '' ); } else { sections.push( '✅ **Low Risk Project**', '- Most tasks are manageable complexity', '- Good for rapid development', '- Suitable for smaller teams', '' ); } // Configuration used sections.push( '## Configuration Used', `- Max Tasks: ${args.maxTasks}`, `- Include Subtasks: ${args.includeSubtasks}`, `- Auto Estimate: ${args.autoEstimate}`, `- Auto Prioritize: ${args.autoPrioritize}`, `- Auto Dependencies: ${args.autoDetectDependencies}`, args.targetComplexity ? `- Target Complexity: ≤${args.targetComplexity}` : '', '' ); // Next steps sections.push( '## Next Steps', '1. Review the generated tasks and adjust priorities if needed', '2. Use `expand_task` to break down complex tasks further', '3. Use `get_next_task` to get recommendations for what to work on first', '4. Create a GitHub project and add these tasks using `add_project_item`', '5. Use `update_task_lifecycle` to track progress as you work', '' ); // Related commands sections.push( '## Related Commands', '- `expand_task` - Break down complex tasks into subtasks', '- `get_next_task` - Get AI recommendations for next task to work on', '- `analyze_task_complexity` - Get detailed complexity analysis', '- `add_feature` - Add new features to the project', '- `create_project` - Create GitHub project to track these tasks' ); return sections.join('\n'); } // Tool definition export const parsePRDTool: ToolDefinition<ParsePRDArgs> = { name: "parse_prd", description: "Parse a Product Requirements Document (PRD) and generate a comprehensive list of actionable development tasks with AI-powered analysis, similar to claude-task-master functionality", schema: parsePRDSchema as unknown as ToolSchema<ParsePRDArgs>, examples: [ { name: "Parse PRD for task generation", description: "Parse a PRD document and generate development tasks", args: { prdContent: `# Task Management App PRD\n\n## Overview\nBuild a modern task management application...\n\n## Features\n- User authentication\n- Task creation and management\n- Team collaboration\n- Real-time updates`, maxTasks: 25, includeSubtasks: true, autoEstimate: true, autoPrioritize: true, autoDetectDependencies: true, projectType: "web-app", createLifecycle: true, createTraceabilityMatrix: true, includeUseCases: true, projectId: "task-management-app", enhancedGeneration: true, contextLevel: "standard" as const, includeBusinessContext: false, includeTechnicalContext: false, includeImplementationGuidance: false } } ] }; // Export the execution function for the tool registry export { executeParsePRD };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kunwarVivek/mcp-github-project-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server