Skip to main content
Glama

generate_from_template

Create ComfyUI workflows by substituting custom parameters into predefined templates, optionally saving the generated DSL content for workflow automation.

Instructions

Generate a workflow from a template with custom parameters.

Creates a complete DSL workflow by substituting parameters into the template. Optionally saves to file.

Args: template_name: Name of the template to use parameters: Dictionary of parameter values to substitute save_path: Optional path to save the generated workflow

Returns: Generated DSL content and validation results

Examples: generate_from_template("text2img_basic", {"prompt": "sunset"}) generate_from_template("img2img", {"image_path": "input.png"}, "workflows/my_img2img.dsl")

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
template_nameYes
parametersNo
save_pathNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • MCP tool handler for 'generate_from_template'. Orchestrates template retrieval, parameter validation, DSL generation via TemplateManager, optional file saving, and result formatting.
    @mcp.tool
    def generate_from_template(
        template_name: str,
        parameters: dict = None,
        save_path: str = None
    ) -> dict:
        """Generate a workflow from a template with custom parameters.
        
        Creates a complete DSL workflow by substituting parameters into
        the template. Optionally saves to file.
        
        Args:
            template_name: Name of the template to use
            parameters: Dictionary of parameter values to substitute
            save_path: Optional path to save the generated workflow
        
        Returns:
            Generated DSL content and validation results
        
        Examples:
            generate_from_template("text2img_basic", {"prompt": "sunset"})
            generate_from_template("img2img", {"image_path": "input.png"}, "workflows/my_img2img.dsl")
        """
        try:
            # Validate template exists
            template = template_manager.get_template(template_name)
            if template is None:
                raise ToolError(f"Template '{template_name}' not found")
            
            # Validate parameters if provided
            if parameters:
                validation = template_manager.validate_parameters(template_name, parameters)
                if not validation["valid"]:
                    return {
                        "status": "error",
                        "errors": validation["errors"],
                        "warnings": validation.get("warnings", [])
                    }
            
            # Generate the workflow
            dsl_content = template_manager.generate_workflow(template_name, parameters)
            
            if dsl_content is None:
                raise ToolError(f"Failed to generate workflow from template '{template_name}'")
            
            result = {
                "status": "success",
                "template_name": template_name,
                "dsl_content": dsl_content,
                "parameters_used": parameters or {},
                "warnings": []
            }
            
            # Add warnings if any
            if parameters:
                validation = template_manager.validate_parameters(template_name, parameters)
                result["warnings"] = validation.get("warnings", [])
            
            # Save to file if requested
            if save_path:
                try:
                    path = validate_path(save_path)
                    path.write_text(dsl_content)
                    result["saved_to"] = str(path)
                    result["file_size"] = path.stat().st_size
                except Exception as e:
                    result["warnings"].append(f"Failed to save to {save_path}: {e}")
            
            return result
            
        except Exception as e:
            raise ToolError(f"Error generating from template: {e}")
  • Core helper function in TemplateManager that implements the workflow generation logic by loading template DSL (custom or official), substituting parameters via string replacement, and returning the final DSL content.
    def generate_workflow(
        self, 
        template_name: str, 
        parameters: Optional[Dict[str, str]] = None,
        source: str = "auto"
    ) -> Optional[str]:
        """Generate a workflow DSL from template with parameter substitution."""
        # Try custom templates first, then official
        template = None
        dsl_content = None
        
        if source in ["auto", "custom"]:
            template = self.custom_templates.get(template_name)
            if template:
                dsl_content = template.dsl_content
        
        if not template and source in ["auto", "official"]:
            official_template = official_manager.get_template(template_name)
            if official_template and official_template.dsl_content:
                dsl_content = official_template.dsl_content
                # Create a minimal template-like object for parameter handling
                template = type('Template', (), {
                    'parameters': {},  # Official templates don't have default parameters
                    'dsl_content': dsl_content
                })()
        
        if not template or not dsl_content:
            return None
        
        # Start with template's default parameters
        final_params = template.parameters.copy() if hasattr(template, 'parameters') and template.parameters else {}
        
        # Override with provided parameters
        if parameters:
            final_params.update(parameters)
        
        # Substitute parameters in DSL content if any
        if final_params:
            for param_name, param_value in final_params.items():
                # Replace {param_name} with actual value
                placeholder = f"{{{param_name}}}"
                dsl_content = dsl_content.replace(placeholder, str(param_value))
        
        return dsl_content
  • Helper function for parameter validation, extracts placeholders from DSL, checks required/missing/extra params, and performs type/constraint validation used by the tool handler.
    def validate_parameters(
        self, 
        template_name: str, 
        parameters: Dict[str, str],
        source: str = "auto"
    ) -> Dict[str, List[str]]:
        """Validate parameters for a template."""
        # Try to find template in custom or official
        template = None
        if source in ["auto", "custom"]:
            template = self.custom_templates.get(template_name)
        
        if not template and source in ["auto", "official"]:
            official_template = official_manager.get_template(template_name)
            if official_template and official_template.dsl_content:
                # Create minimal template object for validation
                template = type('Template', (), {
                    'parameters': {},
                    'dsl_content': official_template.dsl_content
                })()
        if not template:
            return {
                "valid": False,
                "errors": [f"Template '{template_name}' not found"],
                "warnings": []
            }
        
        errors = []
        warnings = []
        
        # Check for required parameters (those in template but not provided)
        template_params = template.parameters or {}
        required_params = set(self._extract_parameters_from_dsl(template.dsl_content))
        provided_params = set(parameters.keys())
        
        missing_params = required_params - provided_params
        if missing_params:
            errors.append(f"Missing required parameters: {', '.join(missing_params)}")
        
        # Check for extra parameters
        extra_params = provided_params - required_params
        if extra_params:
            warnings.append(f"Extra parameters will be ignored: {', '.join(extra_params)}")
        
        # Validate specific parameter types/constraints
        for param_name, param_value in parameters.items():
            if param_name in template_params:
                validation_errors = self._validate_parameter_value(
                    param_name, param_value, template_name
                )
                errors.extend(validation_errors)
        
        return {
            "valid": len(errors) == 0,
            "errors": errors,
            "warnings": warnings
        }
  • Import and global initialization of TemplateManager instance used by all template tools including generate_from_template.
    from ..templates import TemplateManager
    
    # Create MCP server
    mcp = FastMCP("ComfyUI Workflow Manager 🎨")
    
    # Security: Define allowed base directory for file operations
    WORKFLOWS_BASE = Path.cwd() / "workflows"
    WORKFLOWS_BASE.mkdir(exist_ok=True)
    
    # Initialize template manager
    template_manager = TemplateManager()
Behavior3/5

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

With no annotations provided, the description carries full burden. It discloses that it 'creates a complete DSL workflow' and 'optionally saves to file', indicating mutation behavior and file system interaction. However, it doesn't mention permissions needed, error conditions, rate limits, or what happens if save_path conflicts with existing files.

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

Conciseness5/5

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

The description is well-structured with a clear opening sentence, organized Args and Returns sections, and practical examples. Every sentence adds value—no fluff or repetition. It's appropriately sized for a 3-parameter tool with complex functionality.

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

Completeness4/5

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

Given 3 parameters with 0% schema coverage and no annotations, the description does a good job explaining parameters and purpose. The presence of an output schema means it doesn't need to detail return values. However, for a mutation tool that interacts with file systems, more behavioral context (e.g., error handling, idempotency) would improve completeness.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate. It provides clear semantic explanations for all 3 parameters: template_name (name of template), parameters (dictionary for substitution), and save_path (optional save location). This adds significant value beyond the bare schema, though it doesn't detail parameter formats or constraints.

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

Purpose5/5

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

The description clearly states the specific action ('Generate a workflow from a template with custom parameters') and distinguishes it from siblings like get_template (which retrieves) or write_workflow (which writes raw content). It specifies the resource (workflow) and method (substituting parameters into template).

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

Usage Guidelines4/5

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

The description implies usage for creating workflows from templates, but doesn't explicitly state when to use this versus alternatives like write_workflow (for manual creation) or validate_template_parameters (for checking parameters first). It provides context through examples but lacks explicit 'when-not' guidance or named alternatives.

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/christian-byrne/comfy-mcp'

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