flow_run
Runs a chain of HTTP requests sequentially, extracting data from each response to pass as variables to later steps using {{variable}}.
Instructions
Ejecuta una secuencia de requests en orden. Extrae variables de cada respuesta para usar en pasos siguientes con {{variable}}.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| steps | Yes | Pasos a ejecutar en orden | |
| stop_on_error | No | Detener al primer error (default: true) |
Implementation Reference
- src/tools/flow.ts:44-151 (handler)The main handler function for 'flow_run' tool. It iterates over steps, resolves URLs with flow variables, executes each request via http-client, extracts variables from responses using getByPath, caches them, and builds a results summary.
async (params) => { try { const stopOnError = params.stop_on_error ?? true const envVariables = await storage.getActiveVariables() const flowVariables: Record<string, string> = { ...envVariables } const results: Array<{ name: string status: number timing: number extracted: Record<string, string> call_id?: string error?: string }> = [] for (const step of params.steps) { try { const resolvedUrl = resolveUrl(step.url, flowVariables) const config: RequestConfig = { method: step.method, url: resolvedUrl, headers: step.headers, body: step.body, query: step.query, auth: step.auth, } const interpolated = interpolateRequest(config, flowVariables) const response: RequestResponse = await executeRequest(interpolated) const callId = makeCallId() await cache.save(callId, interpolated.method, interpolated.url, response) // Extract variables from response const extracted: Record<string, string> = {} if (step.extract) { for (const [varName, path] of Object.entries(step.extract)) { const value = getByPath(response, path) if (value !== undefined && value !== null) { extracted[varName] = String(value) flowVariables[varName] = String(value) } } } results.push({ name: step.name, status: response.status, timing: response.timing.total_ms, extracted, call_id: callId, }) } catch (error) { const message = error instanceof Error ? error.message : String(error) results.push({ name: step.name, status: 0, timing: 0, extracted: {}, error: message, }) if (stopOnError) break } } // Build output const allOk = results.every((r) => !r.error && r.status >= 200 && r.status < 400) const lines: string[] = [ `${allOk ? '✅ FLOW COMPLETO' : '❌ FLOW CON ERRORES'} — ${results.length}/${params.steps.length} pasos ejecutados`, '', ] for (let i = 0; i < results.length; i++) { const r = results[i] const icon = r.error ? '❌' : r.status >= 200 && r.status < 400 ? '✅' : '⚠️' lines.push(`${icon} Paso ${i + 1}: ${r.name}`) if (r.error) { lines.push(` Error: ${r.error}`) } else { lines.push(` Status: ${r.status} | Tiempo: ${r.timing}ms`) if (r.call_id) lines.push(` call_id: ${r.call_id}`) } if (Object.keys(r.extracted).length > 0) { const vars = Object.entries(r.extracted) .map(([k, v]) => `${k}=${v.length > 50 ? v.substring(0, 50) + '...' : v}`) .join(', ') lines.push(` Extraído: ${vars}`) } lines.push('') } return { content: [{ type: 'text' as const, text: lines.join('\n') }], isError: !allOk, } } catch (error) { const message = error instanceof Error ? error.message : String(error) return { content: [{ type: 'text' as const, text: `Error: ${message}` }], isError: true, } } }, ) - src/tools/flow.ts:13-27 (schema)FlowStepSchema - Zod schema defining each step: name, method, url, headers, body, query, auth, and extract (variables to extract from responses).
const FlowStepSchema = z.object({ name: z.string().describe('Nombre del paso (ej: "login", "crear-post")'), method: HttpMethodSchema.describe('HTTP method'), url: z.string().describe('URL del endpoint'), headers: z.record(z.string()).optional().describe('Headers HTTP'), body: z.any().optional().describe('Body del request'), query: z.record(z.string()).optional().describe('Query parameters'), auth: AuthSchema.optional().describe('Autenticación'), extract: z .record(z.string()) .optional() .describe( 'Variables a extraer de la respuesta para pasos siguientes. Key = nombre variable, value = path (ej: { "TOKEN": "body.token", "USER_ID": "body.data.id" })', ), }) - src/tools/flow.ts:37-43 (schema)Input schema for the flow_run tool: steps (array of FlowStepSchema) and stop_on_error (optional boolean).
{ steps: z.array(FlowStepSchema).describe('Pasos a ejecutar en orden'), stop_on_error: z .boolean() .optional() .describe('Detener al primer error (default: true)'), }, - src/tools/flow.ts:34-35 (registration)Registration of the tool named 'flow_run' via server.tool() call in registerFlowTool function.
server.tool( 'flow_run', - src/server.ts:67-67 (registration)Where registerFlowTool is invoked in the server setup to register flow_run.
registerFlowTool(server, storage, responseCache)