|
| 1 | +--- |
| 2 | +name: build-sim-workflow |
| 3 | +description: Build, test, deploy, run, and debug a Sim workflow through the Sim MCP tools. Use when the user asks to create or change a Sim workflow, wire blocks or integrations into one, run or deploy it, find out why a run failed, or resume a run waiting for approval. |
| 4 | +--- |
| 5 | + |
| 6 | +# Build a Sim workflow |
| 7 | + |
| 8 | +Work through the Sim MCP server's four tools: `search_operations`, `describe_operation`, `call_read_operation`, and `call_write_operation`. Every call names an `operation` and fills `params` (path), `query`, and `body`. |
| 9 | + |
| 10 | +Never write a request from memory. Before the first call to any operation, run `describe_operation` and build the request from the schema it returns. Schemas change; the descriptions also state access rules and edge cases. |
| 11 | + |
| 12 | +If a call returns `403` asking for a personal key or OAuth, tell the user: workspace API keys cannot edit graphs, deploy, or run drafts. |
| 13 | + |
| 14 | +## Loop |
| 15 | + |
| 16 | +1. **Find the workspace.** `listWorkspaces` if the user did not name one. Catalog and create calls need `workspaceId`. |
| 17 | +2. **Discover blocks.** `listBlocks` with `search` (or `capability=trigger` for starters), then `getBlock` for each block you will place. Use its `inputSchema` and `operationInputSchema` field ids as `inputs` keys, its `operations` for the operation id, and its `outputs` for what later blocks can reference as `<blockname.field>`. Do not guess field ids. |
| 18 | +3. **Create or load the workflow.** `createWorkflow` returns the seeded Start block's id. For an existing workflow, read `getWorkflowState` first. |
| 19 | +4. **Declare inputs.** Set the Start block's `inputFormat` (an array of `{ name, type }`) with an `edit` operation. Runs pass `input` keyed by those names; blocks reference them as `<start.name>`. |
| 20 | +5. **Dry-run the edit.** `applyWorkflowOperations` with `query: { dryRun: true }`. Batch related edits; refer to new blocks by the `block_id` you chose. Ignore `previewBlockIds` for later requests. |
| 21 | +6. **Read the result before applying.** Fix and re-dry-run until clean: |
| 22 | + - `skipped`, `inputValidationErrors`: edits that did not take. |
| 23 | + - `lint.fieldIssues[].missingRequiredFields`: will fail at run time. |
| 24 | + - `lint.unresolvedReferences`: bad credentials, resources, tools, or `<block.output>` references. |
| 25 | + - `lint.orphanBlocks`, `lint.sources`, `lint.emptyOutgoingPorts`, `lint.invalidBranchPorts`: wiring problems. |
| 26 | + - `lint.manualRunIssue`: the builder's Run button would refuse the workflow. |
| 27 | + Lint never blocks a write, so it is your job to act on it. |
| 28 | +7. **Apply.** Same body without `dryRun`, with `atomic: true`. Use `mintedBlockIds` for every later reference to new blocks. Do not resubmit `deferred` edges. |
| 29 | +8. **Test the draft.** `executeWorkflow` with `run: { source: "manual" }` and sample `input`. Narrow with `run.entry` (a trigger, `useMockPayload`, or a block plus `sourceRunId`) and `run.stopAfterBlockId`. Check `status`; failures come back as `status: "failed"` with HTTP 200. |
| 30 | +9. **Debug a failure.** The synchronous response's `error.blockId` names the failing block. Otherwise call `getLog` with the `runId` and walk `traceSpans` (and `children`) for the span with `errorMessage`. Fix with an `edit`, dry-run, apply, then rerun from that block with `run.entry: { type: "block", blockId, sourceRunId }`. |
| 31 | +10. **Deploy only when the user asks.** `deployWorkflow`, then poll `getWorkflowDeployment` until `latestDeploymentAttempt.status` is `active` or `failed`. Do not retry a deploy that timed out without checking; each accepted deploy creates a version. |
| 32 | +11. **Run the deployment.** `executeWorkflow` without `run`. For long runs use `async: true` or `waitTimeoutSeconds`, then poll `getWorkflowRun` until `status` is terminal or `paused`. Send an `X-Run-Id` header and reuse it on retry; never retry with a new id. |
| 33 | +12. **Resume approvals.** A `paused` run lists `paused.points`. Show the user each human point's `inputFields`, get their answer, then `resumeWorkflow` with its `contextId` and `input`. Never approve on the user's behalf. |
| 34 | + |
| 35 | +## Rules |
| 36 | + |
| 37 | +- Confirm with the user before deploying, deleting blocks or workflows, or resuming a paused run. |
| 38 | +- Report lint findings you did not fix. |
| 39 | +- Edits change the draft only. Say so when the workflow is deployed and `needsRedeployment` becomes true. |
| 40 | +- Guide: https://docs.sim.ai/api-reference/build-and-run-workflows |
0 commit comments