Skip to main content
Glama

execute_workflow

Run automated workflows by ID with custom variables for tasks like planning, code review, summarization, and project management.

Instructions

Execute a workflow by ID with optional variables

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
workflowIdYesThe ID of the workflow to execute
variablesNoVariables to pass to the workflow

Implementation Reference

  • MCP tool handler for 'execute_workflow'. Retrieves workflow from registry, executes it via workflowEngine, handles errors, and returns formatted JSON response.
      async (args) => {
        try {
          const workflow = registry.getWorkflow(args.workflowId);
          if (!workflow) {
            return {
              content: [
                {
                  type: "text",
                  text: `Workflow not found: ${args.workflowId}`,
                },
              ],
              isError: true,
            };
          }
    
          const result = await registry.workflowEngine.execute(workflow, args.variables);
    
          if (result.success) {
            // Format the results for display
            const stepsSummary = Array.from(result.results.entries()).map(([stepId, stepResult]) => ({
              stepId,
              success: stepResult.success,
              error: stepResult.error,
            }));
    
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(
                    {
                      workflow: workflow.name,
                      success: true,
                      duration: result.duration,
                      variables: result.variables,
                      steps: stepsSummary,
                    },
                    null,
                    2
                  ),
                },
              ],
            };
          } else {
            return {
              content: [
                {
                  type: "text",
                  text: JSON.stringify(
                    {
                      workflow: workflow.name,
                      success: false,
                      error: result.error,
                      duration: result.duration,
                    },
                    null,
                    2
                  ),
                },
              ],
              isError: true,
            };
          }
        } catch (error) {
          return {
            content: [
              {
                type: "text",
                text: `Error executing workflow: ${error instanceof Error ? error.message : String(error)}`,
              },
            ],
            isError: true,
          };
        }
      }
    );
  • Input schema using Zod for the tool parameters.
      workflowId: z.string().describe("The ID of the workflow to execute"),
      variables: z.record(z.any()).optional().describe("Variables to pass to the workflow"),
    },
  • Registration of the 'execute_workflow' tool with the MCP server in registerWorkflowTools function.
        "execute_workflow",
        "Execute a workflow by ID with optional variables",
        {
          workflowId: z.string().describe("The ID of the workflow to execute"),
          variables: z.record(z.any()).optional().describe("Variables to pass to the workflow"),
        },
        async (args) => {
          try {
            const workflow = registry.getWorkflow(args.workflowId);
            if (!workflow) {
              return {
                content: [
                  {
                    type: "text",
                    text: `Workflow not found: ${args.workflowId}`,
                  },
                ],
                isError: true,
              };
            }
    
            const result = await registry.workflowEngine.execute(workflow, args.variables);
    
            if (result.success) {
              // Format the results for display
              const stepsSummary = Array.from(result.results.entries()).map(([stepId, stepResult]) => ({
                stepId,
                success: stepResult.success,
                error: stepResult.error,
              }));
    
              return {
                content: [
                  {
                    type: "text",
                    text: JSON.stringify(
                      {
                        workflow: workflow.name,
                        success: true,
                        duration: result.duration,
                        variables: result.variables,
                        steps: stepsSummary,
                      },
                      null,
                      2
                    ),
                  },
                ],
              };
            } else {
              return {
                content: [
                  {
                    type: "text",
                    text: JSON.stringify(
                      {
                        workflow: workflow.name,
                        success: false,
                        error: result.error,
                        duration: result.duration,
                      },
                      null,
                      2
                    ),
                  },
                ],
                isError: true,
              };
            }
          } catch (error) {
            return {
              content: [
                {
                  type: "text",
                  text: `Error executing workflow: ${error instanceof Error ? error.message : String(error)}`,
                },
              ],
              isError: true,
            };
          }
        }
      );
    }
  • Core WorkflowEngine.execute method that implements the workflow execution logic delegated to by the tool handler.
    async execute(
      workflow: Workflow,
      initialVars?: Record<string, unknown>
    ): Promise<WorkflowResult> {
      const startTime = Date.now();
    
      // Create execution context
      const context: WorkflowExecutionContext = {
        variables: { ...workflow.variables, ...initialVars },
        results: new Map(),
        state: {
          currentStep: 0,
          startTime,
          completedSteps: [],
          failedSteps: [],
        },
      };
    
      try {
        // Execute each step
        for (let i = 0; i < workflow.steps.length; i++) {
          context.state.currentStep = i;
          const step = workflow.steps[i];
    
          // Check run condition if present
          if (step.runCondition) {
            const shouldRun = Boolean(this.evaluator.evaluate(step.runCondition, context));
            if (!shouldRun) {
              continue; // Skip this step
            }
          }
    
          try {
            const result = await this.executeStep(step, context);
            const stepResult: WorkflowStepResult = {
              stepId: step.id,
              success: true,
              result,
              retries: 0,
              duration: 0,
            };
            context.results.set(step.id, stepResult);
            context.state.completedSteps.push(step.id);
          } catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            const stepResult: WorkflowStepResult = {
              stepId: step.id,
              success: false,
              error: errorMessage,
              retries: 0,
              duration: 0,
            };
            context.results.set(step.id, stepResult);
            context.state.failedSteps.push(step.id);
    
            // Handle error based on onError setting
            if (step.onError === "continue") {
              continue; // Continue to next step
            } else if (step.onError === "retry" && step.retryCount) {
              // Retry logic
              let success = false;
              for (let r = 0; r < step.retryCount; r++) {
                try {
                  const result = await this.executeStep(step, context);
                  const retryResult: WorkflowStepResult = {
                    stepId: step.id,
                    success: true,
                    result,
                    retries: r + 1,
                    duration: 0,
                  };
                  context.results.set(step.id, retryResult);
                  context.state.failedSteps = context.state.failedSteps.filter(
                    (id) => id !== step.id
                  );
                  success = true;
                  break;
                } catch {
                  // Continue retrying
                }
              }
              if (!success) {
                return {
                  success: false,
                  variables: context.variables,
                  results: context.results,
                  error: `Step '${step.id}' failed after ${step.retryCount} retries`,
                  duration: Date.now() - startTime,
                };
              }
            } else {
              // Default: stop on error
              return {
                success: false,
                variables: context.variables,
                results: context.results,
                error: `Step '${step.id}' failed: ${errorMessage}`,
                duration: Date.now() - startTime,
              };
            }
          }
        }
    
        return {
          success: context.state.failedSteps.length === 0,
          variables: context.variables,
          results: context.results,
          duration: Date.now() - startTime,
        };
      } catch (error) {
        return {
          success: false,
          variables: context.variables,
          results: context.results,
          error: error instanceof Error ? error.message : String(error),
          duration: Date.now() - startTime,
        };
      }
    }

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/ishuru/open-mcp'

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