Skip to main content
Glama
debugg-ai

Debugg AI MCP

Official
by debugg-ai

Search Workflow Executions

search_executions

Retrieve workflow execution details by UUID for full records or filter by status and project for paginated summaries, including outcomes, durations, timestamps, and node executions.

Instructions

Search or look up workflow executions (history of check_app_in_browser, trigger_crawl, and other workflow runs).

Two modes:

  • uuid mode: {"uuid": ""} → single execution with FULL detail including nodeExecutions, state, errorInfo. NotFound if the uuid doesn't exist.

  • filter mode: {"status": "completed"|"running"|"failed"|"cancelled", "projectUuid": "...", "page", "pageSize"} → paginated summaries.

Response shape: {filter, pageInfo, executions[]}. Summary items have outcome/status/durationMs/timestamps; uuid-mode items additionally have nodeExecutions + state + errorInfo.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
uuidNoExecution UUID. Returns single execution with full detail. Mutually exclusive with projectUuid/status filters.
projectUuidNoFilter by project UUID.
statusNoFilter by status: completed | running | failed | cancelled | pending.
pageNoPage number (1-indexed).
pageSizeNoPage size (1..200). Default 20.

Implementation Reference

  • Main handler function for the search_executions tool. Handles two modes: uuid mode (get full execution detail) and filter mode (paginated list). Calls DebuggAIServerClient to fetch execution data, optionally embeds screenshots/GIFs as image content blocks.
    export async function searchExecutionsHandler(
      input: SearchExecutionsInput,
      _context: ToolContext,
    ): Promise<ToolResponse> {
      const start = Date.now();
      logger.toolStart('search_executions', input);
    
      try {
        const client = new DebuggAIServerClient(config.api.key);
        await client.init();
    
        if (input.uuid) {
          try {
            const execution = await client.workflows!.getExecution(input.uuid);
            const payload = {
              filter: { uuid: input.uuid },
              pageInfo: { page: 1, pageSize: 1, totalCount: 1, totalPages: 1, hasMore: false },
              executions: [execution],
            };
            logger.toolComplete('search_executions', Date.now() - start);
    
            const content: ToolResponse['content'] = [
              { type: 'text', text: JSON.stringify(payload, null, 2) },
            ];
    
            const SCREENSHOT_URL_KEYS = ['finalScreenshot', 'screenshot', 'screenshotUrl', 'screenshotUri'];
            const GIF_KEYS = ['runGif', 'gifUrl', 'gif', 'videoUrl', 'recordingUrl'];
            const nodes: any[] = execution.nodeExecutions ?? [];
            const subworkflowNode = nodes.find((n: any) => n.nodeType === 'subworkflow.run');
    
            let screenshotEmbedded = false;
            let screenshotUrl: string | null = null;
            let gifUrl: string | null = null;
    
            const screenshotB64 = subworkflowNode?.outputData?.screenshotB64;
            if (typeof screenshotB64 === 'string' && screenshotB64) {
              content.push(imageContentBlock(screenshotB64, 'image/png'));
              screenshotEmbedded = true;
            }
    
            for (const node of nodes) {
              const data = node.outputData ?? {};
              if (!screenshotEmbedded && !screenshotUrl) {
                for (const key of SCREENSHOT_URL_KEYS) {
                  if (typeof data[key] === 'string' && data[key]) {
                    screenshotUrl = data[key] as string;
                    break;
                  }
                }
              }
              if (!gifUrl) {
                for (const key of GIF_KEYS) {
                  if (typeof data[key] === 'string' && data[key]) {
                    gifUrl = data[key] as string;
                    break;
                  }
                }
              }
              if ((screenshotEmbedded || screenshotUrl) && gifUrl) break;
            }
    
            if (!screenshotEmbedded && screenshotUrl) {
              const img = await fetchImageAsBase64(screenshotUrl).catch(() => null);
              if (img) content.push(imageContentBlock(img.data, img.mimeType));
            }
            if (gifUrl) {
              const gif = await fetchImageAsBase64(gifUrl).catch(() => null);
              if (gif) content.push(imageContentBlock(gif.data, 'image/gif'));
            }
    
            return { content };
          } catch (err: any) {
            if (err?.statusCode === 404 || err?.response?.status === 404) return notFound(input.uuid);
            throw err;
          }
        }
    
        const pagination = toPaginationParams({ page: input.page, pageSize: input.pageSize });
        const { pageInfo, executions } = await client.workflows!.listExecutions({
          status: input.status,
          projectId: input.projectUuid,
          page: pagination.page,
          pageSize: pagination.pageSize,
        });
    
        const payload = {
          filter: {
            status: input.status ?? null,
            projectUuid: input.projectUuid ?? null,
          },
          pageInfo,
          executions,
        };
        logger.toolComplete('search_executions', Date.now() - start);
        return { content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }] };
      } catch (error) {
        logger.toolError('search_executions', error as Error, Date.now() - start);
        throw handleExternalServiceError(error, 'DebuggAI', 'search_executions');
      }
    }
  • Zod schema (SearchExecutionsInputSchema) defining input validation: uuid (optional UUID), projectUuid, status, page, pageSize. Refine rule prevents combining uuid with filter params. Also exports SearchExecutionsInput type.
    export const SearchExecutionsInputSchema = z.object({
      uuid: z.string().uuid().optional(),
      projectUuid: z.string().uuid().optional(),
      status: z.string().min(1).optional(),
      page: z.number().int().min(1).optional(),
      pageSize: z.number().int().min(1).optional(),
    }).strict().refine(
      (v) => !(v.uuid && (v.projectUuid || v.status)),
      { message: 'Cannot combine uuid with filter params (projectUuid, status).' },
    );
  • buildSearchExecutionsTool() defines the MCP Tool object with name 'search_executions', description, and inputSchema. buildValidatedSearchExecutionsTool() wraps it with Zod schema and handler reference.
    export function buildSearchExecutionsTool(): Tool {
      return {
        name: 'search_executions',
        title: 'Search Workflow Executions',
        description: DESCRIPTION,
        inputSchema: {
          type: 'object',
          properties: {
            uuid: { type: 'string', description: 'Execution UUID. Returns single execution with full detail. Mutually exclusive with projectUuid/status filters.' },
            projectUuid: { type: 'string', description: 'Filter by project UUID.' },
            status: { type: 'string', description: 'Filter by status: completed | running | failed | cancelled | pending.' },
            page: { type: 'number', description: 'Page number (1-indexed).' },
            pageSize: { type: 'number', description: 'Page size (1..200). Default 20.' },
          },
          additionalProperties: false,
        },
      };
    }
    
    export function buildValidatedSearchExecutionsTool(): ValidatedTool {
      const tool = buildSearchExecutionsTool();
      return { ...tool, inputSchema: SearchExecutionsInputSchema, handler: searchExecutionsHandler };
    }
  • tools/index.ts:55-59 (registration)
    Tool registration in the central registry. On line 36, buildSearchExecutionsTool() is added to the tools array, and on line 50, buildValidatedSearchExecutionsTool() is added to validated tools. The tool is stored in toolRegistry map by name.
      _validatedTools = validated;
    
      toolRegistry.clear();
      for (const v of validated) toolRegistry.set(v.name, v);
    }
  • Re-exports the searchExecutionsHandler for convenience via the handlers barrel export.
    export * from './searchExecutionsHandler.js';
Behavior4/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 uuid mode returns full detail with nodeExecutions, state, errorInfo, and that missing uuid leads to NotFound. Filter mode returns paginated summaries. It does not mention side effects (expected none) or authorization, but for a search tool this is adequate.

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 concise yet complete, with clear structure using paragraphs and bullet points. It front-loads the purpose and then explains modes. Every sentence adds value.

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 no output schema and no annotations, the description provides good context on behavioral differences and response shapes for both modes. It could mention default ordering or any limits on page size, but it is sufficiently complete for typical usage.

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

Parameters3/5

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

Schema coverage is 100%, so parameters are already documented. The description adds the mode distinction and explains mutual exclusivity of uuid vs projectUuid/status. However, it does not add much beyond the schema for individual parameters (e.g., default page size is already in schema).

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 tool searches workflow executions, and distinguishes from siblings like search_projects or search_environments by focusing on execution history of workflows like check_app_in_browser and trigger_crawl. It specifies two modes (uuid and filter) which further clarifies purpose.

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 explains when to use uuid mode vs filter mode, and that they are mutually exclusive. It also describes the response shape. However, it does not explicitly mention when NOT to use this tool or compare it to alternative sibling tools like search_projects. Still, the context is clear enough for most agents.

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/debugg-ai/debugg-ai-mcp'

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