Skip to main content
Glama

phase_output

Capture and document results for completed workflow phases, ensuring structured output artifacts with numbered file naming and required formats like markdown, JSON, or text.

Instructions

Record the output/results when completing a workflow phase - REQUIRES ACTUAL OUTPUT ARTIFACTS with numbered file naming

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
outputYesThe results/findings from this phase
outputArtifactsYesMANDATORY: List of actual output artifacts you created for this phase (use numbered file names)
phaseYesThe phase you are completing

Implementation Reference

  • Core handler function for the phase_output tool. Validates artifacts, processes outputs, records phase completion in SessionManager, handles metrics, and returns success/error with artifact details.
    export async function handlePhaseOutput( params: { phase: Phase; output: any; outputArtifacts: { path: string; format: 'markdown' | 'json' | 'text'; description: string; content: string; }[]; }, sessionManager: SessionManager ) { const session = sessionManager.getSession(); if (!session) { return { error: 'No active session', message: 'Start a workflow with build_custom_workflow first' }; } // ENFORCEMENT: Validate output artifacts are provided if (!params.outputArtifacts || params.outputArtifacts.length === 0) { return { error: 'VALIDATION FAILED: No output artifacts provided', message: '⛔ Cannot complete phase without providing actual output artifacts', resolution: [ 'You must create actual documentation OR provide structured JSON output', 'Option 1 - File: { path: "/path/to/plan.md", format: "markdown", description: "My plan", content: "# Plan\\n..." }', 'Option 2 - JSON Response: { path: "audit-analysis", format: "json", description: "Analysis results", content: "{...}" }' ], hint: 'The phase_output tool now requires actual artifacts, not just recording that work was done' }; } // ENFORCEMENT: Validate each artifact const validationErrors: string[] = []; for (const artifact of params.outputArtifacts) { // Check content is not empty if (!artifact.content || artifact.content.trim().length < 10) { validationErrors.push(`Artifact "${artifact.path}": Content too short or empty (minimum 10 characters)`); } // Validate JSON format if specified if (artifact.format === 'json') { try { JSON.parse(artifact.content); } catch { validationErrors.push(`Artifact "${artifact.path}": Invalid JSON format`); } } // Check for meaningful content based on phase if (!validatePhaseSpecificContent(params.phase, artifact)) { validationErrors.push(`Artifact "${artifact.path}": Does not contain expected ${params.phase} content`); } } if (validationErrors.length > 0) { return { error: 'VALIDATION FAILED: Output artifacts do not meet requirements', validationErrors, message: '⛔ Cannot complete phase with invalid artifacts', resolution: [ 'Fix the validation errors listed above', 'Ensure your artifacts contain meaningful, structured content', 'For JSON artifacts, ensure valid JSON syntax', 'For markdown artifacts, ensure proper structure and detail', 'Path can be a file path OR descriptive identifier for structured output' ] }; } const savedArtifacts: Array<{ path: string; format: 'markdown' | 'json' | 'text'; description: string; content: string; savedAt: string | null; saveError?: string; }> = []; // Resolve output directory (handles relative paths) const rawOutputDirectory = session.workflowConfig?.outputPreferences?.outputDirectory || 'structured-workflow'; const outputDirectory = resolveOutputDirectory(rawOutputDirectory, process.cwd()); for (const artifact of params.outputArtifacts) { // Build a numbered filename suggestion const fileConfig: NumberedFileConfig = { phase: params.phase, outputDirectory: outputDirectory, extension: getExtensionForFormat(artifact.format), includeDate: true }; const suggestedFileName = generateNumberedFileName(fileConfig); const suggestedPath = path.join(outputDirectory, sanitizeTaskName(session.taskDescription), suggestedFileName); // Prepare array of artifact write instructions; no disk operation savedArtifacts.push({ ...artifact, path: suggestedPath, savedAt: null // Nothing actually written }); } // Record the phase output with artifacts (including saved paths) const enrichedOutput = { ...params.output, artifacts: savedArtifacts, validatedAt: new Date().toISOString(), outputDirectory: outputDirectory, taskDirectory: path.join(outputDirectory, sanitizeTaskName(session.taskDescription)) }; sessionManager.recordPhaseOutput(params.phase, enrichedOutput); // Mark phase as completed if not already if (!session.completedPhases.includes(params.phase)) { session.completedPhases.push(params.phase); } // Update metrics based on phase output if (params.phase === 'LINT' && params.output.errors) { sessionManager.updateMetrics({ lintIssuesFound: params.output.errors.length || 0 }); } if (params.phase === 'ITERATE' && params.output.fixesApplied) { sessionManager.updateMetrics({ lintIssuesFixed: params.output.fixesApplied.length || 0 }); } // Count successfully saved artifacts const savedCount = savedArtifacts.filter(a => !a.saveError).length; const failedCount = savedArtifacts.length - savedCount; return { recorded: true, phase: params.phase, artifactsValidated: params.outputArtifacts.length, artifactsSaved: savedCount, artifactsFailed: failedCount, artifacts: savedArtifacts.map(a => ({ path: a.path, format: a.format, description: a.description, savedAt: a.savedAt, saveError: a.saveError })), outputDirectory: enrichedOutput.outputDirectory, taskDirectory: enrichedOutput.taskDirectory, timestamp: new Date().toISOString(), message: savedCount > 0 ? `✅ Successfully recorded and saved ${savedCount} artifact(s) for ${params.phase} phase` + (failedCount > 0 ? ` (${failedCount} failed to save)` : '') : `✅ Successfully validated ${params.outputArtifacts.length} artifact(s) for ${params.phase} phase (file saving disabled)`, hint: 'Use workflow_status to see overall progress, or validate_phase_completion to verify requirements' }; }
  • Tool factory function defining the phase_output tool, including name, description, and detailed inputSchema with phase enum, output object, and mandatory outputArtifacts array.
    export function createPhaseOutputTool(): Tool { return { name: 'phase_output', description: 'Record the output/results when completing a workflow phase - REQUIRES ACTUAL OUTPUT ARTIFACTS with numbered file naming', inputSchema: { type: 'object', properties: { phase: { type: 'string', enum: ['AUDIT_INVENTORY', 'COMPARE_ANALYZE', 'QUESTION_DETERMINE', 'WRITE_OR_REFACTOR', 'TEST', 'LINT', 'ITERATE', 'PRESENT'], description: 'The phase you are completing' }, output: { type: 'object', description: 'The results/findings from this phase', additionalProperties: true }, outputArtifacts: { type: 'array', items: { type: 'object', properties: { path: { type: 'string', description: 'File path if written to disk, OR descriptive identifier for JSON output provided in response' }, format: { type: 'string', enum: ['markdown', 'json', 'text'], description: 'Format of the output' }, description: { type: 'string', description: 'Brief description of what this artifact contains' }, content: { type: 'string', description: 'REQUIRED: The actual content/JSON of your output (for validation)' } }, required: ['path', 'format', 'description', 'content'] }, description: 'MANDATORY: List of actual output artifacts you created for this phase (use numbered file names)', minItems: 1 } }, required: ['phase', 'output', 'outputArtifacts'] } }; }
  • src/index.ts:137-157 (registration)
    Registers the phase_output tool in the MCP server's tools list by calling createPhaseOutputTool() for the ListToolsRequestHandler.
    const tools = [ // Workflow entry points createRefactorWorkflowTool(), // Refactoring workflow createFeatureWorkflowTool(), // Feature creation workflow createTestWorkflowTool(), // Test writing workflow createTddWorkflowTool(), // TDD workflow createBuildCustomWorkflowTool(), // Custom workflow builder // Phase guidance tools ...createPhaseGuidanceTools(), // Handles both suggestive and directive modes createTestGuidanceTool(), // TEST phase guidance // Validation tools ...createValidationTools(), // Both validate_action and validate_phase_completion // Workflow management createUserInputRequiredTool(), // Escalation handling createWorkflowStatusTool(), // Workflow status createPhaseOutputTool(), // Phase output recording createDiscoverWorkflowToolsTool() // Tool discovery ];
  • src/index.ts:274-280 (registration)
    Dispatches phase_output tool calls to the handlePhaseOutput function in the server's CallToolRequestHandler switch statement.
    case 'phase_output': return { content: [{ type: 'text', text: JSON.stringify(await handlePhaseOutput(args as any, sessionManager), null, 2) }] };
  • Helper function that validates artifact content is relevant to the specific phase using keyword matching.
    function validatePhaseSpecificContent( phase: Phase, artifact: { path: string; format: string; description: string; content: string } ): boolean { const content = artifact.content.toLowerCase(); switch (phase) { case 'AUDIT_INVENTORY': // For audit/inventory, expect analysis and changes return ( (content.includes('audit') || content.includes('analysis') || content.includes('dependencies')) || (content.includes('inventory') || content.includes('changes') || content.includes('modifications')) || (artifact.format === 'json' && (content.includes('changes') || content.includes('files'))) ); case 'COMPARE_ANALYZE': // For compare/analyze, expect approaches and comparisons return ( content.includes('approach') || content.includes('option') || content.includes('comparison') || content.includes('pros') || content.includes('cons') || content.includes('recommend') ); case 'QUESTION_DETERMINE': // For question/determine, expect questions and implementation plans return ( content.includes('question') || content.includes('assumption') || content.includes('plan') || content.includes('step') || content.includes('implement') ); case 'WRITE_OR_REFACTOR': // For write/refactor, expect implementation details return ( content.includes('implement') || content.includes('change') || content.includes('modify') || content.includes('file') || content.includes('code') || content.includes('refactor') || content.includes('write') || content.includes('create') ); case 'TEST': // For test, expect test results and metrics return ( content.includes('test') || content.includes('pass') || content.includes('fail') || content.includes('result') || content.includes('coverage') || content.includes('metric') ); case 'LINT': // For lint, expect quality checks and errors return ( content.includes('lint') || content.includes('error') || content.includes('warning') || content.includes('quality') || content.includes('issue') || content.includes('fix') ); case 'ITERATE': // For iterate, expect fixes and improvements return ( content.includes('fix') || content.includes('resolve') || content.includes('improve') || content.includes('issue') || content.includes('iteration') || content.includes('update') ); case 'PRESENT': // For present, expect summary and recommendations return ( content.includes('summary') || content.includes('complete') || content.includes('result') || content.includes('recommend') || content.includes('future') || content.includes('overview') ); default: return true; // Allow unknown phases to pass basic validation } }

Latest Blog Posts

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/kingdomseed/structured-workflow-mcp'

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