Skip to main content
Glama

card_workflow

Execute multi-step Adaptive Cards pipelines for Microsoft and third-party platforms. Process includes generation, validation, optimization, templating, and transformation in a single call.

Instructions

Execute a multi-step card pipeline in a single call. Steps: generate, validate, optimize, template, transform.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
stepsYesPipeline steps to execute in order
contentNoContent for generate step
dataNoData for generate/data_to_card step
hostNo
versionNo

Implementation Reference

  • The `handleCardWorkflow` function implements the logic for executing a series of card-related steps (generate, validate, optimize, template, transform).
    async function handleCardWorkflow(
      input: CardWorkflowInput,
    ): Promise<Record<string, unknown>> {
      const { steps, content, data, host = "generic", version = "1.6" } = input;
    
      // Validate step order: steps that need a card must come after generate
      const cardProducers = new Set(["generate"]);
      const cardConsumers = new Set(["validate", "optimize", "template", "transform"]);
      let hasCardProducer = false;
      for (const step of steps) {
        if (cardConsumers.has(step.tool) && !hasCardProducer) {
          throw new Error(
            `Step "${step.tool}" requires a card, but no "generate" step precedes it. ` +
            `Reorder steps so "generate" comes first.`,
          );
        }
        if (cardProducers.has(step.tool)) hasCardProducer = true;
      }
    
      let card: Record<string, unknown> | undefined;
      let validation;
      const stepsCompleted: string[] = [];
      let designNotes = "";
    
      for (const step of steps) {
        const params = step.params || {};
    
        switch (step.tool) {
          case "generate": {
            const genResult = await handleGenerateCard({
              content: (params.content as string) || content || "Create a card",
              data: (params.data || data) as Record<string, unknown> | string | undefined,
              host: (params.host as HostApp) || host as HostApp,
              intent: params.intent as any,
              version: (params.version as string) || version,
            });
            card = genResult.card;
            validation = genResult.validation;
            designNotes = genResult.designNotes;
            stepsCompleted.push("generate");
            break;
          }
          case "validate": {
            if (!card) throw new Error("No card to validate. Run 'generate' step first.");
            validation = handleValidateCard({
              card,
              host: (params.host as HostApp) || host as HostApp,
              strictMode: params.strictMode as boolean,
            });
            stepsCompleted.push("validate");
            break;
          }
          case "optimize": {
            if (!card) throw new Error("No card to optimize. Run 'generate' step first.");
            const optResult = handleOptimizeCard({
              card,
              goals: params.goals as any,
              host: (params.host as HostApp) || host as HostApp,
            });
            card = optResult.card;
            stepsCompleted.push("optimize");
            break;
          }
          case "template": {
            if (!card) throw new Error("No card to templatize. Run 'generate' step first.");
            const tplResult = handleTemplateCard({
              card,
              dataShape: params.dataShape as any,
            });
            card = tplResult.template;
            stepsCompleted.push("template");
            break;
          }
          case "transform": {
            if (!card) throw new Error("No card to transform. Run 'generate' step first.");
            const txResult = handleTransformCard({
              card,
              transform: (params.transform as any) || "apply-host-config",
              targetVersion: params.targetVersion as string,
              targetHost: (params.targetHost as HostApp) || host as HostApp,
            });
            card = txResult.card;
            stepsCompleted.push("transform");
            break;
          }
        }
      }
    
      if (!card) throw new Error("Workflow produced no card. Include a 'generate' step.");
    
      // Re-validate against the final card state (not an intermediate step)
      const lastStep = stepsCompleted[stepsCompleted.length - 1];
      if (lastStep !== "validate") {
        validation = handleValidateCard({ card, host: host as HostApp });
      }
    
      const cardId = storeCard(card, { tool: "card_workflow" });
    
      return {
        card,
        cardId,
        validation,
  • The `CardWorkflowInput` interface defines the input structure for the `card_workflow` tool, including the ordered steps to be executed.
    export interface CardWorkflowInput {
      steps: Array<{
        tool: "generate" | "validate" | "optimize" | "template" | "transform";
        params?: Record<string, unknown>;
      }>;
      content?: string;
      data?: Record<string, unknown> | string;
      host?: HostApp;
      version?: string;
    }
  • Registration of the `card_workflow` tool within the server request handler.
    case "card_workflow": {
      result = await handleCardWorkflow(parsed as unknown as CardWorkflowInput);

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/VikrantSingh01/adaptive-cards-mcp'

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