Skip to main content
Glama
kingdomseed

Structured Workflow MCP

by kingdomseed

phase_output

Records verified outputs and artifacts when completing a workflow phase, requiring actual numbered files for validation in structured development processes.

Instructions

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

Input Schema

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

Implementation Reference

  • Core handler function that validates phase output artifacts, generates file paths, records output to sessionManager, marks phase as completed, and returns success/error 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 definition including name, description, and input schema requiring phase enum, output object, and array of outputArtifacts with content.
    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 by including createPhaseOutputTool() in the MCP server's tools array.
    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 calls to the phase_output tool by invoking the handlePhaseOutput function with sessionManager.
    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 appropriate for the specific workflow phase.
    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
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions mandatory artifacts with numbered file naming, which adds some context about requirements. However, it lacks details on permissions, side effects (e.g., whether recording is persistent or mutable), error handling, or response format, which are crucial for a tool that records outputs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded, stating the purpose and key requirement in a single sentence. It avoids unnecessary details, but could be slightly more structured by separating usage instructions from requirements. Overall, it's efficient with minimal waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (3 parameters with nested objects, no output schema, and no annotations), the description is incomplete. It doesn't explain what happens after recording (e.g., storage, retrieval, or validation outcomes), lacks error scenarios, and provides minimal guidance on how outputs are used in the workflow. This leaves gaps for effective tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds minimal value beyond the schema by emphasizing 'REQUIRES ACTUAL OUTPUT ARTIFACTS' and 'numbered file naming,' which are implied in the schema's 'outputArtifacts' description. This meets the baseline for high schema coverage without significant additional insights.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Record the output/results when completing a workflow phase.' It specifies the verb ('record') and resource ('output/results'), and distinguishes it from guidance-oriented siblings by focusing on recording actual artifacts. However, it doesn't explicitly differentiate from 'validate_phase_completion' or 'workflow_status', which might have overlapping functions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by stating 'when completing a workflow phase' and 'REQUIRES ACTUAL OUTPUT ARTIFACTS,' suggesting it should be used at phase completion with tangible outputs. It doesn't provide explicit alternatives or exclusions, such as when to use versus 'validate_phase_completion' or other sibling tools, leaving some ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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