Workflow Builder Guide
This page is the instruction set for building a Stow Workflow. If you were directed here by a workflows_setup response, read the entire page before proceeding.
AI NOTICE (must follow): If you are an AI assistant reading this page, you MUST read every section before taking any action. Do not skim. A workflow saved with an incorrect step schema will fail silently at execution time.
What a Workflow Is
A workflow is an ordered list of steps saved against your Stow workspace. When an agent calls execute_workflow, Stow returns the step list and the agent executes each step in order.
The engine does not execute steps. The calling agent does. This means:
- Tool steps are direct MCP calls the agent fires verbatim
- Instruction steps are natural-language tasks the agent performs using its own reasoning
- LLM-heavy work (web research, summarization, analysis) works because the agent is the executor
- The value is reasoning amortization — plan once, replay without re-planning
Step Types
Every element in the steps array has a required type field: "tool" or "instruction".
Tool step
A verbatim MCP tool call. The agent fires mcp_tool with mcp_params exactly as stored — no inference required.
{
"step_index": 0,
"type": "tool",
"mcp_tool": "call_stow_tool",
"mcp_params": {
"slug": "gmail_list_emails",
"params": { "max_results": 10, "label_ids": ["INBOX"] }
},
"description": "Get the 10 most recent inbox emails"
}
Field rules:
mcp_tool— the MCP tool you called when verifying this step (almost alwayscall_stow_tool)mcp_params— the exact object you passed to that tool, stored verbatimdescription— optional but strongly recommended; one sentence stating what the step does
Instruction step
A task the agent executes using its own reasoning and available tools at runtime.
{
"step_index": 1,
"type": "instruction",
"description": "Summarize the emails and identify any that need urgent replies"
}
Field rules:
description— required; must be self-contained; another agent with no prior context must be able to follow it- Do not assume the executing agent has memory of prior conversation — be explicit about inputs, outputs, and intent
Step Schema (complete)
{
"step_index": 0,
"type": "tool | instruction",
"mcp_tool": "(tool steps only) string — e.g. call_stow_tool",
"mcp_params": "(tool steps only) object — exact params passed to mcp_tool",
"description": "(required for instruction; optional context for tool)"
}
step_index must be 0-based and sequential. The save_workflow endpoint validates structure but does not reorder steps.
How to Build a Workflow
Follow these phases in order. Do not skip or combine phases.
Phase 1 — Understand the goal
Ask the user to describe what the workflow should do. Clarify:
- Which services are involved (Gmail, Airtable, Slack, etc.)
- The full sequence of steps in order
- Whether any steps require LLM reasoning vs direct tool calls
Do not proceed until the full sequence is clear.
Phase 2 — Execute each step live
For every step the user describes, perform it and capture the definition:
For a tool step:
- Identify the right Stow tool. Call
explore_{service}if needed to get the full tool list and params. - Execute it using
call_stow_toolwith the appropriateslugandparams. - Show the result to the user and confirm it is correct.
- Record the step as:
{ "step_index": N, "type": "tool", "mcp_tool": "call_stow_tool", "mcp_params": { "slug": "...", "params": {...} }, "description": "..." }mcp_paramsmust be the exact object you passed — copy it verbatim from your call.
For an instruction step:
- Perform the task (web research, data transformation, summarization, etc.).
- Confirm the result with the user.
- Record the step as:
Write the description so any agent could execute it cold, without this conversation as context.{ "step_index": N, "type": "instruction", "description": "Clear one-sentence task description." }
Phase 3 — Confirm and save
Once all steps are verified:
- Summarize the full workflow: name, description, steps in order.
- Ask the user: "Would you like to save this as a workflow?"
- On confirmation, call
save_workflowwith the verified step definitions.
save_workflow — Required Fields
{
"name": "string — human-readable workflow name",
"description": "string — optional one-paragraph summary",
"service_ids": ["uuid", "uuid"],
"steps": [ ... ]
}
name— required; the engine auto-slugifies this for use withexecute_workflowservice_ids— UUIDs of the Stow services whose tools are used in tool steps; used for display in the dashboardsteps— required; array of step objects validated by the engine
The engine returns { id, slug, name, step_count } on success. The slug is what agents pass to execute_workflow.
execute_workflow — Runtime Behaviour
When an agent calls execute_workflow with a workflow slug, it receives:
{
"workflow": "slug",
"name": "Workflow Name",
"description": "...",
"steps": [ ... ]
}
The agent then executes each step in step_index order:
- Tool step: call
mcp_tool(e.g.call_stow_tool) withmcp_paramsexactly as returned - Instruction step: follow
descriptionusing own reasoning and available tools
The agent carries all results in its context window — inter-step data passing is natural.
Rules
- Only include steps you actually executed and verified in Phase 2. Do not invent params or fabricate results.
- For tool steps: store mcp_params verbatim. Do not summarise or simplify the params object.
- For instruction steps: write descriptions that stand alone. Do not reference "the previous step result" without specifying what it is.
- One action = one step. Do not combine a tool call and a summarisation into a single step.
- service_ids should be UUIDs from the services you actually called. Check with
list_available_servicesif unsure. - Do not save a workflow until the user confirms. Always summarise first and get explicit approval.
Common Mistakes
| Mistake | Consequence | Fix |
|---------|-------------|-----|
| Storing mcp_tool: "gmail_list_emails" instead of "call_stow_tool" | Agent at runtime does not know how to dispatch | Always record the MCP wrapper, not the inner slug |
| Instruction step with description like "process the results" | Ambiguous — executing agent has no context | Be explicit: "Read the Airtable records returned in step 0 and identify rows where Status = 'Pending'" |
| Combining two actions in one step | Harder to debug; partial failures are opaque | Split into two steps |
| Inventing params not used in the live test | Tool may fail or return unexpected results | Only save params that were actually accepted by the tool |
Example Workflow
Goal: Get recent Gmail inbox, summarise urgent items, write summary to Airtable.
{
"name": "Inbox Triage to Airtable",
"description": "Fetches the 10 most recent inbox emails, identifies urgent items, and writes a summary row to an Airtable table.",
"service_ids": ["<gmail-service-uuid>", "<airtable-service-uuid>"],
"steps": [
{
"step_index": 0,
"type": "tool",
"mcp_tool": "call_stow_tool",
"mcp_params": {
"slug": "gmail_list_emails",
"params": { "max_results": 10, "label_ids": ["INBOX"] }
},
"description": "Fetch the 10 most recent inbox emails"
},
{
"step_index": 1,
"type": "instruction",
"description": "Review the emails returned in step 0. Identify any that require urgent action (contain deadlines, requests for immediate response, or marked as high priority). Compose a single plain-text summary listing the sender, subject, and one-line reason for urgency for each qualifying email."
},
{
"step_index": 2,
"type": "tool",
"mcp_tool": "call_stow_tool",
"mcp_params": {
"slug": "airtable_create_record",
"params": {
"base_id": "appXXXXXXXXXXXXXX",
"table_name": "Inbox Summaries",
"fields": {
"Summary": "{{step_1_result}}",
"Date": "{{today}}"
}
}
},
"description": "Write the urgent-items summary from step 1 as a new row in the Airtable Inbox Summaries table"
}
]
}
Note on
{{step_1_result}}and{{today}}: These are illustrative placeholders. At runtime the executing agent substitutes them from its context — step 1's output is in the agent's context window when step 2 executes. The params stored in the workflow should reflect what was used in the live test run (Phase 2), which may use literal values or agent-resolved references.