Editing Workflows
Editing Methods
Via MCP Tools
Use the manage tool with edit action:
mcp__moira__manage({ action: "edit", workflowId: "my-workflow", changes: { // changes go here },});Via workflow-management-flow
Start the management workflow:
mcp__moira__start({ action: "prepare", workflowId: "workflow-management-flow", parentExecutionId: "none",});mcp__moira__start({ action: "execute", startAttemptId: "<Start attempt ID from prepare>" });Select “edit” when prompted for action.
Use workflow-management-flow for complex edits. It reviews the design before mutation, validates the resulting graph, and independently reviews the completed workflow.
Via the Workflow CLI
Repository authors can use the official moira-workflow CLI for file-backed edits. First confirm
which checkout supplies a globally linked command, especially when several Moira worktrees exist:
moira-workflow --versionThe output includes both the package version and exact source path. Long descriptions and complete variable schemas can be read from files, avoiding fragile shell quoting:
moira-workflow ./workflow.json set-description --file ./description.txtmoira-workflow ./workflow.json set-system-reminder --file ./reminder.txtmoira-workflow ./workflow.json set-tags research,verificationmoira-workflow ./workflow.json set-variable-schema result --file ./result-schema.jsonThe process view uses the same file-backed authoring surface. Set the complete block list from
JSON with set-progress (or grow it with add-block / edit-block), then give every node its
block with set-block — routing nodes included, since the derivation refuses an unowned node. Progress attachment is available on
user-notification and deprecated telegram-notification nodes; none and false clear the
corresponding optional fields.
moira-workflow ./workflow.json set-progress --file ./progress.jsonmoira-workflow ./workflow.json update implement --progress-node-id implementationmoira-workflow ./workflow.json update implement --progress-active-label "Implement {{unit}}/{{total}}"moira-workflow ./workflow.json update notify --progress-node-id review --attach-progress-image trueThe block contract has its own commands: own a node by a block, add or edit a block with its
description, label a connection that leaves a block, and explain a return with the cause of the
loop and the condition that ends it. Each write reports how many block-contract diagnostics
remain, so a flow is annotated iteratively until derive shows none; --no-version-bump keeps
the version while iterating.
moira-workflow ./workflow.json set-block route-plan-approval planmoira-workflow ./workflow.json add-block deliver "Deliver" "Hand the result over" --after executemoira-workflow ./workflow.json edit-block deliver --summary "Present the result"moira-workflow ./workflow.json set-label check-plan-approved true "plan approved"moira-workflow ./workflow.json set-label route-review false "review found defects" \ --cause "The independent review reported blocking findings." --exit "The review passes."moira-workflow ./workflow.json deriveThese commands persist schema fields; they do not derive the process or judge its meaning, and
they do not replace the final validate, derive, schema, behavioral scenarios, or independent
semantic review.
For a complete planned rewrite, sync preserves the destination identity and its catalog migration
aliases in previousSlugs. The catalog reader validates those aliases separately; only the
executable graph is passed to the engine validator. Aliases always come from the real destination,
not from a workspace copy. A metadata or graph validation failure leaves the destination unchanged.
The standalone validate command exits unsuccessfully for either class of error, so an agent or CI
script can use it as a real gate without weakening runtime/upload graph validation.
moira-workflow ./workspace/workflow.json sync ./workflows/production/flows/<flow>.jsonmoira-workflow ./workflows/production/flows/<flow>.json validateBefore reviewing or changing a large graph, print its complete deterministic control-flow schema:
moira-workflow ./workflows/production/flows/<flow>.json schemaThe schema names every real node and labelled connection, conditions, cycles, declared outputs and mappings, context references, normal start paths, explicit teleport-only regions, and disconnected components. When the workflow defines a process view, the same projection includes every ordered block, any legacy display edge still stored on it, and every node-to-block mapping. It is a read-only structural projection for agent or human reasoning; it does not run the workflow, interpret workflow-specific meaning, or claim that a structurally visible route is semantically correct.
How workflow-management-flow handles edits
For an edit, the management workflow loads the complete current workflow and records the edit requirements, analysis, plan, and review reports in its workspace. Their contents stay in files; the graph carries only small values that affect routing.
The initial choice also records whether server access is allowed. An explicit local-only or offline instruction is reused without asking again and prevents the edit path from downloading or comparing a server definition.
The same first step records the operating mode. In interactive mode every approval stays as it
is: design, plan, and result are confirmed by you. In autonomous mode the workflow routes around
those three approvals and delivers a single final report at the end instead. The agent reuses a
mode you already stated, infers an unambiguous one — including a run started as a child of an
already autonomous process — and asks once only when the mode is neither stated nor derivable.
Autonomy removes waiting for a person, not authority. Uploading still requires an explicit decision, and in autonomous mode an upload without prior authorization resolves to “no” instead of escalating to a non-standard method. Writing the edited definition back to its already resolved local target is the requested work of the run, so it needs no separate approval in either mode.
Before planning, the workflow decides whether to audit the whole source workflow against the known anti-pattern catalog. In interactive mode it asks, reports concrete existing findings, and asks which of them should join the edit scope. In autonomous mode the agent makes both choices itself from the requested change and the available evidence, and leaves the findings it did not take in the audit report. When the audit is skipped, the analysis remains limited to the requested change and its necessary dependencies.
The plan describes outcomes, affected contracts, invariants, acceptance criteria, evidence methods, and risks. Before it requires a validation or proof mechanism, it must identify the required state, a plausible wrong state, and an observation that reliably distinguishes them. An unprovable derived criterion is revised instead of being replaced with a surrogate signal. The plan does not prescribe an exhaustive file list, exact commands, pseudocode, or a fixed sequence of local edits unless an external contract requires them.
Create and edit use the same independent pre-mutation design review. Reviews record detailed
findings in a stable workspace file and return only pass, repair, or replan for routing.
repair is reserved for a confirmed defect owned by the reviewed artifact; an invalid criterion,
evidence model, requirement interpretation, plan, or process returns to its earliest contract owner.
After a real repair, the reviewer receives the bounded root class and changed knowledge. A repeated
same-root finding without stronger evidence and validation-only work both trigger reassessment rather
than another validation layer. Structural validation remains the responsibility of the node that
creates or changes the workflow and uses Moira’s official validator.
Change Types
Update Metadata
mcp__moira__manage({ action: "edit", workflowId: "my-workflow", changes: { metadata: { version: "2.0.0", description: "Updated description", }, },});Update Node Content
mcp__moira__manage({ action: "edit", workflowId: "my-workflow", changes: { updateNodes: [ { nodeId: "task-node", changes: { directive: "New directive text", completionCondition: "New condition", }, }, ], },});Add Nodes
mcp__moira__manage({ action: "edit", workflowId: "my-workflow", changes: { addNodes: [ { type: "agent-directive", id: "new-node", directive: "New task", completionCondition: "Task complete", connections: { success: "existing-node" }, }, ], },});Remove Nodes
mcp__moira__manage({ action: "edit", workflowId: "my-workflow", changes: { removeNodes: ["node-to-remove"], },});When removing nodes, update connections in other nodes that referenced the removed node.
Safe Editing Process
-
Get current structure
mcp__moira__manage({action: "get-structure",workflowId: "my-workflow",}); -
Find nodes to edit
mcp__moira__manage({action: "search-nodes",workflowId: "my-workflow",query: "search term",}); -
Get node details
mcp__moira__manage({action: "get-node",workflowId: "my-workflow",nodeId: "node-id",}); -
Apply changes
mcp__moira__manage({action: "edit",workflowId: "my-workflow",changes: {/* ... */},}); -
Validate
mcp__moira__manage({action: "validate",workflowId: "my-workflow",});
Editing Without Extra Machinery
Make the change with the official MCP actions or the workflow CLI, and validate the real artifact before you finish. A one-off generator, a migration script, or an intermediate format written to make one edit becomes an undeclared dependency: the workflow then only round-trips correctly where that tool exists, and nothing in the definition says so. The workflow JSON is the artifact of record.
Reconciling Repository and Server Copies
A bundled workflow exists twice: as a file in the repository and as a catalog entry on the instance
that serves it. Before editing, resolve which identities refer to the same workflow — the public
owner/slug, the internal UUID, and any local path — and compare the two definitions rather than
assuming they match.
# Fetch the served definition through a one-time download tokenmcp__moira__token({ action: "download", workflowId: "moira/quick-task" })When the two differ, decide the baseline deliberately: which definition the requested change actually
targets, which is newer by metadata.version, and what each one would lose. Combining the two JSON
documents mechanically produces a graph neither side reviewed.
Changing a bundled workflow’s slug changes its catalog identity. To rename it without leaving the old
entry active after an upgrade, add the old slug to the catalog-only previousSlugs array. The loader
migrates that entry under the same owner and preserves its database ID; it fails if more than one
declared previous identity exists, rather than guessing or creating a duplicate. Do not use
previousSlugs to merge unrelated workflows.
Updating Connections
Single Connection Update
{ updateNodes: [ { nodeId: "source-node", changes: { connections: { success: "new-target-node", }, }, }, ];}Condition Node Connections
{ updateNodes: [ { nodeId: "condition-node", changes: { connections: { true: "when-true-node", false: "when-false-node", }, }, }, ];}Version Control
Increment Version
Always update version when making changes:
{ metadata: { version: "1.1.0"; // was 1.0.0 }}Version semantics:
- Major (2.0.0): Breaking changes, restructured flow
- Minor (1.1.0): New features, new nodes
- Patch (1.0.1): Bug fixes, text corrections
Compare Versions
mcp__moira__manage({ action: "diff", workflowId: "my-workflow", compareWorkflowId: "my-workflow-old",});Common Edits
Fix Typo in Directive
{ updateNodes: [ { nodeId: "task-node", changes: { directive: "Corrected directive text", }, }, ];}Add Required Field to InputSchema
{ updateNodes: [ { nodeId: "input-node", changes: { inputSchema: { type: "object", properties: { existing_field: { type: "string" }, new_field: { type: "string" }, // added }, required: ["existing_field", "new_field"], // updated }, }, }, ];}Insert Node in Flow
{ addNodes: [ { type: "agent-directive", id: "inserted-node", directive: "New step", connections: { success: "original-target" } } ], updateNodes: [ { nodeId: "original-source", changes: { connections: { success: "inserted-node" } } } ]}Validation Errors
Missing Connection Target
Error: Node 'task-1' connection target 'missing-node' not foundFix: Update connection to valid node ID.
Orphaned Node
Warning: Node 'orphan-node' is not reachable from startFix: Add connection from another node or remove orphaned node.
Invalid Node Type
Error: Unknown node type 'custom-type'Fix: Choose a built-in type from the Nodes reference. For a namespaced extension type, make sure its extension is installed. A validator without authoritative live registry data reports the type as unresolved; a live registry that does not contain it reports an error.
See Also
- Creating Workflows - Building new workflows
- MCP Tools - Tool reference