Skip to content
Connect an agent
For agents

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.

For
  • Claude Code

TL;DR

QuestionAnswer
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.

Plugin save loop: 5 participants. Claude writes the source with the MCP tools, saves it, and the hook draws the SVG with the command line.

1. Install the plugin

Inside Claude Code:

text
/plugin marketplace add plotwork-official/plotwork-claude-plugin/plugin install plotwork@plotwork

Or name the marketplace in the install itself:

text
/plugin install plotwork --marketplace plotwork-official/plotwork-claude-plugin

The 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 sayWhat 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 savedWhat the hook writesHow the docs show it
A fence in docs/guide.mddocs/assets/diagrams/<id>.svg and <id>.dark.svg, and the picture block under the fenceThe picture block is a <picture> element that follows the reader's light or dark setting
docs/diagrams/checkout.diagramdocs/diagrams/checkout.svg, with the source embeddedLink 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.

SettingDefaultChange it
FolderThe project rootAsk for one folder, such as "preview docs"
Port3900, or the next free one of the ten after itAsk for a port
Address127.0.0.1 onlyNot 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.

WhenWhat the plugin does
The session startsOne sentence in the session note: draw diagrams with the Plotwork tools, never Mermaid, PlantUML, Graphviz, or D2.
Your prompt asks for a diagramTwo 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 blockThe 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:

PartWhat counts
LanguagesA 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 alonenode_modules, .git, build output, vendor, and test fixtures (fixtures, __fixtures__, __tests__, testdata, __snapshots__).
Only new blocksAn 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:

text
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_MERMAIDEffect
convert, or unsetThe default. A new block is refused with the reason above.
warnThe write goes through, and Claude gets the same reason as a note.
allowThe 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:

json
{  "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.

json
{  "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

VariableEffect
PLOTWORK_HOOKS=offTurns the hook off, including the Mermaid guard. The skills then run the command line themselves.
PLOTWORK_MERMAIDconvert (the default), warn, or allow. See When you want Mermaid.
PLOTWORK_CLIThe command the hook runs instead of the default, such as yarn plotwork. It is split on spaces.
PLOTWORK_PUBLISH=libraryOff 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_ORGThe 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.

QuestionAnswer
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 seeWhyFix
Claude says the hook could not run npxNo Node on the path, or no network for the first downloadInstall 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 secondsnpx is downloading the command lineLater saves use the cached copy
A picture is stale after you edit by handThe hook runs only when Claude savesRun npx -y @buun_group/plotwork@0.1.0-beta.13 sync <page>
A Mermaid block you asked for was refusedThe guard refuses new Mermaid in documentation by defaultAsk Claude to keep it, and set PLOTWORK_MERMAID=allow or warn in the env of .claude/settings.json
The tools appear twiceThe server is added both by the plugin and by claude mcp addclaude mcp remove plotwork

See also

DocWhy
Connecting an agentAdd the MCP server to other clients, or use the hosted server
Command line overviewEvery command the hook and the skills run
Markdown and GitHubHow a fence and its picture block look in a page
Migrating from MermaidWhat convert_mermaid and sync_markdown do with existing Mermaid
Keep diagrams in sync in CIFail a pull request whose pictures are stale
Writing diagrams with an agentThe loop the skills follow