prompt_to_project
Convert natural language project descriptions into structured project entities. Analyze mode provides templates for AI agents to fill; 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 implementing the 'prompt_to_project' tool logic. Parses args with Zod schema, handles 'analyze' mode by generating structured project template, guidance, and requirements for AI agent, and 'create' mode by executing the provided plan: creating project, initiatives, tasks, and documents using 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 defining the input arguments for the prompt_to_project tool: prompt string, execution_mode enum (analyze/create), and optional project_plan object.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/tools/prompt-to-project.ts:32-44 (schema)Supporting schema for project_plan structure used in 'create' mode, including nested project, initiatives (with tasks), and documents.const ProjectPlanSchema = z.object({ project: z.object({ name: z.string(), description: z.string().optional(), status: z.enum(['active', 'completed', 'archived']).default('active') }), initiatives: z.array(InitiativePlanSchema).default([]), documents: z.array(z.object({ title: z.string(), content: z.string(), document_type: z.enum(['requirement', 'design', 'technical', 'meeting_notes', 'other']) })).optional() });
- src/index.ts:129-141 (registration)Registration of the promptToProjectTools array into the server's complete list of available tools (this.allTools), exposed via listTools MCP method.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), ]
- src/index.ts:143-155 (registration)Registration of the tool handler into the server's handler map (this.allHandlers[name]), used for executing tool calls via MCP CallToolRequest.this.allHandlers = { ...projectHandlers, ...taskHandlers, ...documentHandlers, ...conversationHandlers, ...contextAggregationHandlers, ...workflowAutomationHandlers, ...intelligentSearchHandlers, ...analyticsInsightsHandlers, ...initiativeHandlers, ...promptToProjectTools.reduce((acc, tool) => ({ ...acc, [tool.name]: tool.handler }), {}), ...debugHandlers, }