# Writing diagrams with an agent

> Page: https://docs.plotwork.dev/mcp/agent-loop. Index of every page: https://docs.plotwork.dev/llms.txt

The loop an AI agent follows to produce a correct diagram: read the language once, write source, validate until clean, check the meaning, render. It is for people who connect an agent to the diagram tools, and for the prompt an agent reads.

## TL;DR

| Rule | Yes | No |
|---|---|---|
| Learn the language | Call `get_diagram_syntax` once, before the first diagram, and again with `kind` for the kind you draw | Guess node types from memory |
| Choose a kind | Unsure which kind fits? Call `suggest_diagram`; for a whole document, `plan_document_diagrams`. See [choosing a kind](#9-choosing-a-kind-and-planning-a-document) | Force every picture into a flow |
| Check | Call `validate_diagram` after every edit, until `valid` is true | Render first and hope |
| Fix | Use each error's `line`, `column`, and `hint` | Rewrite the whole diagram for one typo |
| Icons | Call `search_icons` with the product name from the request, and use the first result | Invent an icon name, or guess `amazon:s3` |
| Suggestions | Add the exact `icon=` or `type=` that `W204` or `W205` gives, or write `icon=none` | Ignore a suggestion without deciding |
| Colors | Choose a `type` or a `tone` | Ask for hex colors; they do not exist in the language |
| Meaning | Call `outline_diagram` and read it as the reader would | Assume the layout says what you meant |
| Starting point | For a common architecture, call `find_pattern` and adapt the checked diagram it returns. See [architecture patterns](https://docs.plotwork.dev/architecture-patterns.md) | Draw a three-tier network or a serverless API from nothing |
| Size | One idea per diagram, at most about 15 nodes, and one more for each group, up to 25 | One diagram for a whole system |
| Fewer calls | Prefer a workflow: `draw_diagram` checks, describes, and draws in one call. See [workflows](#8-workflows-one-call-instead-of-several) | Call `validate_diagram`, `outline_diagram`, and `render_diagram` one after another |
| Editing | To change a picture that already exists, call `read_diagram` with its link or its text, edit the source, and draw again with `embedSource` true. See [Editing an existing diagram](https://docs.plotwork.dev/editing-existing-diagrams.md) | Redraw it from the picture, or edit the SVG by hand |
| Mermaid already | Have Mermaid already? See [Migrating from Mermaid](https://docs.plotwork.dev/migrating-from-mermaid.md) | Retype a Mermaid diagram by hand |

## 1. The loop

**Diagram source**

```diagram
sequence "Agent authoring loop" desc="An agent reads the language, writes a diagram, validates it until it is clean, then renders it."

actor agent person   "Agent"
actor tools service  "Diagram tools"

agent -> tools : "get_diagram_syntax"
tools --> agent : "Node types, arrows, limits, examples"

loop "until valid is true" {
  agent -> tools : "validate_diagram"
  tools --> agent : "Errors with line, column, hint"
}

agent -> tools : "outline_diagram"
tools --> agent : "Plain-text description"
note over agent, tools : "The agent checks the outline against what it meant to draw"

agent -> tools : "render_diagram"
tools --> agent : "SVG and size"
```

*Picture: Agent authoring loop: 2 participants. An agent reads the language, writes a diagram, validates it until it is clean, then renders it.*

**Text description**

**Participants:**

- Agent, person
- Diagram tools, service

**Steps:**

- 1. Agent to Diagram tools: get_diagram_syntax
- 2. Diagram tools to Agent (dashed): Node types, arrows, limits, examples
- loop: until valid is true
  - 3. Agent to Diagram tools: validate_diagram
  - 4. Diagram tools to Agent (dashed): Errors with line, column, hint
- 5. Agent to Diagram tools: outline_diagram
- 6. Diagram tools to Agent (dashed): Plain-text description
- Note over Agent and Diagram tools: The agent checks the outline against what it meant to draw
- 7. Agent to Diagram tools: render_diagram
- 8. Diagram tools to Agent (dashed): SVG and size

## 2. Read the language

`get_diagram_syntax` returns the language as data, in two sizes so that an agent does not pay for kinds it does not draw. With no arguments it returns the overview: every node type with its default icon and tone, arrows, line options, tones, status icons, icon sets and providers, limits, how to edit an existing picture, one line about each kind, and the tested examples of the kinds those shared tables describe. Pass `kind` (for example `git` or `flow`) to get that kind in full: its statements, limits, and a tested example. `flow` also carries the group types with their frame, tone, and icon, the overlays, and a complete cloud architecture example. The error codes are in the [diagnostic codes](https://docs.plotwork.dev/reference/language/diagnostics.md) reference, because every diagnostic a tool returns already carries its code, line, column, and hint. It lists the icon sets but not every icon: it points to `search_icons`, which finds a product icon from its name. It never changes, so an agent reads the overview once per session, and a kind once.

## 3. Validate until clean

`validate_diagram` takes the source and returns every problem in one pass. A mistake is a normal result, not an exception, so the agent can loop.

Source with a misspelled type:

```plotwork
flow "T"
node a servce "A"
```

Each mistake has a code, a position, and a hint. Drawn with the offending line and a caret under the characters to change, it reads like this.

```text
error E120: Unknown node type "servce"
   2 | node a servce "A"
     |        ^^^^^^
hint: Did you mean "service"?
```

The agent changes `servce` to `service`, validates again, and gets `valid: true`. The tool returns the same facts as data:

| Field | Use |
|---|---|
| `valid` | `true` when the diagram can be rendered. Loop until it is. |
| `errors` | Every mistake: `code`, `message`, `line`, `column`, `length`, and `hint`. |
| `line`, `column`, `length` | The exact characters to change, counted inside the diagram source. The caret above is drawn from them. |
| `hint` | The suggested fix. For an unknown word it names the closest valid one. |
| `warnings` | Quality problems in a valid diagram: too dense, too wide, text cut, unconnected node. Fix them when the diagram is meant for a document. Two are suggestions, described below. |
| `summary` and `size` | Present once the diagram is valid. |

**The result as JSON**

```json
{
  "valid": false,
  "errors": [
    {
      "code": "E120",
      "message": "Unknown node type \"servce\"",
      "line": 2,
      "column": 8,
      "length": 6,
      "hint": "Did you mean \"service\"?"
    }
  ],
  "warnings": []
}
```

The full result also carries `kind` and `severity`, and `summary` and `size` as `null` until the diagram is valid.

### Icon and group-type suggestions

For an architecture diagram, `validate_diagram` also suggests the icon and the group type an author left out. Each suggestion is a warning with the exact text to add, so the fix is one edit and never a guess. Nothing is applied for you.

| Code | The warning says | The fix |
|---|---|---|
| `W204` | `Node "db" has no icon=, and its label names azure:cosmos-db` | Add `icon=azure:cosmos-db` to the node, or write `icon=none` to keep it plain. |
| `W205` | `Group "net" has no type=, and its name says subnet` | Add `type=subnet` to the group, or `type=subnet provider=aws` when the name also names a provider. |

The rules are fixed, so the same source gets the same suggestions every time. A label counts only as whole words, the longest phrase wins, and a label that fits two products or two types gets no suggestion. A generic phrase such as `SQL database` counts only inside a group, or a diagram, whose `provider=` owns that product, and a brand such as `Redis` counts only when it is the whole label. The [cloud architecture guide](https://docs.plotwork.dev/cloud-architecture.md) shows the full recipe.

## 4. Check the meaning

A valid diagram can still say the wrong thing: an arrow reversed, a node in the wrong group. `outline_diagram` returns the diagram as plain text, in reading order. Compare it to the intent. The one-line summary becomes the alt text of the picture, and the rest appears in the collapsed Text description, so it is also what a screen reader hears.

## 5. Render and place

`render_diagram` returns the SVG, its pixel size, and any warnings, in the `light` or `dark` theme. To put a diagram in a document, write it as a `diagram` fence in the Markdown file and call `sync_markdown` with the file; see [Diagrams in Markdown and on GitHub](https://docs.plotwork.dev/markdown-and-github.md).

## 6. Habits that produce good diagrams

| Habit | Yes | No |
|---|---|---|
| Labels | `Auth API`, `Token exchange` | `The service that handles authentication requests` |
| Detail | Put it in `sub="OAuth 2.1"` or a note | Put it in the label |
| Types | `database` for a database, `gateway` for a gateway | `step` for everything |
| Boundaries | A `group` with `type=trust-boundary` or `type=network`, a dashed frame | A text label that says "inside the VPC" |
| Cloud products | `icon=aws:lambda` found with `search_icons`, one node per service | A generic box labeled `Lambda`, or one node per instance |
| Outcomes | A `terminal` with `icon=status:success` or `status:denied` | A green node chosen by hand |
| Splitting | Two diagrams joined by a sentence | Fifteen nodes plus a legend |

## 7. Ways to call the tools

| Surface | How |
|---|---|
| MCP over stdio | `npx -y @buun_group/plotwork-mcp@0.1.0`, started by your client, with no key. See [Connecting an agent](https://docs.plotwork.dev/mcp/connect.md). |
| MCP over HTTP | `https://mcp.plotwork.dev/mcp` with an API key, or `https://mcp.plotwork.dev/mcp-oauth` with a browser sign-in. |
| HTTP API | `POST /v1/diagrams/validate`, `/render`, `/outline`, `GET /v1/icons`, `GET /v1/vocabulary`, on the Pro plan. See the [API reference](https://docs.plotwork.dev/api/reference.md). |

## 8. Workflows: one call instead of several

A workflow is a tool that performs several operations and returns one combined answer, so the agent spends one turn where it would spend three or four. The single tools stay for fine-grained steps. Every workflow is read-only, never guesses, and keeps its work bounded; the [tool reference](https://docs.plotwork.dev/mcp/tools.md) lists the operations and the limit of each.

| Workflow | Ask your agent | It replaces |
|---|---|---|
| `draw_diagram` | "Draw this flow and check it" | `validate_diagram`, then `outline_diagram`, then `render_diagram`. Invalid source returns every error and draws nothing, so the loop is one call per fix. |
| `convert_mermaid` | "Convert this Mermaid diagram to Plotwork" | The converter, then validation, outline, and render. The result lists everything that was dropped, with a hint for each. |
| `map_icons` | "Choose icons for these services" | One `search_icons` call per name. A name that could mean more than one icon comes back with candidates and no guess. |
| `find_pattern` | "Is there a ready-made diagram for a two-zone network?" | A guess at what exists. It ranks the checked patterns for the request in plain words and returns summaries, never source. |
| `get_pattern` | "Show me the three-tier network pattern for Azure" | Reading a pattern by hand. It fills the pattern with your slot values and returns the source, every slot, the advice, and the diagram as a tree. |
| `draw_from_pattern` | "Draw the serverless API pattern, with my service names" | `get_pattern`, then `validate_diagram`, then `render_diagram`. Slot values that break a rule come back as problems, and nothing is drawn. |
| `sync_markdown` | "Replace the Mermaid diagrams in README.md" | Reading the fences, converting, rendering, and building the picture blocks for a whole document. |
| `suggest_diagram` | "Which diagram shows who can call which endpoint?" | Reading every kind to choose one. It ranks the kinds for the request and gives a starter for each. |
| `plan_document_diagrams` | "Which parts of this design doc need a picture?" | Reading a document section by section and choosing a kind for each. |

To move the Mermaid diagrams in a document, the sequence is:

1. Call `sync_markdown` with the document text, its path, `convertMermaid: true`, and `mode: "check"`. Read the report.
2. Call it again with `mode: "sync"`. The result holds the rewritten document and the picture files.
3. Write the returned `markdown` to the document and each returned file to its `path`. The tool writes nothing itself.
4. Review the change in git before committing.

[Migrating from Mermaid](https://docs.plotwork.dev/migrating-from-mermaid.md) explains the diagnostics and shows the result of each call.

## 9. Choosing a kind and planning a document

Two workflows help before any source is written. Both are cheap: they read text, parse each starter once, and lay nothing out.

| Workflow | Send | You get |
|---|---|---|
| `suggest_diagram` | `request` in plain words, and optional `data`: a pasted table, a list, `Label: value` lines, or numbers by period | Up to 3 kinds, best first, each with a one-sentence reason, a confidence, the statements to use, and a starter that parses. Names and numbers from the request and the data are in the starter, and `tailored` says so. |
| `plan_document_diagrams` | `document`: Markdown, HTML, or text pasted from Confluence, Notion, or Google Docs | The sections a picture would help, in document order, each with its heading, its line, a kind, a reason, and a starter drafted from the section's lists, tables, numbers, and dates. Sections that read well as text, or already hold a diagram, are left out. |

The shape of the text counts as much as its words:

| The text holds | The kind suggested |
|---|---|
| A table of roles with R, A, C, and I | `matrix` with `style=raci` |
| A table of roles with yes and no | `matrix`, a permission matrix |
| Numbers by month, week, or quarter | `xychart` |
| A number for each part | `pie`, `treemap`, or `sankey` |
| `A -> B: 1200` lines | `sankey` |
| Dated lines, such as `2024: Public API` | `timeline` |
| `Role: action` lines where the roles come back | `swimlane` |
| Paths such as `src/index.ts` | `tree` with `style=files` |
| A numbered list | `flow` |

A starter is a start: replace its placeholders, call `get_diagram_syntax` with its kind, and check it with `draw_diagram` before you draw. To put the pictures into the document, add each as a `diagram` fence under its heading and call `sync_markdown`.

The MCP server also offers prompts, which a client lists in its prompt menu. Each tells the agent which tools to call, in order.

| Prompt | Arguments | What it does |
|---|---|---|
| `diagram-from-description` | `description` | `suggest_diagram`, then `get_diagram_syntax`, then `draw_diagram`; a common architecture goes to `find_pattern` first. |
| `diagrams-for-document` | `document`, optional `path` | `plan_document_diagrams`, then a checked diagram for each section, then `sync_markdown`. |
| `permission-matrix` | `endpoints`, `roles` | A matrix with roles as columns and endpoints as rows. |
| `architecture-overview` | `system` | `find_pattern` and `draw_from_pattern`, or a layered or C4 diagram written for the system. |
| `convert-mermaid-file` | `markdown`, optional `path` | `sync_markdown` with `convertMermaid`, then `convert_mermaid` for each fence that did not convert. |

## 10. Save diagrams to your library

Saving a finished diagram to Plotwork keeps it where your team can find it, beside the files and view links on your machine. Where it goes depends on how you connect.

| You use | What happens |
|---|---|
| The hosted MCP server, and an organisation you belong to keeps members' diagrams in its library | The server tells the agent to save each finished diagram to that private library with `publish_diagram`, without asking you, because only members can open it. Each valid drawing's next step says so too, and the answer names the library and gives the page for members. See [Where members publish](https://docs.plotwork.dev/organisations.md#13-where-members-publish). |
| The hosted MCP server with an organisation key | The same: the key's own library is private, so the agent saves there. |
| The hosted MCP server with only your own library | The agent publishes only when you ask, because that link is public. |
| The local MCP server | Nothing is saved: it has no account. Use the command line below. |
| The command line | `plotwork publish file.diagram` saves every diagram of a file with the key in `PLOTWORK_API_KEY`, where your organisations decide, and prints the link. `--org` names the library. |
| The Claude Code plugin | `PLOTWORK_PUBLISH=library` saves each file to the organisation in `PLOTWORK_ORG` after it is drawn. See [Claude Code plugin](https://docs.plotwork.dev/agents/claude-code-plugin.md#save-to-your-organisations-library). |

## See also

| Doc | Why |
|---|---|
| [Connecting an agent](https://docs.plotwork.dev/mcp/connect.md) | Settings for Claude Code and other clients |
| [Tool reference](https://docs.plotwork.dev/mcp/tools.md) | Arguments and results of every tool |
| [API reference](https://docs.plotwork.dev/api/reference.md) | The same operations over HTTP |
| [Writing diagrams](https://docs.plotwork.dev/writing-diagrams.md) | The language by example |
| [Cloud architecture](https://docs.plotwork.dev/cloud-architecture.md) | The five-step recipe for AWS, Azure, and Google Cloud diagrams, with every icon and group type drawn |
| [Architecture patterns](https://docs.plotwork.dev/architecture-patterns.md) | Ready-made, checked diagrams to start from, found and filled by tools |
| [Editing an existing diagram](https://docs.plotwork.dev/editing-existing-diagrams.md) | Read the source back from a link or an SVG file, change it, and save or publish it again |
| [Migrating from Mermaid](https://docs.plotwork.dev/migrating-from-mermaid.md) | Convert existing Mermaid diagrams, and what to do with each diagnostic |
| [Language reference](https://docs.plotwork.dev/reference/language.md) | Every word the language accepts |
