yax_run_secure_workflow
Execute agent actions like emails, API calls, or on-chain transactions with policy enforcement and TEE attestation, returning a signed receipt anchored to Filecoin.
Instructions
Runs any agent action — email, API call, on-chain tx, or workflow — with policy enforcement and TEE attestation. Returns a run ID, policy decision, and signed Filecoin-anchored receipt.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| intent | Yes | Human-readable description of what the agent intends to do, e.g. 'Send invoice follow-up email to client ABC'. | |
| action_type | Yes | Action category: 'api_call', 'payment', 'email', 'on_chain', 'data_read', or 'workflow'. | |
| parameters | No | Action-specific parameters such as recipient address, amount, endpoint URL, or payload body. | |
| spend_cap_override | No | Optional per-call spend cap in USD. Must be less than or equal to the agent's configured policy cap. | |
| webhook_url | No | Optional https:// URL. When the run reaches a terminal state, the gateway POSTs the signed receipt to this URL with X-YAX-Signature: hmac-sha256=<hex>. Eliminates polling. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| run_id | No | Unique identifier for this run, e.g. run_7f29c91a. | |
| status | No | Run status: completed, denied, or pending_approval. | |
| policy | No | ShadeGuard policy result including decision, version, and guard status. | |
| tee_attestation | No | TEE attestation identifier for hardware-verified execution paths. | |
| proof | No | Filecoin CID and BTFS CID for permanent tamper-proof proof storage. | |
| receipt_signature | No | Cryptographic signature over the full receipt payload. | |
| anchored_at | No | ISO 8601 timestamp when the receipt was anchored. |
Implementation Reference
- sdk-ts/src/index.ts:194-196 (handler)The runSecureWorkflow method in the YieldAgentX402 class is the typed client-side handler that calls the 'yax_run_secure_workflow' MCP tool via the generic call() method, passing RunSecureWorkflowArgs and expecting RunSecureWorkflowResponse.
runSecureWorkflow(args: RunSecureWorkflowArgs): Promise<RunSecureWorkflowResponse> { return this.call<RunSecureWorkflowResponse>("yax_run_secure_workflow", args as unknown as Record<string, unknown>); } - sdk-ts/src/index.ts:194-196 (registration)The tool name 'yax_run_secure_workflow' is registered at line 195 where it's passed to this.call() as the tool name string. It is also referenced in the streaming variant at line 227 for SSE-based streaming.
runSecureWorkflow(args: RunSecureWorkflowArgs): Promise<RunSecureWorkflowResponse> { return this.call<RunSecureWorkflowResponse>("yax_run_secure_workflow", args as unknown as Record<string, unknown>); } - sdk-ts/src/types.ts:65-71 (schema)RunSecureWorkflowArgs interface defining the input schema: intent (string), action_type (enum of allowed types), parameters (optional Record), spend_cap_override (optional number), webhook_url (optional string).
export interface RunSecureWorkflowArgs { intent: string; action_type: "api_call" | "payment" | "email" | "on_chain" | "data_read" | "workflow"; parameters?: Record<string, unknown>; spend_cap_override?: number; webhook_url?: string; } - sdk-ts/src/types.ts:73-90 (schema)RunSecureWorkflowResponse interface defining the output schema: ok, run_id, status, workflow_id, policy, tee_attestation, proof, receipt_signature, anchored_at, and optional webhook details.
export interface RunSecureWorkflowResponse { ok: boolean; run_id: string | null; status: RunStatus; workflow_id: string; policy?: PolicyDecision; tee_attestation?: string | null; proof?: Proof | null; receipt_signature?: string | null; anchored_at?: string | null; webhook?: { registered: boolean; url: string; delivery: string; verify_with: string; retry_policy: string; } | null; } - sdk-ts/src/index.ts:216-283 (helper)streamSecureWorkflow is an async generator that provides SSE-based streaming progress events for the 'yax_run_secure_workflow' tool, yielding progress updates, final results, or errors.
async *streamSecureWorkflow(args: RunSecureWorkflowArgs): AsyncGenerator< | { type: "progress"; stage: string; run_id?: string; filecoin_cid?: string | null; tee_attestation?: string | null; workflow_id?: string; timestamp: string } | { type: "result"; result: RunSecureWorkflowResponse } | { type: "error"; code: number | string; message: string }, void, unknown > { const body: JsonRpcEnvelope = { jsonrpc: "2.0", id: ++this._id, method: "tools/call", params: { name: "yax_run_secure_workflow", arguments: args as unknown as Record<string, unknown> }, }; const headers: Record<string, string> = { "Content-Type": "application/json", "Accept": "text/event-stream", }; if (this.apiKey) headers["Authorization"] = `Bearer ${this.apiKey}`; if (this.agentId) headers["X-Agent-ID"] = this.agentId; const res = await fetch(this.endpoint, { ...this._fetchInit, method: "POST", headers, body: JSON.stringify(body), }); if (!res.ok || !res.body) { yield { type: "error", code: res.status, message: `HTTP ${res.status}` }; return; } const reader = res.body.getReader(); const decoder = new TextDecoder(); let buf = ""; let currentEvent = "message"; try { while (true) { const { value, done } = await reader.read(); if (done) break; buf += decoder.decode(value, { stream: true }); let idx: number; // Process complete SSE frames separated by double newline. while ((idx = buf.indexOf("\n\n")) !== -1) { const frame = buf.slice(0, idx); buf = buf.slice(idx + 2); let dataLine = ""; currentEvent = "message"; for (const line of frame.split("\n")) { if (line.startsWith("event:")) currentEvent = line.slice(6).trim(); else if (line.startsWith("data:")) dataLine += line.slice(5).trim(); } if (!dataLine) continue; let payload: any; try { payload = JSON.parse(dataLine); } catch { continue; } if (currentEvent === "progress" && payload?.params) { yield { type: "progress", ...payload.params }; } else if (payload?.result) { const inner = payload.result?.structuredContent ?? (() => { try { return JSON.parse(payload.result?.content?.[0]?.text || "{}"); } catch { return null; } })(); if (inner) yield { type: "result", result: inner as RunSecureWorkflowResponse }; } else if (payload?.error) { yield { type: "error", code: payload.error.code, message: payload.error.message }; } } } } finally { reader.releaseLock(); } }