The Claude Code plugin
The Plotwork plugin for Claude Code joins the MCP server and the command line, so a diagram you ask for ends up as an SVG in your docs with no step of your own. It is for anyone who uses Claude Code in a repository with documentation.
- Claude Code
TL;DR
| Question | Answer |
|---|---|
| What does it add? | The local MCP server, a hook that draws diagrams with the command line every time Claude saves one, a gallery on localhost that reloads, and three skills that tell Claude how to use them together. |
| What if Claude starts to write Mermaid? | The hook refuses a new Mermaid, PlantUML, Graphviz, or D2 block in a documentation file and tells Claude which Plotwork tools to use instead. PLOTWORK_MERMAID=warn or allow relaxes it. |
| How do I install it? | /plugin marketplace add plotwork-official/plotwork-claude-plugin, then /plugin install plotwork@plotwork. |
What happens when Claude saves a .diagram file? | The hook runs plotwork render and writes the SVG beside it, with the source inside. |
What happens when Claude saves a Markdown page with a diagram fence? | The hook runs plotwork sync: a light and a dark SVG land in assets/diagrams/ beside the page, and the picture block is written under the fence. |
| What if the diagram has a mistake? | Nothing is written. Claude gets each mistake with its line, column, and hint, fixes it, and saves again. |
| How do I see the pictures? | Ask Claude to preview them, or run /plotwork:preview. The gallery is on http://127.0.0.1:3900 and reloads within a second of a change. |
| Does it need an account or a key? | No. The MCP server, the command line, and the gallery all run on your machine. |
| Does it use the network? | npx downloads the MCP server and the command line from npm the first time. After that, nothing is sent by default. |
How the pieces fit
The MCP tools write and check the source. The command line draws the pictures on disk. The hook runs the command line the moment Claude saves a file, so the SVG never passes through the model and the picture is the one CI draws.
sequence "Plugin save loop" desc="Claude writes the source with the MCP tools, saves it, and the hook draws the SVG with the command line."
actor you person "You"actor claude agent "Claude Code"actor mcp service "Plotwork MCP" sub="draw_diagram"actor hook function "Plugin hook" sub="After each save"actor cli service "Command line" sub="render or sync"
you -> claude : "Add a diagram of checkout to the docs"claude -> mcp : "Check the source"mcp --> claude : "Valid, with an outline"claude -> hook : "Saves the page or .diagram file"hook -> cli : "Draw it"alt "the diagram is valid" { cli --> hook : "SVGs written" hook --> claude : "Files drawn"} else "it has a mistake" { cli --> hook : "Line, column, hint" hook --> claude : "Blocked: fix and save again"}claude --> you : "Diagram is in the docs"Participants:
- You, person
- Claude Code, agent
- Plotwork MCP (draw_diagram), service
- Plugin hook (After each save), function
- Command line (render or sync), service
Steps:
-
- You to Claude Code: Add a diagram of checkout to the docs
-
- Claude Code to Plotwork MCP: Check the source
-
- Plotwork MCP to Claude Code (dashed): Valid, with an outline
-
- Claude Code to Plugin hook: Saves the page or .diagram file
-
- Plugin hook to Command line: Draw it
- alt: the diagram is valid
- 6. Command line to Plugin hook (dashed): SVGs written
-
- Plugin hook to Claude Code (dashed): Files drawn
- else: it has a mistake
- 8. Command line to Plugin hook (dashed): Line, column, hint
-
- Plugin hook to Claude Code (dashed): Blocked: fix and save again
-
- Claude Code to You (dashed): Diagram is in the docs
1. Install the plugin
Inside Claude Code:
/plugin marketplace add plotwork-official/plotwork-claude-plugin/plugin install plotwork@plotworkOr name the marketplace in the install itself:
/plugin install plotwork --marketplace plotwork-official/plotwork-claude-pluginThe repository plotwork-official/plotwork-claude-plugin (opens in a new tab) holds the plugin and its marketplace, and is updated with each change to the plugin. To update an installed copy, run /plugin marketplace update plotwork.
Restart Claude Code when it asks. Run /mcp to confirm that the plotwork server is connected. The plugin needs Node 22 or newer.
If you already added the server with claude mcp add plotwork, remove that one with claude mcp remove plotwork so Claude sees one set of tools.
2. Ask for a diagram
Ask in plain words, and say where it goes:
| You say | What Claude does |
|---|---|
"Add a diagram of the checkout flow to docs/architecture.md." | Writes a diagram fence into the page. The hook syncs it. |
"Draw our Terraform in infra/ as a diagram for the docs site." | Calls import_source, saves docs/diagrams/infra.diagram. The hook writes infra.svg. |
| "Illustrate the README." | Calls plan_document_diagrams, adds a fence for each section that needs one, and saves. |
"Move the Mermaid diagrams in docs/ to Plotwork." | Calls sync_markdown with convertMermaid for each page. |
| "Show me the diagrams." | Starts the gallery and gives you its address. |
Claude picks these up from the skills without being told their names. You can also run one yourself: /plotwork:draw, /plotwork:document, or /plotwork:preview.
3. Where the pictures go
| What Claude saved | What the hook writes | How the docs show it |
|---|---|---|
A fence in docs/guide.md | docs/assets/diagrams/<id>.svg and <id>.dark.svg, and the picture block under the fence | The picture block is a <picture> element that follows the reader's light or dark setting |
docs/diagrams/checkout.diagram | docs/diagrams/checkout.svg, with the source embedded | Link it from any page with a Markdown image whose path is diagrams/checkout.svg, relative to the page |
Commit the SVGs with the page. Never edit the picture block by hand; the next sync rewrites it. The Markdown and GitHub guide explains the picture block.
The command line reads your repository settings on every run, so header defaults in plotwork.config.json apply to the hook's pictures. At the start of a session the plugin tells Claude the file is there, so the MCP tools use it too.
4. Preview on localhost
The gallery shows every SVG under the project, grouped by folder, with each light picture beside its dark one. It skips node_modules, .git, and build output.
| Setting | Default | Change it |
|---|---|---|
| Folder | The project root | Ask for one folder, such as "preview docs" |
| Port | 3900, or the next free one of the ten after it | Ask for a port |
| Address | 127.0.0.1 only | Not changeable; it is never reachable from another machine |
Pictures are shown in <img> elements, where a script inside an SVG never runs, and the server answers only for .svg files.
5. Mermaid and other diagram languages
Claude knows Mermaid well, so it reaches for it by habit. The plugin steers it to Plotwork at three points, and none of them repeats on every turn.
| When | What the plugin does |
|---|---|
| The session starts | One sentence in the session note: draw diagrams with the Plotwork tools, never Mermaid, PlantUML, Graphviz, or D2. |
| Your prompt asks for a diagram | Two sentences of guidance, only when the prompt names a diagram as a whole word: diagram, flowchart, flow chart, sequence diagram, architecture diagram, ERD, entity relationship, Mermaid, mind map, Gantt, state machine, C4, swimlane, or org chart. "Diagrammatic" does not count. |
| Claude is about to save a new block | The write is refused before it happens, with what to do instead. |
What is refused
A write is refused when it adds a block in another diagram language to a documentation file:
| Part | What counts |
|---|---|
| Languages | A fence of mermaid, plantuml, puml, dot, graphviz, or d2, with backticks or tildes; a <div class="mermaid"> or <pre class="mermaid"> element; a Sphinx .. mermaid::, .. graphviz::, or .. uml:: directive. |
| Files | .md, .mdx, .markdown, .rst, .txt, a markdown cell of an .ipynb notebook, and a README or CHANGELOG with no extension. Code and data files are never read, so a test that holds Mermaid in a string is left alone. |
| Folders left alone | node_modules, .git, build output, vendor, and test fixtures (fixtures, __fixtures__, __tests__, testdata, __snapshots__). |
| Only new blocks | An edit whose old text already held the block goes through, and so does a rewrite of a page that keeps the blocks it had. Working near an existing Mermaid diagram is never blocked. |
Claude reads this reason, and in practice follows it in the same turn:
This page is drawn with Plotwork, so write a ```diagram fence in Plotwork's language instead of mermaid. Call mcp__plugin_plotwork_plotwork__get_diagram_syntax once if you have not read the language, check the source with mcp__plugin_plotwork_plotwork__draw_diagram (svg "never"), and the plugin syncs the fence into a picture when you save. To keep this Mermaid, call mcp__plugin_plotwork_plotwork__convert_mermaid with it and write the Plotwork source it returns; for a whole page of Mermaid, call mcp__plugin_plotwork_plotwork__sync_markdown with convertMermaid true. If the person asked for mermaid by name, tell them the Plotwork plugin refused it and that PLOTWORK_MERMAID=allow lets it through.When you want Mermaid
PLOTWORK_MERMAID | Effect |
|---|---|
convert, or unset | The default. A new block is refused with the reason above. |
warn | The write goes through, and Claude gets the same reason as a note. |
allow | The write goes through with nothing said, and the session and prompt notes leave Mermaid out. |
To set it for one repository, put it in the env of the repository's .claude/settings.json, which Claude Code passes to the hook:
{ "env": { "PLOTWORK_MERMAID": "warn" }}It is not a field of plotwork.config.json: every released command line, Action, and MCP server checks that file strictly, and would refuse a field it does not know.
Without the plugin
If you added the MCP server with claude mcp add and do not want the plugin, this hook in your .claude/settings.json refuses a new Mermaid fence in a Markdown file in the same way. It is plain Node with nothing to install. The plugin does more: it also covers PlantUML, Graphviz, D2, notebooks, and fixtures, adds the prompt and session notes, and draws the fences on save, so prefer the plugin when you can install it.
{ "hooks": { "PreToolUse": [ { "matcher": "Write|Edit|MultiEdit", "hooks": [ { "type": "command", "command": "node -e \"let s='';process.stdin.on('data',c=>s+=c).on('end',()=>{const fs=require('fs'),e=JSON.parse(s),i=e.tool_input||{},f=String(i.file_path||'');if(!['.md','.mdx','.markdown'].some(x=>f.toLowerCase().endsWith(x)))return;const n=t=>(String(t||'').match(/^ {0,3}(\\x60{3,}|~{3,})[ \\t]*mermaid\\b/gim)||[]).length;const old=e.tool_name==='Write'&&fs.existsSync(f)?fs.readFileSync(f,'utf8'):'';const edits=i.edits||[{old_string:i.old_string??old,new_string:i.new_string??i.content}];if(edits.some(x=>n(x.new_string)>n(x.old_string)))console.log(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',permissionDecision:'deny',permissionDecisionReason:'Draw this with Plotwork instead of Mermaid: write a diagram fence in the Plotwork language and check it with the draw_diagram tool, or call convert_mermaid on this Mermaid and use the source it returns. For a whole page of Mermaid, call sync_markdown with convertMermaid true.'}}))})\"", "timeout": 5 } ] } ] }}6. Settings
| Variable | Effect |
|---|---|
PLOTWORK_HOOKS=off | Turns the hook off, including the Mermaid guard. The skills then run the command line themselves. |
PLOTWORK_MERMAID | convert (the default), warn, or allow. See When you want Mermaid. |
PLOTWORK_CLI | The command the hook runs instead of the default, such as yarn plotwork. It is split on spaces. |
PLOTWORK_PUBLISH=library | Off unless set. After a drawing that worked, the hook also saves the file's diagrams to an organisation's private library and gives the agent the link. See Save to your organisation's library. |
PLOTWORK_API_KEY, PLOTWORK_ORG | The key the library save uses, and the organisation it saves to. Without PLOTWORK_ORG, the hook uses brand.organization from plotwork.config.json. |
Without PLOTWORK_CLI, the hook runs the plotwork your project installed in node_modules, and otherwise npx -y @buun_group/plotwork@0.1.0-beta.13, the release this plugin pins. Pin the same release in CI, as Keep diagrams in sync in CI shows, so the check draws what the hook drew.
Save to your organisation's library
Set PLOTWORK_PUBLISH=library, PLOTWORK_API_KEY and PLOTWORK_ORG in the environment Claude Code starts with, or in the env of your Claude Code settings. Each time the hook draws a .diagram file or syncs a page, it then runs plotwork publish <file> --org <org> and adds the link to the note the agent reads, so the agent can hand it to you. Only members of the organisation can open it.
| Question | Answer |
|---|---|
| Can it publish to a public link? | No. The hook always names the organisation, and does nothing when none is named. Use plotwork publish yourself for a public link. |
| What if the save fails? | The note says why, and nothing is blocked: the files are still drawn in the repository. |
| Which command line does it need? | A release that has publish. Set PLOTWORK_CLI to a newer one if the pinned release is older. |
Troubleshooting
| What you see | Why | Fix |
|---|---|---|
Claude says the hook could not run npx | No Node on the path, or no network for the first download | Install Node 22, or install the command line in the project with npm install --save-dev @buun_group/plotwork@0.1.0-beta.13 |
| The first save takes a few seconds | npx is downloading the command line | Later saves use the cached copy |
| A picture is stale after you edit by hand | The hook runs only when Claude saves | Run npx -y @buun_group/plotwork@0.1.0-beta.13 sync <page> |
| A Mermaid block you asked for was refused | The guard refuses new Mermaid in documentation by default | Ask Claude to keep it, and set PLOTWORK_MERMAID=allow or warn in the env of .claude/settings.json |
| The tools appear twice | The server is added both by the plugin and by claude mcp add | claude mcp remove plotwork |
See also
| Doc | Why |
|---|---|
| Connecting an agent | Add the MCP server to other clients, or use the hosted server |
| Command line overview | Every command the hook and the skills run |
| Markdown and GitHub | How a fence and its picture block look in a page |
| Migrating from Mermaid | What convert_mermaid and sync_markdown do with existing Mermaid |
| Keep diagrams in sync in CI | Fail a pull request whose pictures are stale |
| Writing diagrams with an agent | The loop the skills follow |