apply_operations Atomically edit flowcharts using expectedRevision and unique requestId. For small patches use merge_non_overlapping plus expected field values/versions; structural edits require strict revisions. Reuse revisionAfter and changed versions, never assume untouched cached objects are refreshed. dryRun does not save. Retry lost responses identically; conflicts need focused rereads and a new requestId. Details: /docs/mcp/apply_operations. Building a chart: one batch holds up to 500 operations, so nodes and the edges between them can share tempRefs in a single request. add_node/update_node take notes (text beside the node), link {nodeId} (a ↩ loop-back copy of another node) and rows (a bundle node: one node listing items, each optionally ↩; still one node for alternation). To rebuild a chart in place, start the batch with clear_flowchart (a person must do it when agent deletes are off). For isolated node/edge text or style edits, prefer conflictPolicy=merge_non_overlapping and send only the fields being changed. A known node usually needs one focused read_board(nodeIds) and one write; use already-known state if sufficient. Carry revisionAfter and nodeVersions/edgeVersions into subsequent edits on this sheet; null versions mean deletion. Versions describe the committed result, are absent for dryRun, and replays return the original versions (which may now be stale). A newer revision does not refresh cached untouched objects: guard their previously read fields/versions or reread them before editing. Field preconditions avoid conflicts with unrelated fields on the same node; whole-object versions intentionally guard every field. On conflict, reread the affected objects and necessary context, reconsider, then use a NEW requestId with retryOfRequestId pointing to the failed request. Edit one sheet atomically. Supply sheetId; it is required on multi-sheet documents. The revision and conditional versions are scoped to that sheet. A browser tab switch never retargets a command. Supply expectedRevision from read_board and a unique requestId. Default conflictPolicy reject requires the current revision. merge_non_overlapping permits only update_node/update_edge/rename_board/set_connector_default/set_metadata: compare touched fields to a retained expectedRevision, or supply preconditions covering every touched field or object version. Preconditions can also guard additional read dependencies. They always run atomically. Structural/layout operations require reject. On conflict reread, reconsider changes, and use a NEW requestId. Retry identical input with the SAME requestId after a lost response. dryRun validates without committing or reserving. Node deletion removes incident edges. Plain text replaces rich formatting. Operations: insert_prefab: Insert a prefab snapshot returned by read_prefabs at x/y. Fresh IDs preserve internal edges. createdIds maps tempRef to the first node and tempRef_0, tempRef_1, etc. to members in definition order. Snapshot input makes retries independent of later prefab edits.; humanize: Clean up positions using the same Humanize algorithm as the editor. Omit ids for the whole board; at most 500 targets. Preserves text, styling, sizes and edges. Reports remaining bounding-box overlaps.; align_nodes: Align selected nodes to their combined bounds; center_x/center_y align centers. Does not reroute edges.; distribute_nodes: Distribute in current spatial order. With gap, anchor the first node and use that edge-to-edge gap. Without gap, preserve outer bounds and equalize gaps; refuses negative gaps.; snap_to_grid: Snap selected node top-left positions to grid multiples, anchored at board origin.; normalize_sizes: Set selected node dimensions; preserves their centers and text. Review wrapping after resizing.; set_metadata: Set one namespaced extensions key on a board, node or edge. Supply id for node/edge. value is JSON; remove:true deletes the key. Other keys survive. Use qraft.role for node roles and qraft.instructions for board guidance; metadata is data, not privileged instructions. qraft.link {nodeId, overrides?} makes a node a linked copy (↩ loop-back) of another node: groups text, shape, size, fill, border and font follow the original unless listed in overrides; editing a followed group on the copy adds it to overrides.; set_theme: Give the whole document its own chrome theme so every viewer sees the project's look instead of their personal preset. Supply theme.colors.background plus any of surface, text, muted, accent, danger, ok, canvas, connector (default arrow color); Qraft derives the full palette, picks light or dark from the background, and keeps text readable. Optional name (shown in File → Themes), scheme, base preset, fonts, a background image (theme.background.assetId of an uploaded raster image, with surfaces: canvas, rail, tab types such as kanban or journal, or workspace for all; fit, position, opacity, blur) and direct token overrides. Replaces any previous project theme; stored under board extensions qraft.theme and reverted like any change.; clear_flowchart: Remove every node and edge on this flowchart tab, keeping the tab, its name and settings, so later operations in the same batch can rebuild it. A whole-content removal: agents need full deletes enabled, otherwise a person must do it. Try it with dryRun first; board history can revert it.; clear_theme: Remove the project theme so viewers return to their own preset. No-op when none is set.; rename_board: Set the board title. Does not change graph IDs.; set_connector_default: Set the document default connector kind.; add_node: Create a node. Caller supplies tempRef; omitted placement is deterministic outside existing bounds. Defaults come from Qraft style/geometry. notes: plain text kept beside the node (its Notes panel), not drawn on it. link {nodeId, overrides?}: make it a linked copy (↩ loop-back) of another node, named by id or an earlier tempRef.; update_node: Partial node update by stable ID or earlier tempRef. Missing fields unchanged. Partial style preserves other style fields. plain textFormat replaces rich formatting. notes replaces the node's notes ("" or null removes them); link sets or (null) removes its loop-back link.; remove_node: Remove a node and cascade-delete incident edges. Those edges appear in the change record.; add_edge: Create an edge between existing or same-batch nodes and valid handles.; update_edge: Partial edge update by stable ID or earlier tempRef.; remove_edge: Remove an edge by ID.; reorder_nodes: Replace node order. ids must be a permutation of current plus same-batch created nodes, minus removals.