Search Workflow Executions
search_executionsRetrieve workflow execution records by UUID for full detail or filter by status, project, and pagination for summaries.
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 for the search_executions tool. Two modes: uuid mode (single execution with full detail + screenshot/GIF embedding) and filter mode (paginated list of executions). Uses DebuggAIServerClient to call the backend API.
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-86 (schema)Zod schema and TypeScript type for search_executions input. uuid is mutually exclusive with projectUuid/status. Supports optional page/pageSize for pagination.
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).' }, ); export type SearchExecutionsInput = z.infer<typeof SearchExecutionsInputSchema>; - tools/searchExecutions.ts:13-30 (registration)Builds the MCP Tool definition for search_executions with name, title, description, and raw JSON input schema.
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, }, }; } - tools/searchExecutions.ts:32-35 (registration)Wraps the tool definition with Zod validation schema and the handler function, creating a ValidatedTool.
export function buildValidatedSearchExecutionsTool(): ValidatedTool { const tool = buildSearchExecutionsTool(); return { ...tool, inputSchema: SearchExecutionsInputSchema, handler: searchExecutionsHandler }; } - tools/index.ts:57-85 (registration)Registration of search_executions in the central tool registry. buildValidatedSearchExecutionsTool() is called in initTools() and the resulting ValidatedTool is stored in toolRegistry keyed by name.
const validated: ValidatedTool[] = [ buildValidatedTestPageChangesTool(ctx), buildValidatedTriggerCrawlTool(ctx), buildValidatedProbePageTool(), buildValidatedSearchProjectsTool(), buildValidatedSearchEnvironmentsTool(), buildValidatedCreateEnvironmentTool(), buildValidatedUpdateEnvironmentTool(), buildValidatedDeleteEnvironmentTool(), buildValidatedUpdateProjectTool(), buildValidatedDeleteProjectTool(), buildValidatedSearchExecutionsTool(), buildValidatedCreateProjectTool(), buildValidatedCreateTestSuiteTool(), buildValidatedSearchTestSuitesTool(), buildValidatedDeleteTestSuiteTool(), buildValidatedCreateTestCaseTool(), buildValidatedUpdateTestCaseTool(), buildValidatedDeleteTestCaseTool(), buildValidatedRunTestSuiteTool(), buildValidatedGetTestSuiteResultsTool(), ]; _tools = tools; _validatedTools = validated; toolRegistry.clear(); for (const v of validated) toolRegistry.set(v.name, v); }