Skip to main content
Glama

AI Code Toolkit

by AgiFlow
AddDesignPatternTool.ts6.1 kB
/** * AddDesignPatternTool * * DESIGN PATTERNS: * - Tool pattern with getDefinition() and execute() methods * - Service delegation for business logic * - JSON Schema validation for inputs * - YAML manipulation for architect.yaml updates * * CODING STANDARDS: * - Implement Tool interface from ../types * - Use TOOL_NAME constant with kebab-case * - Return CallToolResult with content array * - Handle errors with isError flag * - Validate all inputs thoroughly * * AVOID: * - Complex business logic in execute method * - Unhandled promise rejections * - Missing input validation */ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; import type { Tool, ToolDefinition, Feature } from '../types/index.js'; import { TemplatesManagerService } from '@agiflowai/aicode-utils'; import * as fs from 'node:fs/promises'; import * as yaml from 'js-yaml'; import * as path from 'node:path'; interface AddDesignPatternToolInput { template_name: string; pattern_name: string; design_pattern: string; includes: string[]; description: string; } export class AddDesignPatternTool implements Tool<AddDesignPatternToolInput> { static readonly TOOL_NAME = 'add-design-pattern'; getDefinition(): ToolDefinition { return { name: AddDesignPatternTool.TOOL_NAME, description: "Admin tool to add a new design pattern to a template's architect.yaml file. Creates the file if it doesn't exist.", inputSchema: { type: 'object', properties: { template_name: { type: 'string', description: 'Name of the template (e.g., "nextjs-15", "typescript-mcp-package")', }, pattern_name: { type: 'string', description: 'Name of the design pattern', }, design_pattern: { type: 'string', description: 'The design pattern description or category', }, includes: { type: 'array', items: { type: 'string' }, description: 'Array of file patterns that match this design pattern (e.g., ["src/components/**/*.tsx"])', }, description: { type: 'string', description: 'Detailed markdown description following the format: Pattern Overview, What TO DO (✅), What NOT TO DO (❌), and Examples with code blocks', }, }, required: ['template_name', 'pattern_name', 'design_pattern', 'includes', 'description'], additionalProperties: false, }, }; } async execute(input: AddDesignPatternToolInput): Promise<CallToolResult> { try { // Get templates root const templatesRoot = await TemplatesManagerService.findTemplatesPath(); const templatePath = path.join(templatesRoot, input.template_name); // Check if template exists try { await fs.access(templatePath); } catch { return { content: [ { type: 'text', text: JSON.stringify( { error: `Template "${input.template_name}" not found at ${templatePath}`, available_hint: 'Check templates directory for available templates', }, null, 2, ), }, ], isError: true, }; } const architectPath = path.join(templatePath, 'architect.yaml'); // Read existing architect.yaml or create new structure let architectConfig: { features?: Feature[] } = { features: [] }; try { const content = await fs.readFile(architectPath, 'utf-8'); const parsed = yaml.load(content) as any; architectConfig = parsed || { features: [] }; // Ensure features array exists if (!architectConfig.features) { architectConfig.features = []; } } catch { // File doesn't exist, will create new one architectConfig = { features: [] }; } // Check if pattern already exists const existingPattern = architectConfig.features?.find( (f) => f.name === input.pattern_name || f.architecture === input.pattern_name, ); if (existingPattern) { return { content: [ { type: 'text', text: JSON.stringify( { error: `Pattern "${input.pattern_name}" already exists in ${input.template_name}`, existing_pattern: existingPattern, }, null, 2, ), }, ], isError: true, }; } // Add new pattern const newFeature: Feature = { name: input.pattern_name, design_pattern: input.design_pattern, includes: input.includes, description: input.description, }; architectConfig.features?.push(newFeature); // Write back to file const yamlContent = yaml.dump(architectConfig, { indent: 2, lineWidth: -1, // Disable line wrapping noRefs: true, }); await fs.writeFile(architectPath, yamlContent, 'utf-8'); return { content: [ { type: 'text', text: JSON.stringify( { success: true, message: `Added design pattern "${input.pattern_name}" to ${input.template_name}`, file: architectPath, pattern: newFeature, }, null, 2, ), }, ], }; } catch (error) { return { content: [ { type: 'text', text: JSON.stringify( { error: error instanceof Error ? error.message : 'Unknown error', template_name: input.template_name, }, null, 2, ), }, ], isError: true, }; } } }

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/AgiFlow/aicode-toolkit'

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