prompt_to_project
Convert natural language project descriptions into structured project entities. Analyze mode generates requirements templates; create mode executes agent-provided plans.
Instructions
Convert a natural language project description into structured project entities. In analyze mode, returns a template for the AI agent to fill. In create mode, executes the agent-provided plan.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prompt | Yes | ||
| execution_mode | Yes | ||
| project_plan | No |
Implementation Reference
- src/tools/prompt-to-project.ts:160-347 (handler)The core handler function for the 'prompt_to_project' tool. It validates input using Zod schema, supports 'analyze' mode (returns structured template and guidance for AI agent) and 'create' mode (executes the plan by creating projects, initiatives, tasks, and documents via dedicated handlers).handler: async (args: unknown) => { try { const validatedArgs = PromptToProjectArgsSchema.parse(args); if (validatedArgs.execution_mode === 'analyze') { logger.info('Analyzing project prompt for agent processing', { prompt: validatedArgs.prompt }); const template = generateProjectTemplate(validatedArgs.prompt); const guidance = generateAnalysisGuidance(validatedArgs.prompt); const requirements = extractKeyRequirements(validatedArgs.prompt); return { content: [ { type: 'text' as const, text: JSON.stringify({ mode: 'analyze', guidance, template, requirements, original_prompt: validatedArgs.prompt, next_step: "Fill out the template with specific details and call this tool again with execution_mode='create' and the filled project_plan" }, null, 2) } ] }; } else if (validatedArgs.execution_mode === 'create') { if (!validatedArgs.project_plan) { throw new Error('project_plan is required when execution_mode is "create"'); } logger.info('Creating project from agent-provided plan', { projectName: validatedArgs.project_plan.project.name }); // Get the authenticated user context // For MCP keys, we need a valid UUID. Use a placeholder UUID let userId = '00000000-0000-0000-0000-000000000000'; // Null UUID as placeholder try { const authContext = authManager.getAuthContext(); if (authContext.userId && authContext.userId !== 'mcp-pending') { userId = authContext.userId; } else { logger.info('Using placeholder UUID for MCP context owner_id'); } } catch (e) { // If not authenticated yet, use placeholder logger.info('Using placeholder UUID for MCP context owner_id'); } // Use the MCP handlers directly to ensure proper authentication and association // Create the project using the MCP handler const projectResult = await projectHandlers.create_project({ name: validatedArgs.project_plan.project.name, description: validatedArgs.project_plan.project.description, status: validatedArgs.project_plan.project.status }); const createdProject = projectResult.project; const createdInitiatives = []; const createdTasks = []; const createdDocuments = []; // Create initiatives and their tasks for (const initiative of validatedArgs.project_plan.initiatives) { try { // Use the MCP handler which properly handles project association const initiativeResult = await initiativeHandlers.create_initiative({ name: initiative.name, objective: initiative.objective, description: initiative.description, priority: initiative.priority, status: initiative.status, owner_id: userId, // Required field project_ids: [createdProject.id], // Associate with the created project start_date: initiative.start_date, target_date: initiative.target_date, metadata: {}, tags: [] }); const createdInitiative = initiativeResult.initiative; createdInitiatives.push(createdInitiative); // Create tasks for this initiative for (const task of initiative.tasks) { try { const taskResult = await taskHandlers.create_task({ project_id: createdProject.id, initiative_id: createdInitiative.id, title: task.title, description: task.description, priority: task.priority, status: task.status, assignee_id: task.assignee_id, due_date: task.due_date }); createdTasks.push(taskResult.task); } catch (taskError) { logger.error('Failed to create task', { task: task.title, error: taskError }); } } } catch (initiativeError) { logger.error('Failed to create initiative', { initiative: initiative.name, error: initiativeError }); } } // Create documents if provided if (validatedArgs.project_plan.documents) { for (const doc of validatedArgs.project_plan.documents) { try { const docResult = await documentHandlers.create_document({ project_id: createdProject.id, title: doc.title, content: doc.content, document_type: doc.document_type }); createdDocuments.push(docResult.document); } catch (docError) { logger.error('Failed to create document', { document: doc.title, error: docError }); } } } return { content: [ { type: 'text' as const, text: JSON.stringify({ mode: 'create', success: true, created: { project: { id: createdProject.id, name: createdProject.name, description: createdProject.description }, initiatives: createdInitiatives.map(i => ({ id: i.id, name: i.name, objective: i.objective })), tasks: createdTasks.map(t => ({ id: t.id, title: t.title, initiative_id: t.initiative_id })), documents: createdDocuments.map(d => ({ id: d.id, title: d.title, type: d.document_type })) }, summary: `Successfully created project "${createdProject.name}" with ${createdInitiatives.length} initiatives, ${createdTasks.length} tasks, and ${createdDocuments.length} documents.` }, null, 2) } ] }; } else { throw new Error(`Invalid execution_mode: ${validatedArgs.execution_mode}`); } } catch (error) { logger.error('Error in prompt_to_project tool', { error }); const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text' as const, text: JSON.stringify({ error: errorMessage, details: error instanceof z.ZodError ? error.errors : undefined }, null, 2) } ], isError: true }; } }
- src/tools/prompt-to-project.ts:46-50 (schema)Zod schema for input validation of the prompt_to_project tool, defining prompt, execution_mode ('analyze' or 'create'), and optional project_plan structure.const PromptToProjectArgsSchema = z.object({ prompt: z.string().describe('Natural language description of the project to create'), execution_mode: ExecutionMode.describe('analyze: return structured requirements for agent to process, create: execute agent-provided plan'), project_plan: ProjectPlanSchema.optional().describe('Required when execution_mode is "create" - the structured plan to execute') });
- src/index.ts:128-155 (registration)Registration of the prompt_to_project tool in the MCP server: imported at line 25, added to allTools array (line 139), and handler mapped into allHandlers (line 153).// Combine all tools and handlers this.allTools = [ ...Object.values(projectTools), ...Object.values(taskTools), ...Object.values(documentTools), ...Object.values(conversationTools), ...Object.values(contextAggregationTools), ...Object.values(workflowAutomationTools), ...Object.values(intelligentSearchTools), ...Object.values(analyticsInsightsTools), ...Object.values(initiativeTools), ...promptToProjectTools, ...Object.values(debugTools), ] this.allHandlers = { ...projectHandlers, ...taskHandlers, ...documentHandlers, ...conversationHandlers, ...contextAggregationHandlers, ...workflowAutomationHandlers, ...intelligentSearchHandlers, ...analyticsInsightsHandlers, ...initiativeHandlers, ...promptToProjectTools.reduce((acc, tool) => ({ ...acc, [tool.name]: tool.handler }), {}), ...debugHandlers, }
- src/tools/prompt-to-project.ts:52-64 (helper)Helper function to extract key requirements from the prompt using regex patterns to detect timeline, team, technology mentions etc., used in analysis.function extractKeyRequirements(prompt: string) { const requirements = { mentions_timeline: /deadline|timeline|due|by|until|before|sprint|milestone/i.test(prompt), mentions_team: /team|developer|designer|engineer|member|person|people/i.test(prompt), mentions_technology: /react|node|python|java|database|api|frontend|backend|fullstack/i.test(prompt), mentions_features: /feature|functionality|capability|requirement|user story/i.test(prompt), mentions_priority: /urgent|critical|high priority|important|asap|immediately/i.test(prompt), is_technical: /api|database|frontend|backend|integration|deployment|testing/i.test(prompt), is_business: /customer|user|market|revenue|sales|marketing|business/i.test(prompt) }; return requirements; }
- Helper function generates a fillable project template structure based on prompt analysis, used in 'analyze' mode.function generateProjectTemplate(prompt: string) { const requirements = extractKeyRequirements(prompt); const template = { project: { name: "[Project name based on the prompt]", description: "[Comprehensive project description expanding on: " + prompt + "]", status: "active" as const }, initiatives: [ { name: "[Core Feature/Initiative 1]", objective: "[What this initiative aims to achieve]", description: "[Detailed description]", priority: requirements.mentions_priority ? "high" as const : "medium" as const, status: "planning" as const, tasks: [ { title: "[Specific task 1]", description: "[Task details]", priority: "medium" as const, status: "todo" as const } ] } ], documents: requirements.is_technical ? [ { title: "Technical Specification", content: "[Technical documentation for the project]", document_type: "technical" as const }, { title: "Project Requirements", content: "[Detailed requirements document]", document_type: "requirement" as const } ] : [] }; return template; }