Skip to main content
Glama

Execute a Mistral workflow

workflow_execute

Start a Mistral workflow execution with input, with option to wait for result or poll for status.

Instructions

Start a Mistral Workflow execution.

workflowIdentifier is the workflow name or ID (visible in mistral://workflows). input is a free-form JSON object matching the workflow's input schema.

Modes:

  • waitForResult=false (default): returns immediately with execution_id and RUNNING status. Poll workflow_status to track completion.

  • waitForResult=true: blocks until the workflow finishes and returns the result inline. Use timeoutSeconds (default 30) to cap the wait.

Use deploymentName to target a specific deployment slot when multiple are configured.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
workflowIdentifierYesWorkflow name or ID.
inputNoInput payload matching the workflow input schema.
executionIdNoOptional custom execution ID. Auto-generated if omitted.
waitForResultNoBlock until completion and return result inline. Default: false.
timeoutSecondsNoMax wait time when waitForResult=true. Default: 30.
deploymentNameNoTarget a specific deployment slot.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
workflow_nameYes
execution_idYes
syncYestrue when waitForResult=true (result is inline).
statusNo
resultNo
root_execution_idNo
start_timeNo
end_timeNo
total_duration_msNo

Implementation Reference

  • The async handler function for the workflow_execute tool. It calls mistral.workflows.executeWorkflow() with the provided input (workflowIdentifier, input, executionId, waitForResult, timeoutSeconds, deploymentName), then processes the response into a structured output distinguishing sync vs async execution modes.
    async (input) => {
      try {
        const res = await mistral.workflows.executeWorkflow({
          workflowIdentifier: input.workflowIdentifier,
          workflowExecutionRequest: {
            input: input.input ?? null,
            executionId: input.executionId,
            waitForResult: input.waitForResult ?? false,
            timeoutSeconds: input.timeoutSeconds,
            deploymentName: input.deploymentName,
          },
        });
    
        const sync = input.waitForResult === true;
        let structured: z.infer<typeof WorkflowExecuteOutputSchema>;
    
        if (sync && "result" in res && !("status" in res)) {
          // WorkflowExecutionSyncResponse
          const syncRes = res as { workflowName: string; executionId: string; result: unknown };
          structured = {
            workflow_name: syncRes.workflowName,
            execution_id: syncRes.executionId,
            sync: true,
            result: syncRes.result,
          };
        } else {
          // WorkflowExecutionResponse
          const asyncRes = res as {
            workflowName: string;
            executionId: string;
            rootExecutionId: string;
            status: string | null;
            startTime: Date;
            endTime: Date | null;
            result: unknown;
            totalDurationMs?: number | null;
          };
          structured = {
            workflow_name: asyncRes.workflowName,
            execution_id: asyncRes.executionId,
            sync: false,
            status: asyncRes.status,
            result: asyncRes.result,
            root_execution_id: asyncRes.rootExecutionId,
            start_time: asyncRes.startTime instanceof Date
              ? asyncRes.startTime.toISOString()
              : String(asyncRes.startTime),
            end_time: asyncRes.endTime instanceof Date
              ? asyncRes.endTime.toISOString()
              : asyncRes.endTime
                ? String(asyncRes.endTime)
                : null,
            total_duration_ms: asyncRes.totalDurationMs ?? null,
          };
        }
    
        const summary = sync
          ? `Workflow ${structured.workflow_name} completed (${structured.execution_id}).`
          : `Workflow ${structured.workflow_name} started as ${structured.execution_id} — status: ${structured.status}.`;
    
        return {
          content: [toTextBlock(summary)],
          structuredContent: structured,
        };
      } catch (err) {
        return errorResult("workflow_execute", err);
      }
    }
  • Registration of the workflow_execute tool on the MCP server via server.registerTool(), including title, description, inputSchema with all parameters (workflowIdentifier, input, executionId, waitForResult, timeoutSeconds, deploymentName), outputSchema using WorkflowExecuteOutputShape, and annotations.
    server.registerTool(
      "workflow_execute",
      {
        title: "Execute a Mistral workflow",
        description: [
          "Start a Mistral Workflow execution.",
          "",
          "`workflowIdentifier` is the workflow name or ID (visible in mistral://workflows).",
          "`input` is a free-form JSON object matching the workflow's input schema.",
          "",
          "Modes:",
          "  - waitForResult=false (default): returns immediately with execution_id and RUNNING status.",
          "    Poll workflow_status to track completion.",
          "  - waitForResult=true: blocks until the workflow finishes and returns the result inline.",
          "    Use timeoutSeconds (default 30) to cap the wait.",
          "",
          "Use deploymentName to target a specific deployment slot when multiple are configured.",
        ].join("\n"),
        inputSchema: {
          workflowIdentifier: z.string().min(1).describe("Workflow name or ID."),
          input: z
            .record(z.string(), z.unknown())
            .optional()
            .describe("Input payload matching the workflow input schema."),
          executionId: z
            .string()
            .optional()
            .describe("Optional custom execution ID. Auto-generated if omitted."),
          waitForResult: z
            .boolean()
            .optional()
            .describe("Block until completion and return result inline. Default: false."),
          timeoutSeconds: z
            .number()
            .int()
            .positive()
            .optional()
            .describe("Max wait time when waitForResult=true. Default: 30."),
          deploymentName: z
            .string()
            .optional()
            .describe("Target a specific deployment slot."),
        },
        outputSchema: WorkflowExecuteOutputShape,
        annotations: {
          title: "Execute Mistral workflow",
          readOnlyHint: false,
          destructiveHint: false,
          idempotentHint: false,
          openWorldHint: true,
        },
      },
      async (input) => {
        try {
          const res = await mistral.workflows.executeWorkflow({
            workflowIdentifier: input.workflowIdentifier,
            workflowExecutionRequest: {
              input: input.input ?? null,
              executionId: input.executionId,
              waitForResult: input.waitForResult ?? false,
              timeoutSeconds: input.timeoutSeconds,
              deploymentName: input.deploymentName,
            },
          });
    
          const sync = input.waitForResult === true;
          let structured: z.infer<typeof WorkflowExecuteOutputSchema>;
    
          if (sync && "result" in res && !("status" in res)) {
            // WorkflowExecutionSyncResponse
            const syncRes = res as { workflowName: string; executionId: string; result: unknown };
            structured = {
              workflow_name: syncRes.workflowName,
              execution_id: syncRes.executionId,
              sync: true,
              result: syncRes.result,
            };
          } else {
            // WorkflowExecutionResponse
            const asyncRes = res as {
              workflowName: string;
              executionId: string;
              rootExecutionId: string;
              status: string | null;
              startTime: Date;
              endTime: Date | null;
              result: unknown;
              totalDurationMs?: number | null;
            };
            structured = {
              workflow_name: asyncRes.workflowName,
              execution_id: asyncRes.executionId,
              sync: false,
              status: asyncRes.status,
              result: asyncRes.result,
              root_execution_id: asyncRes.rootExecutionId,
              start_time: asyncRes.startTime instanceof Date
                ? asyncRes.startTime.toISOString()
                : String(asyncRes.startTime),
              end_time: asyncRes.endTime instanceof Date
                ? asyncRes.endTime.toISOString()
                : asyncRes.endTime
                  ? String(asyncRes.endTime)
                  : null,
              total_duration_ms: asyncRes.totalDurationMs ?? null,
            };
          }
    
          const summary = sync
            ? `Workflow ${structured.workflow_name} completed (${structured.execution_id}).`
            : `Workflow ${structured.workflow_name} started as ${structured.execution_id} — status: ${structured.status}.`;
    
          return {
            content: [toTextBlock(summary)],
            structuredContent: structured,
          };
        } catch (err) {
          return errorResult("workflow_execute", err);
        }
      }
    );
  • Output schema (WorkflowExecuteOutputShape and WorkflowExecuteOutputSchema) defining the shape of the response: workflow_name, execution_id, sync, status, result, root_execution_id, start_time, end_time, total_duration_ms.
    export const WorkflowExecuteOutputShape = {
      workflow_name: z.string(),
      execution_id: z.string(),
      sync: z.boolean().describe("true when waitForResult=true (result is inline)."),
      status: z.string().nullable().optional(),
      result: z.unknown().nullable().optional(),
      root_execution_id: z.string().optional(),
      start_time: z.string().optional(),
      end_time: z.string().nullable().optional(),
      total_duration_ms: z.number().nullable().optional(),
    };
    export const WorkflowExecuteOutputSchema = z.object(WorkflowExecuteOutputShape);
  • Helper function errorResult used by the workflow_execute handler to format error responses (line 178 in tools-workflows.ts).
    export function errorResult(tool: string, err: unknown) {
      const message = err instanceof Error ? err.message : String(err);
      return {
        content: [toTextBlock(`[mistral-mcp:${tool}] ${message}`)],
        isError: true as const,
      };
    }
  • src/index.ts:82-83 (registration)
    Top-level invocation where registerWorkflowTools is called in the main server setup, making workflow_execute available in every profile.
    // workflow tools are present in every profile
    registerWorkflowTools(server, mistral);
Behavior5/5

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

Annotations indicate readOnlyHint=false, destructiveHint=false, idempotentHint=false, which aligns with execution being non-idempotent. Description adds details on blocking behavior, timeout, and polling, providing behavioral context beyond annotations.

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?

Concise with front-loaded purpose. Uses bullet-like structure for modes. Every sentence adds value without redundancy.

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

Completeness5/5

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

Given 6 parameters, nested objects, and presence of output schema, description covers all necessary aspects: modes, defaults, optional features. No gaps.

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

Parameters5/5

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

Input schema has 100% coverage with descriptions. Description adds extra meaning: explains workflowIdentifier source (mistral://workflows), describes default values for waitForResult and timeoutSeconds, and clarifies deploymentName usage.

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?

Description clearly states 'Start a Mistral Workflow execution.' It specifies the action (execute) and resource (Mistral Workflow), and distinguishes from sibling tools like workflow_status and workflow_interact which handle different operations.

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

Usage Guidelines5/5

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

Explicitly describes two usage modes (waitForResult=false vs true), advises polling with workflow_status for async case, and explains targeting specific deployments with deploymentName. Provides clear when-to-use guidance.

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/Swih/mistral-mcp'

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