Skip to content
Connect an agent
Workflows

edit_diagram

Changes diagram source with typed operations, on every kind, and checks the result. It is a workflow of the MCP server and the HTTP API, with the title "Edit diagram".

TL;DR

QuestionAnswer
What is it?A workflow: one call does the work of several tools and returns one combined answer.
What does it do?Changes diagram source with typed operations, on every kind, and checks the result.
What does it replace?rewriting the source by hand and the draw_diagram check.
How do I call it over HTTP?POST /v1/diagrams/edit
Does it change anything?No. It is read-only and idempotent, and it talks to nothing outside itself. It saves no file and returns its answer as data.
Which bounds apply?maxEditOperations, maxEditTextLength. See the bounds below.
Where do I read its schema as data?An MCP client gets the name, description, and JSON Schema of every tool from tools/list.

What it does

Workflow. Changes diagram source with typed operations, on every kind, and checks the result. Each op and its fields: rename (target, to: an id everywhere it is used, or a label), set (target, or from and to for an edge, or target "header"; option, value, null removes it), add_node (id, label, type, options; into a block or after a statement; statement for a whole line), remove (target, with its block and edges), add_edge (from, to, label, arrow, options), remove_edge (from, to, label), move (target, into: a block, or null for the top level), replace_text (find, replace, all). Untouched lines keep their comments and layout. Each op reports applied, or why not with a hint, and a failed one is skipped. svg "never" (the default) lays nothing out; auto or always draws as draw_diagram does, with viewUrl and saveCommand. Replaces rewriting the source by hand and the draw_diagram check.

Steps

OperationRunsWhat it does
parseonly when neededParse the source and return its errors, without laying it out or linting it.
outlineonly when neededDescribe a valid diagram as plain text.
validateonly when neededParse the source and lint it: every error, and the quality, icon, and group-type warnings.
renderonly when neededLay out and paint a valid diagram in one color scheme.

One call performs at most 4 operations.

Example call

The arguments of the call, as JSON:

json
{  "source": "flow \"Login\" direction=right\n# the sign-in path\nnode user person \"User\"\nnode api service \"Auth API\"\nnode db database \"Users DB\"\nuser -> api : \"POST /login\"\napi -> db : \"look up user\"",  "operations": [    {      "op": "rename",      "target": "api",      "to": "gateway"    },    {      "op": "set",      "target": "db",      "option": "icon",      "value": "simple:postgresql"    },    {      "op": "add_node",      "id": "cache",      "type": "database",      "label": "Session cache"    },    {      "op": "add_edge",      "from": "gateway",      "to": "cache",      "label": "store session"    }  ]}

The source argument, written out one line at a time:

Plotwork
flow "Login" direction=right# the sign-in pathnode user person "User"node api service "Auth API"node db database "Users DB"user -> api : "POST /login"api -> db : "look up user"

Prompts that lead to it

  • Rename the Auth API node to gateway and add a session cache it writes to.
  • Move the database into the data group and remove the old queue.

Arguments

FieldTypeRequiredDescription
sourcestringyesDiagram source; the first line is the header, such as flow "Title" (draw_diagram lists every kind). at least 1 character; at most 50000 characters.
operationsobject[]yesApplied in order.
operations[].op"rename" | "set" | "add_node" | "remove" | "add_edge" | "remove_edge" | "move" | "replace_text"yes
operations[].targetstringnoId, label, table.column, or "header". at most 2000 characters.
operations[].tostringnorename: the new name. Edges: the end. at most 2000 characters.
operations[].fromstringnoEdges: the start. at most 2000 characters.
operations[].optionstringnoat most 40 characters; pattern ^[a-z][A-Za-z0-9_-]*$.
operations[].valuestring | nullnoset: null removes the option.
operations[].idstringnoat most 2000 characters.
operations[].labelstringnoadd_edge on sankey: the amount. at most 2000 characters.
operations[].typestringnoadd_node: node type, or statement word (c4 person, tree dir). at most 2000 characters.
operations[].optionsobjectno
operations[].statementstringnoadd_node: the whole line, for a kind with no plain node statement. at most 2000 characters.
operations[].intostring | nullnoA block; null is the top level.
operations[].afterstringnoat most 2000 characters.
operations[].arrow"<-->" | "-->" | "<->" | "..>" | "->" | "--"no
operations[].findstringnoat most 2000 characters.
operations[].replacestringnoat most 2000 characters.
operations[].allbooleanno
svg"auto" | "always" | "never"nonever (the default) draws nothing; auto or always draws like draw_diagram. default "never".
themes"light" | "dark" | "both"nolight, dark, or both (the default): the light picture and the dark one a dark page needs. default "both".
settingsobjectnoThe repo's plotwork.config.json, if any. Schema: https://docs.plotwork.dev/schemas/plotwork.config.json (opens in a new tab).

Result

FieldTypeRequiredDescription
sourcestringyesThe edited source. Lines no operation touched are byte for byte as they were, comments included.
changedbooleanyes
resultsobject[]yesOne entry for each operation, in order.
results[].op"rename" | "set" | "add_node" | "remove" | "add_edge" | "remove_edge" | "move" | "replace_text"yes
results[].appliedbooleanyes
results[].linesinteger[]yesLines of the new source this operation wrote, or the lines it removed from.
results[].messagestringyes
results[].hintstring | nullyes
validbooleanyes
kindstring | nullyes
errorsDiagnostic[]yes
errors[].code"E100" | "E101" | "E110" | "E111" | "E120" | "E121" | "E122" | "E123" | "E124" | "E125" | "E130" | "E131" | "E132" | "E133" | "E134" | "E135" | "E136" | "E137" | "E138" | "E139" | "E140" | "W200" | "W201" | "W202" | "W203" | "W204" | "W205" | "W206" | "W207" | "W500" | "M100" | "M101" | "M102" | "M103" | "M104" | "M110" | "M200" | "M201" | "M202" | "M203" | "M204" | "M205" | "M206" | "M207" | "M208" | "M209" | "M210" | "M211" | "M212" | "M213" | "M214" | "M215" | "M216" | "M217" | "M218" | "E300" | "E301" | "E302" | "E303" | "E304" | "W300" | "W301" | "W302" | "W303" | "M120" | "M220" | "M221" | "M222" | "E340" | "E341" | "E342" | "E343" | "E344" | "E345" | "W320" | "W321" | "W322" | "W323" | "M240" | "M241" | "M242" | "E360" | "E361" | "E362" | "E363" | "E364" | "E365" | "E366" | "E367" | "W330" | "W331" | "W332" | "W333" | "W334" | "M250" | "M251" | "E400" | "E401" | "E402" | "E403" | "W350" | "W351" | "W352" | "W353" | "M270" | "M271" | "E420" | "E421" | "E422" | "E423" | "E424" | "W360" | "W361" | "W362" | "W363" | "W364" | "M180" | "M280" | "M281" | "M282" | "E320" | "E321" | "E322" | "E323" | "E324" | "E325" | "E326" | "E327" | "E328" | "E329" | "E330" | "W310" | "W311" | "W312" | "W313" | "W314" | "M130" | "M131" | "M132" | "M230" | "M231" | "M232" | "M233" | "M234" | "M235" | "M236" | "M237" | "M238" | "E380" | "E381" | "E382" | "E383" | "W340" | "W341" | "W342" | "W343" | "M260" | "I100" | "I101" | "I102" | "I103" | "I104" | "I105" | "I200" | "I201" | "I202" | "I203" | "I204" | "I206" | "R100" | "R101" | "R200" | "R201" | "R202" | "R203" | "R204" | "R205" | "R206" | "R207" | "S100" | "S200" | "S101" | "S102" | "S103" | "S104" | "S201" | "S202" | "S203"yesStable code to branch on; E-codes are errors, W-codes are warnings.
errors[].severity"error" | "warning"yesErrors stop rendering; warnings never do.
errors[].messagestringyesWhat is wrong, in one sentence.
errors[].lineintegeryes1-based line in the submitted source. minimum 1.
errors[].columnintegeryes1-based column in that line. minimum 1.
errors[].lengthintegeryesNumber of characters the problem covers. minimum 1.
errors[].hintstring | nullyesA concrete suggestion for fixing it, or null.
warningsDiagnostic[]yesQuality warnings; only when the result is drawn.
warnings[].code"E100" | "E101" | "E110" | "E111" | "E120" | "E121" | "E122" | "E123" | "E124" | "E125" | "E130" | "E131" | "E132" | "E133" | "E134" | "E135" | "E136" | "E137" | "E138" | "E139" | "E140" | "W200" | "W201" | "W202" | "W203" | "W204" | "W205" | "W206" | "W207" | "W500" | "M100" | "M101" | "M102" | "M103" | "M104" | "M110" | "M200" | "M201" | "M202" | "M203" | "M204" | "M205" | "M206" | "M207" | "M208" | "M209" | "M210" | "M211" | "M212" | "M213" | "M214" | "M215" | "M216" | "M217" | "M218" | "E300" | "E301" | "E302" | "E303" | "E304" | "W300" | "W301" | "W302" | "W303" | "M120" | "M220" | "M221" | "M222" | "E340" | "E341" | "E342" | "E343" | "E344" | "E345" | "W320" | "W321" | "W322" | "W323" | "M240" | "M241" | "M242" | "E360" | "E361" | "E362" | "E363" | "E364" | "E365" | "E366" | "E367" | "W330" | "W331" | "W332" | "W333" | "W334" | "M250" | "M251" | "E400" | "E401" | "E402" | "E403" | "W350" | "W351" | "W352" | "W353" | "M270" | "M271" | "E420" | "E421" | "E422" | "E423" | "E424" | "W360" | "W361" | "W362" | "W363" | "W364" | "M180" | "M280" | "M281" | "M282" | "E320" | "E321" | "E322" | "E323" | "E324" | "E325" | "E326" | "E327" | "E328" | "E329" | "E330" | "W310" | "W311" | "W312" | "W313" | "W314" | "M130" | "M131" | "M132" | "M230" | "M231" | "M232" | "M233" | "M234" | "M235" | "M236" | "M237" | "M238" | "E380" | "E381" | "E382" | "E383" | "W340" | "W341" | "W342" | "W343" | "M260" | "I100" | "I101" | "I102" | "I103" | "I104" | "I105" | "I200" | "I201" | "I202" | "I203" | "I204" | "I206" | "R100" | "R101" | "R200" | "R201" | "R202" | "R203" | "R204" | "R205" | "R206" | "R207" | "S100" | "S200" | "S101" | "S102" | "S103" | "S104" | "S201" | "S202" | "S203"yesStable code to branch on; E-codes are errors, W-codes are warnings.
warnings[].severity"error" | "warning"yesErrors stop rendering; warnings never do.
warnings[].messagestringyesWhat is wrong, in one sentence.
warnings[].lineintegeryes1-based line in the submitted source. minimum 1.
warnings[].columnintegeryes1-based column in that line. minimum 1.
warnings[].lengthintegeryesNumber of characters the problem covers. minimum 1.
warnings[].hintstring | nullyesA concrete suggestion for fixing it, or null.
summarystring | nullyes
outlinestring[]yes
outlineTruncatedbooleanyes
sizeSize | nullyes
rendersobject[]yes
renders[].theme"light" | "dark"yes
renders[].svgstringyes
renders[].sizeSizeyesNatural size of a rendered diagram in px.
renders[].size.widthintegeryesWidth in px. minimum 1.
renders[].size.heightintegeryesHeight in px. minimum 1.
picturesOmittedobjectnoPresent only when pictures were left out because the answer would have been too big for an AI client to read in one piece.
picturesOmitted.themes("light" | "dark")[]yesThe color schemes whose pictures were left out.
picturesOmitted.charactersintegeryesHow many characters the pictures left out came to.
picturesOmitted.limitintegeryesThe most characters one answer may hold before the pictures are left out.
picturesOmitted.whystringyesWhy they were left out, and what to do.
viewUrlstringnoA link that shows a valid diagram in a browser; give it to the person who wants to look. The source is in the part after #, never sent to a server, but anyone with the link can read it. Absent when too long; next says so.
svgUrlstringnoThe viewUrl with &download=svg: a person opens it to download the SVG. Not a file address for curl; use saveCommand. Absent when too long.
saveCommandstringnoRun in a shell to save the SVG into the repository: the CLI decodes the link locally, fetches nothing, and embeds the source. Set --out to the path; add --theme dark for dark. Absent when too long.
nextstringyes

Behavior hints

HintValue
readOnlyHinttrue
destructiveHintfalse
idempotentHinttrue
openWorldHintfalse

Bounds

A bound that is reached is reported in the result; nothing is cut silently.

BoundValueWhat it limits
maxEditOperations50Operations in one call.
maxEditTextLength2000Characters in one field of an operation, such as a statement, a find, or a replacement.

See also

DocWhy
Tool referenceEvery tool, with the workflows first
POST /v1/diagrams/editThe same operation over HTTP
Language referenceWhat the diagram source may contain
Writing diagrams with an agentThe loop in practice