> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.simplified.com/skills/platform-operators/simplified-workflows/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.simplified.com/_mcp/server. # Simplified Workflows **Skill ID:** `simplified-workflows` · [Install skills](/skills/install) · [Canonical source](https://github.com/celeryhq/simplified-ai/tree/main/skills/simplified-workflows) ## Try it > Build a workflow for this repeatable process, without running it yet. The instructions below describe the workflow. Installed skills and connected tools are separate; use only operations exposed by your authorized connection. A workflow definition is a reusable graph of steps; it becomes runnable when published. Choose each step from the live action catalog— blocks include — AI text and image generation, video and audio editing, PDF tools, HTTP calls, Slack and email, project tasks, and control flow. A run executes that graph once against a set of inputs. ## Connection and scope Workflow tools (`flows_*`), agent tools, and `smp_callApi` belong to the automation connector at `https://apikit.simplified.com/automation/mcp` in the current multi-profile layout. The plugin’s root `https://apikit.simplified.com/mcp` connection serves public content/project/social tools and does not automatically grant automation tools. Verify exposed capabilities first; connect the automation surface if missing. A full connector, when explicitly configured, also serves these tools. Resolve named or uncertain workspace/teamspace context with `simplified-workspace` on the public/full connection and carry the resolved numeric `space_id` on every workflow tool and passthrough call. Scope is stateless. Workflow resources have no `space_id` argument: use `flows_getWorkflow(workflow_id=..., expand="extra", space_id=...)` for a scoped diagram, and scoped `flows_listWorkflowActions` calls for live action schemas. The static grammar/run-control resources are safe to use independently of teamspace selection. ## Read the reference before writing a graph The connector ships its reference material as **MCP resources**. They are not in context — read them with your client's resource tool. | Task | Read first | | ------------------------------- | ------------------------------------------------------ | | Build or edit a workflow | `workflow://diagram-grammar` | | Run, poll, or control a run | `workflow://run-control` | | Choose a step | `workflow://actions`, then `workflow://actions/{slug}` | | Copy a working workflow's shape | `workflow://workflows/{id}/diagram` | **Do not write a step graph without reading `workflow://diagram-grammar`.** The block-id convention, the connection handle format, and the rule that declaring an input takes two separate places are not inferable from the tool schemas. Guessing yields a workflow that publishes cleanly and then behaves wrongly. If the client cannot read MCP resources, use an available authoritative local copy of the connector’s grammar/run-control references and the current tool descriptions. Do not guess a graph from schema fields alone. If no grammar reference can be accessed, explain that limitation and finish discovery or run-status work that does not depend on graph authoring. The connector also offers a `build_workflow` prompt if the client surfaces prompts. Its request to wait before building should be interpreted against the user’s existing authorization: do not add another approval gate when the user has already requested that construction and scope. ## Running an existing workflow This is the common case. Prefer it over building something new. 1. `flows_listWorkflows` with `search` — find it and read its `inputs` schema. That schema is the only statement of what the run accepts. 2. Read its diagram and resolve the requested inputs and effects before starting. `flows_startWorkflow(workflow_id=, input=, space_id=...)` returns immediately; its `workflow_id` response field is the run UUID. Pass `input: {}` for a workflow with no inputs, and never inject a `context` key. Use a stable `idempotency_key` when retrying an uncertain start so it cannot create a second run. 3. `flows_getWorkflowRunStatus` — poll until the status is `COMPLETED`, `FAILED`, `TERMINATED` or `TIMED_OUT`. Runs take minutes and can take hours; poll at a sensible interval. 4. `flows_getWorkflowRun` — only when you need the task-by-task breakdown of a finished run. If a run stalls at `RUNNING` with a task in progress, it may be waiting on a human-approval step. `workflow://run-control` covers resolving one. ## Building a new workflow ``` flows_listWorkflowActions find each action with search, read its current schema flows_createWorkflow an empty DRAFT flows_updateWorkflow write the step graph flows_publishWorkflow compile it; now runnable ``` The grammar’s worked example demonstrates shape; discover current action/provider/model choices and output paths rather than assuming its illustrative AI settings remain available. When a test run is within the user’s authorized scope, run it once with realistic input and check the output. A request to build/publish alone does not authorize sending notifications, publishing content, or spending credits for an unsolicited test. Finish and report the saved/published workflow before seeking any missing run authorization. Authoring details that repeatedly cost time: * **Publish compiles and validates the executable graph.** Inspect a 400 from save or publish; the current update schema also documents validation errors. Read the offending block message rather than retrying blindly. * **`extra` is replaced wholesale.** Read the existing definition before editing and send the complete merged `extra` including inputs, diagram, and unrelated fields. Author `extra.diagram`; publish rebuilds `extra.conductor`. Omit an explicit publish `version` unless the user intends to overwrite version history. * **Edits are not live until republished.** A changed graph does not affect new runs until `flows_publishWorkflow` runs again. ## Tell the user the plan first A workflow run has real, often external, effects: it sends email, posts to social accounts, publishes content, and spends workspace credits. Each action's `consumes_credits` flag says whether that step bills. * Do not start a run to find out what a workflow does. Read its diagram. * Explain the concrete steps, inputs, credit use, and external destinations. Proceed with construction and runs already authorized by the user; ask only for missing authorization or unresolved consequential scope. Never add a routine confirmation gate for requested reversible authoring. * `flows_deleteWorkflow` and `flows_terminateWorkflowRun` are permanent. * Clean up only definitions clearly created as temporary tests. Preserve requested deliverables and their run history; verify the exact target before deletion. ## Gotchas * **`flows_startWorkflow` returns the RUN id in a field named `workflow_id`.** A UUID there is a run; a small integer is a workflow definition. Run-control calls take `run_id`; the approval endpoint also takes the run UUID despite using `/run/…` in its path. * **`flows_listWorkflows` does not list drafts.** Use `flows_getWorkflow` for one you just created, with `expand=extra` to see its graph. * **`flows_listWorkflowActions` caps `page_size` at 100** regardless of what you ask for, and returns 503 intermittently. Pass `search`; retry a 503. * **Some required action fields list no valid values.** They draw them from a live endpoint — the action's `uiSchema` marks these `selectAsync` and names the URL. Fetch it and choose from the result; a made-up value is accepted and then misbehaves. `workflow://diagram-grammar` has the procedure. * **resume, retry and restart are three different things.** Resume continues a paused run; retry recovers a `FAILED` run from its failed task. Restart reuses the same run UUID and input from the beginning and repeats effects and credits. After correcting and publishing a definition, pass `useLatestDefinitions: true` to restart against the fix; its default is false. To correct input, start a new run with corrected `input` rather than restarting the old input. * **Approval input naming differs from output.** Read `reference_task_name` from status with `expand: "tasks"`, then pass its value as `task_reference_name` to `flows_approveWorkflowTask`, with `run_id` and `status: "COMPLETED"` or `"FAILED"`. Release only a gate the user has authorized you to resolve. * **Paused runs and review gates need action.** Do not endlessly poll a run intentionally paused or waiting for human input; report the required action and continue only within authorized scope. Bound retries of transient action-list 503s (for example three attempts), keeping `page_size` at most 100. ## When a result looks wrong Check a distinguishing field rather than the status code alone. A response can arrive successfully and still be the wrong thing — an empty `inputs` schema, for example, means either that the workflow genuinely takes no inputs *or* that its definition is broken, and the two look identical. If something surprising comes back, confirm what actually answered before concluding the workflow is at fault. ## Reaching past the tools `smp_callApi` takes `method`, a relative API `path`, optional `service` (`api` or `agents`), `query`, `body`, and `space_id`. Never pass a full URL or credentials. It returns `{status, body}`; inspect the status and parse the body before trusting results. Use `query` for selectAsync choices parameters rather than guessing values. Prefer a real tool wherever one exists — the passthrough has no field documentation and no validation. It is for the long tail: the choices endpoint behind a `selectAsync` field, or anything the tool set does not cover. > Use this Simplified skill from a compatible connected assistant.