# draw_from_pattern

> Page: https://docs.plotwork.dev/mcp/tools/draw-from-pattern. Index of every page: https://docs.plotwork.dev/llms.txt

Fills a pattern and draws it in one call. It is a workflow of the MCP server and the HTTP API, with the title "Draw from pattern".

## TL;DR

| Question | Answer |
|---|---|
| What is it? | A workflow: one call does the work of several tools and returns one combined answer. |
| What does it do? | Fills a pattern and draws it in one call. |
| What does it replace? | get_pattern, validate_diagram, outline_diagram and render_diagram calls. |
| How do I call it over HTTP? | [`POST /v1/patterns/draw`](https://docs.plotwork.dev/api/post-v1-patterns-draw.md) |
| 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? | None beyond the limits of each argument, which are in the schema 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. Fills a pattern and draws it in one call. Send the id from find_pattern, a provider (neutral by default, or aws, azure, gcp), optional slot values that rename its parts, and the themes. Returns the source, the slots, the advice on adapting it, the quality warnings, a plain-text outline, and the SVG for light, dark, or both. Use it when a pattern fits with only names changed; use get_pattern to edit the source first. An unknown id, flavour, or slot comes back as a problem with a fix. svg, picturesOmitted, viewUrl, pngUrl, saveCommand, and detail work as in draw_diagram. Replaces the get_pattern, validate_diagram, outline_diagram and render_diagram calls.

## Steps

| Operation | Runs | What it does |
|---|---|---|
| `fillPattern` | always | Fill one pattern for one flavour with slot values: its source, slots, notes, group tree, and outline. |
| `validate` | only when needed | Parse the source and lint it: every error, and the quality, icon, and group-type warnings. |
| `outline` | only when needed | Describe a valid diagram as plain text. |
| `render` | only when needed | Lay out and paint a valid diagram in one color scheme. |

One call performs at most 5 operations.

## Example call

The arguments of the call, as JSON:

```json
{
  "id": "two-zone-network",
  "provider": "aws",
  "themes": "light"
}
```

## Prompts that lead to it

- Draw a two-zone network on AWS with a replicated database.
- Draw the web application pattern for Azure and call the API "Billing API".

## Arguments

| Field | Type | Required | Description |
|---|---|---|---|
| `id` | `string` | yes | The pattern id, as find_pattern returns it, such as three-tier-network. at least 1 character; at most 60 characters. |
| `provider` | `"neutral" \| "aws" \| "azure" \| "gcp"` | no | neutral (generic glyphs, no vendor names; the default), or aws, azure, or gcp for that provider's icons. Not every pattern comes in every flavour; the answer lists the ones it has. default "neutral". |
| `slots` | `object` | no | Slot values keyed by slot id, such as {"office": "Branch office"}: plain text of up to 60 characters, no quotes or line breaks. Omit a slot to keep its default. get_pattern lists the slots and what they mean. |
| `themes` | `"light" \| "dark" \| "both"` | no | light, dark, or both (the default): the light picture and the dark one a dark page needs. default "both". |
| `detail` | `"summary" \| "full"` | no | summary (the default), or full: the whole outline, and the source embedded in each SVG. default "summary". |
| `svg` | `"auto" \| "always" \| "never"` | no | auto (the default) returns the SVGs, but over MCP leaves them out when the answer would be too big for a client (picturesOmitted). always returns them at any size. never draws nothing, which is cheaper. The HTTP API treats auto as always. default "auto". |
| `embedSource` | `boolean` | no | Write the source into each SVG so read_diagram can give it back. Set it when you save the SVG in a repository or publish it to edit later; anyone with the file or link can then read the source. default false. |
| `settings` | `object` | no | The repo's plotwork.config.json, if any. Schema: https://docs.plotwork.dev/schemas/plotwork.config.json. |

## Result

| Field | Type | Required | Description |
|---|---|---|---|
| `found` | `boolean` | yes | True when the pattern and flavour exist and the slot values are usable. When false, problems says why and nothing else is filled. |
| `id` | `string` | yes | The pattern id that was asked for. |
| `title` | `string \| null` | yes |  |
| `patternSummary` | `string \| null` | yes | One sentence: what the pattern shows. |
| `whenToUse` | `string \| null` | yes |  |
| `kind` | `string \| null` | yes |  |
| `flavour` | `"neutral" \| "aws" \| "azure" \| "gcp" \| null` | yes | The flavour that was filled. |
| `flavours` | `("neutral" \| "aws" \| "azure" \| "gcp")[]` | yes | Every flavour this pattern comes in; empty when the pattern was not found. |
| `source` | `string \| null` | yes | Plotwork source, valid and ready to use; null when not found. |
| `slots` | `object[]` | yes | Every slot the source uses, with the value it has. |
| `slots[].id` | `string` | yes | The slot id; the key to use in slots. |
| `slots[].value` | `string` | yes | The text the slot has in the source: the value sent, or the default. |
| `slots[].default` | `string` | yes | The default text. |
| `slots[].meaning` | `string` | yes | What belongs in this slot. |
| `slots[].isDefault` | `boolean` | yes | True when the slot kept its default. |
| `notes` | `object \| null` | yes | How to adapt the pattern: what to keep, what to rename, and when to split. |
| `problems` | `object[]` | yes | Mistakes in the id, the flavour, or the slot values, each with a fix. Empty when found. |
| `problems[].code` | `"unknown-pattern" \| "unknown-flavour" \| "unknown-slot" \| "bad-slot-value" \| "bad-source"` | yes |  |
| `problems[].message` | `string` | yes |  |
| `problems[].hint` | `string` | yes | How to fix it. |
| `valid` | `boolean` | yes | True when the source has no errors. When false, nothing was drawn: fix the errors and call again. |
| `errors` | `Diagnostic[]` | yes | Every error found in one pass, each with line, column, and a hint. Empty when valid. |
| `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"` | yes | Stable code to branch on; E-codes are errors, W-codes are warnings. |
| `errors[].severity` | `"error" \| "warning"` | yes | Errors stop rendering; warnings never do. |
| `errors[].message` | `string` | yes | What is wrong, in one sentence. |
| `errors[].line` | `integer` | yes | 1-based line in the submitted source. minimum 1. |
| `errors[].column` | `integer` | yes | 1-based column in that line. minimum 1. |
| `errors[].length` | `integer` | yes | Number of characters the problem covers. minimum 1. |
| `errors[].hint` | `string \| null` | yes | A concrete suggestion for fixing it, or null. |
| `warnings` | `Diagnostic[]` | yes | Quality warnings for a valid diagram: too dense, too wide, text cut, unconnected nodes, and suggestions for an icon or a group type. Empty when invalid. |
| `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"` | yes | Stable code to branch on; E-codes are errors, W-codes are warnings. |
| `warnings[].severity` | `"error" \| "warning"` | yes | Errors stop rendering; warnings never do. |
| `warnings[].message` | `string` | yes | What is wrong, in one sentence. |
| `warnings[].line` | `integer` | yes | 1-based line in the submitted source. minimum 1. |
| `warnings[].column` | `integer` | yes | 1-based column in that line. minimum 1. |
| `warnings[].length` | `integer` | yes | Number of characters the problem covers. minimum 1. |
| `warnings[].hint` | `string \| null` | yes | A concrete suggestion for fixing it, or null. |
| `summary` | `string \| null` | yes | One-line description of the diagram, usable as alt text; null when invalid. |
| `outline` | `string[]` | yes | The diagram as plain text in reading order, to check it says what you meant; empty when invalid. |
| `outlineTruncated` | `boolean` | yes | True when the summary level cut the outline short. Call again with detail "full" to read all of it. |
| `size` | `Size \| null` | yes | Natural size of the laid-out diagram; null when invalid. |
| `quality` | `Quality` | no | How clean the picture looks (score, grade, measures) and up to three changes that would help; read it instead of looking. Absent when invalid. |
| `quality.score` | `integer` | yes | 0 to 100; 100 is a picture with nothing to fix. The same diagram always gets the same score. minimum 0; maximum 100. |
| `quality.grade` | `"clean" \| "fair" \| "cluttered"` | yes | clean is 85 or more, fair 60 or more, cluttered below. |
| `quality.measures` | `object` | yes | What the score is made from: crossings, lineOverBox, labelOverlaps, smallestTextPx (in an 880px column), aspectRatio, emptySpace (0 to 1), longestLine (px), detour (1 is straight), the counts of boxes, lines, labels, series, and slices, and any measure the kind adds. |
| `quality.hints` | `string[]` | yes | Up to three changes, the one worth most first, each naming the statement or option to edit. |
| `quality.line` | `string` | yes | The grade, the score, and the first hint in one line. |
| `notices` | `Note[]` | no | Information notes, such as an icon alias drawn as the real icon; absent when there is none. |
| `notices[].code` | `string` | yes | A stable code, such as I122 for an icon alias. |
| `notices[].severity` | `"info"` | yes | A note never stops a drawing and is not a warning. |
| `notices[].message` | `string` | yes |  |
| `notices[].line` | `integer` | yes | minimum 1. |
| `notices[].column` | `integer` | yes | minimum 1. |
| `notices[].length` | `integer` | yes | minimum 1. |
| `notices[].hint` | `string \| null` | yes | The text to write instead. |
| `renders` | `object[]` | yes | One picture per requested color scheme, light first; empty when invalid, when svg is never, and when every picture was left out (see picturesOmitted). |
| `renders[].theme` | `"light" \| "dark"` | yes | The color scheme this picture is drawn in. |
| `renders[].svg` | `string` | yes | Self-contained SVG markup with an accessible title and description. |
| `renders[].size` | `Size` | yes | Natural size of a rendered diagram in px. |
| `renders[].size.width` | `integer` | yes | Width in px. minimum 1. |
| `renders[].size.height` | `integer` | yes | Height in px. minimum 1. |
| `picturesOmitted` | `object` | no | Present 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")[]` | yes | The color schemes whose pictures were left out. |
| `picturesOmitted.characters` | `integer` | yes | How many characters the pictures left out came to. |
| `picturesOmitted.limit` | `integer` | yes | The most characters one answer may hold before the pictures are left out. |
| `picturesOmitted.why` | `string` | yes | Why they were left out, and what to do. |
| `viewUrl` | `string` | no | A 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. |
| `pngUrl` | `string` | no | The viewUrl with &download=png: opening it in a browser saves the diagram as a PNG for Slack, email, or a wiki. The PNG is drawn in the person's browser, not on a server, so it is a link to open, not an image address to embed. Absent when too long. |
| `svgUrl` | `string` | no | The viewUrl with &download=svg: a person opens it to download the SVG. Not a file address for curl; use saveCommand. Absent when too long. |
| `saveCommand` | `string` | no | Run 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. |
| `next` | `string` | yes | The next step in one sentence. |

## Behavior hints

| Hint | Value |
|---|---|
| `readOnlyHint` | true |
| `destructiveHint` | false |
| `idempotentHint` | true |
| `openWorldHint` | false |

## See also

| Doc | Why |
|---|---|
| [Tool reference](https://docs.plotwork.dev/mcp/tools.md) | Every tool, with the workflows first |
| [`POST /v1/patterns/draw`](https://docs.plotwork.dev/api/post-v1-patterns-draw.md) | The same operation over HTTP |
| [Language reference](https://docs.plotwork.dev/reference/language.md) | What the diagram source may contain |
| [Writing diagrams with an agent](https://docs.plotwork.dev/mcp/agent-loop.md) | The loop in practice |
