Search Workflow Executions
search_executionsRetrieve 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
| Name | Required | Description | Default |
|---|---|---|---|
| uuid | No | Execution UUID. Returns single execution with full detail. Mutually exclusive with projectUuid/status filters. | |
| projectUuid | No | Filter by project UUID. | |
| status | No | Filter by status: completed | running | failed | cancelled | pending. | |
| page | No | Page number (1-indexed). | |
| pageSize | No | Page 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'); } } - types/index.ts:76-85 (schema)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).' }, ); - tools/searchExecutions.ts:13-35 (registration)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); } - handlers/index.ts:6-6 (helper)Re-exports the searchExecutionsHandler for convenience via the handlers barrel export.
export * from './searchExecutionsHandler.js';