mcp-ai-agent-guidelines
Version:
A comprehensive Model Context Protocol server providing professional tools, resources, and prompts for implementing AI agent best practices
212 lines • 9.03 kB
JavaScript
import { z } from "zod";
import { buildMetadataSection, buildReferencesSection, slugify, } from "../shared/prompt-utils.js";
/**
* Schema for a single step in a prompt chain.
*
* Each step represents a discrete prompting operation with:
* - Clear dependencies on previous steps
* - Explicit error handling strategy
* - Optional output capture for subsequent steps
*
* Inspired by claude-flow's sequential processing patterns.
*/
const ChainStepSchema = z.object({
name: z.string(),
description: z.string().optional(),
prompt: z.string(),
outputKey: z.string().optional(), // Key for storing/accessing this step's output
dependencies: z.array(z.string()).optional().default([]), // Step names or output keys this step depends on
errorHandling: z.enum(["skip", "retry", "abort"]).optional().default("abort"),
});
/**
* Main schema for prompt chaining configuration.
*
* Enables multi-step AI workflows with:
* - Sequential or parallel execution strategies
* - Inter-step data flow via output keys and dependencies
* - Configurable error handling per step
* - Context and variable management
*
* Best for: Progressive refinement, multi-phase analysis, complex transformations
*/
const PromptChainingSchema = z.object({
chainName: z.string(),
description: z.string().optional(),
steps: z.array(ChainStepSchema).min(1),
context: z.string().optional(), // Shared context for all steps
globalVariables: z.record(z.string()).optional().default({}), // Variables accessible to all steps
includeMetadata: z.boolean().optional().default(true),
includeReferences: z.boolean().optional().default(true),
includeVisualization: z.boolean().optional().default(true),
executionStrategy: z
.enum(["sequential", "parallel-where-possible"])
.optional()
.default("sequential"),
});
/**
* Prompt Chaining Builder - Creates sequential/parallel multi-step AI workflows
*
* Inspired by claude-flow's orchestration patterns, this tool enables:
* - Progressive refinement through multi-step prompting
* - Data flow between steps via output keys and dependencies
* - Flexible error handling (skip, retry, abort)
* - Automatic visualization of chain structure
*
* Integration with Serena patterns:
* - Context-aware execution (uses project memories)
* - Planning-first approach (design chain before execution)
* - Memory optimization (chains can be cached for reuse)
*
* Common use cases:
* - Security analysis pipelines (scan → assess → remediate)
* - Code review workflows (static → performance → recommendations)
* - Documentation generation (outline → draft → refine)
*
* @param args - Chain configuration (validated against PromptChainingSchema)
* @returns Formatted chain specification with visualization
*/
export async function promptChainingBuilder(args) {
const input = PromptChainingSchema.parse(args);
// Validate dependencies are acyclic and reference valid steps
validateDependencies(input.steps);
const chainPrompt = buildChainPrompt(input);
const visualization = input.includeVisualization
? buildChainVisualization(input.steps)
: "";
const metadata = input.includeMetadata
? buildMetadataSection({
sourceTool: "mcp_ai-agent-guid_prompt-chaining-builder",
filenameHint: `${slugify(input.chainName)}.chain.md`,
})
: "";
const references = input.includeReferences ? buildChainReferences() : "";
return {
content: [
{
type: "text",
text: `# 🔗 Prompt Chain: ${input.chainName}\n\n${metadata}${input.description ? `## Description\n${input.description}\n\n` : ""}${chainPrompt}\n\n${visualization}${references}`,
},
],
};
}
/**
* Validates step dependencies to ensure chain is executable.
*
* Checks:
* - All dependencies reference existing step names or output keys
* - No circular dependencies (implicit - would cause runtime issues)
* - Dependencies can be resolved in sequential execution order
*
* @param steps - Array of chain steps to validate
* @throws Error if any dependency is invalid
*/
function validateDependencies(steps) {
const stepNames = new Set(steps.map((s) => s.name));
const outputKeys = new Set(steps.filter((s) => s.outputKey).map((s) => s.outputKey));
for (const step of steps) {
for (const dep of step.dependencies || []) {
// Check if dependency is a step name or output key
if (!stepNames.has(dep) && !outputKeys.has(dep)) {
throw new Error(`Step "${step.name}" has invalid dependency "${dep}". Must reference an existing step name or output key.`);
}
}
}
}
function buildChainPrompt(input) {
let output = "";
// Add context if provided
if (input.context) {
output += `## Context\n${input.context}\n\n`;
}
// Add global variables if any
if (Object.keys(input.globalVariables).length > 0) {
output += "## Global Variables\n";
for (const [key, value] of Object.entries(input.globalVariables)) {
output += `- **${key}**: ${value}\n`;
}
output += "\n";
}
// Add execution strategy
output += `## Execution Strategy\n${input.executionStrategy === "sequential" ? "Steps will be executed sequentially in order." : "Steps will be executed in parallel where dependencies allow."}\n\n`;
// Build chain steps
output += "## Chain Steps\n\n";
for (let i = 0; i < input.steps.length; i++) {
const step = input.steps[i];
const stepNum = i + 1;
output += `### Step ${stepNum}: ${step.name}\n\n`;
if (step.description) {
output += `**Description**: ${step.description}\n\n`;
}
// Show dependencies
if (step.dependencies && step.dependencies.length > 0) {
output += `**Dependencies**: ${step.dependencies.join(", ")}\n\n`;
}
// Show error handling strategy
output += `**Error Handling**: ${step.errorHandling}\n\n`;
// Show prompt
output += `**Prompt**:\n\`\`\`\n${step.prompt}\n\`\`\`\n\n`;
// Show output key if defined
if (step.outputKey) {
output += `**Output Key**: \`${step.outputKey}\` (available for subsequent steps)\n\n`;
}
// Show data flow hint
if (step.dependencies && step.dependencies.length > 0) {
output += `**Input Data**: This step receives outputs from: ${step.dependencies.join(", ")}\n\n`;
}
output += "---\n\n";
}
// Add execution instructions
output += "## Execution Instructions\n\n";
output += "1. Execute steps in the order shown above\n";
output +=
"2. Pass outputs from completed steps to dependent steps using the output keys\n";
output +=
"3. Handle errors according to each step's error handling strategy\n";
output += "4. Maintain context and variable state throughout the chain\n";
output += "5. Document intermediate results for debugging and auditing\n";
return output;
}
function buildChainVisualization(steps) {
let mermaid = "## Chain Visualization\n\n```mermaid\ngraph TD\n";
mermaid += " Start([Start Chain])\n";
for (let i = 0; i < steps.length; i++) {
const step = steps[i];
const nodeId = `Step${i + 1}`;
// Add step node
mermaid += ` ${nodeId}["${step.name}"]\n`;
// Connect to previous step or start
if (i === 0) {
mermaid += ` Start --> ${nodeId}\n`;
}
// Add dependency arrows
if (step.dependencies && step.dependencies.length > 0) {
for (const dep of step.dependencies) {
// Find the step index for this dependency
const depIndex = steps.findIndex((s) => s.name === dep || s.outputKey === dep);
if (depIndex !== -1 && depIndex < i) {
mermaid += ` Step${depIndex + 1} -->|output| ${nodeId}\n`;
}
}
}
else if (i > 0) {
// If no explicit dependencies, connect to previous step
mermaid += ` Step${i} --> ${nodeId}\n`;
}
// Add output key annotation if present
if (step.outputKey) {
mermaid += ` ${nodeId} -.->|"${step.outputKey}"| ${nodeId}_out[(" ")]\n`;
mermaid += ` style ${nodeId}_out fill:transparent,stroke:transparent\n`;
}
}
mermaid += ` Step${steps.length} --> End([End Chain])\n`;
mermaid += "```\n\n";
return mermaid;
}
function buildChainReferences() {
return buildReferencesSection([
"Prompt Chaining Patterns: https://www.promptingguide.ai/techniques/prompt_chaining",
"Multi-step AI Workflows: https://arxiv.org/abs/2203.11171",
"Claude Flow Orchestration: https://github.com/ruvnet/claude-flow",
]);
}
//# sourceMappingURL=prompt-chaining-builder.js.map