ascii2svg
This server renders ASCII/Unicode box diagrams into SVG (or HTML) and validates them, with options for styling, repair, and structure reporting.
render_diagram: Convert a plain-text diagram into an SVG file (or an HTML page), with presets for readme/slides/chat/print/dark/page/explore, themes, colors, animation (draw/flow/scroll), square corners, glow/shadow/flat styles, custom accent/font/width/title, portable text output, and interactive folding for trees/mind maps.
check_diagram: Validate a diagram without writing output; returns status, summary, warnings with actionable hints (row/col fixes), and the parsed structure (boxes and edges).
Repair misaligned diagrams: Both tools accept
repairto fix ragged walls, drifting connectors, and short arrows; the corrected text is returned inreport.repair.text.Describe structure: Optionally get boxes and edges (which box each arrow connects) to confirm the diagram means what you intended.
Output flexibility: Omit
output_pathto receive the markup back; use.htmlpaths for scroll-reveal pages; setfoldto start trees with nodes folded.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ascii2svgConvert this diagram to animated SVG"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
You sketch a diagram in plain text: in a README, a code comment, a chat with an AI. It looks right in a monospace font and falls apart everywhere else (Slack, email, Confluence, slides, a phone). ascii2svg turns it into a crisp SVG that draws itself, follows your reader's light or dark mode, and shows data moving along the arrows.
It never guesses. Every run reads its own SVG back and checks it against your text, cell by cell, so what you drew is exactly what you get. And the banner at the top of this page? That's plain text too.
Highlights
Faithful, provably // every character lands in its exact cell, verified by reading the SVG back. A mismatch is an error, never a quiet surprise.
Fixes LLM diagrams //
--repairlines up the walls, connectors and arrowheads a chat model got one column wrong, without touching a word.Alive // lines draw themselves, pulses flow along arrows, tall diagrams unfold as you scroll. Nothing moves for readers who ask for reduced motion.
Trees that fold // call trees, file trees,
npm ls/cargo treeoutput and mind maps become an SVG whose branches fold when clicked, with a colour per branch. No JSON, no DSL: the text you already have.Small // one element per word, not per letter, and one path per line style: files are about half the size they were in 1.15.
More than boxes // flowcharts, sequence and state diagrams, C4, UML, ER crow's feet, Gantt and bar charts, diamonds, dashed lines.
Agent-native // one JSON report for every outcome, hints that say exactly what to move, an MCP server and a Claude skill.
Zero dependencies // one Python file for Python 3.9+. The same file runs in your browser and on npm via WebAssembly.
Related MCP server: MCP SVG Animator
Quick start
New here? The guide walks you through it in plain language: how to run it, how to draw diagrams that render well, which look to pick, and what to do when something doesn't come out as you meant.
In your browser, nothing to install: open the playground, paste a diagram, pick where it's going, download SVG, PNG or a web page. Nothing is uploaded.
From the command line:
pip install ascii2svg
ascii2svg diagram.txt -o diagram.svg --preset readme # colour, light/dark, animationFrom JavaScript, no Python needed: npm install @satyadip28/asciitosvg (see Install).
With Claude: add the skill,
then just ask "turn this diagram into an image for my slides". Or connect the MCP server:
claude mcp add ascii2svg -- ascii2svg --mcp.
Type this…
+------------+ +------------+ +------------+ +-------------+
| Idea |---->| Draft |---->| Review |---->| Publish |
+------------+ +------------+ +-----+------+ +-------------+
^ |
| |
+------------------+
needs changes…get this
Plain + - | became real lines, v ^ < > became arrowheads, and the words stayed words.
Unicode box characters (┌─┐ │ └─┘ ╭╮ ═║ ▶) work just as well.
LLM diagrams, fixed
Ask any chat model for an architecture diagram and the boxes rarely line up: an emoji counted
as one column instead of two, a wall one space short, a connector that drifts sideways
between rows. --repair puts them back:
Boxes: walls, corners and edges up to 12 columns off move into line. A box whose words don't fit (a long label, or emoji counted as one column) grows to fit them, all rows at once.
Connectors: a piece one or two cells to the side moves into line, and so does a whole half of a line that drifted 3-6 columns. Gaps of a cell or two are filled, and an arrow that stops short of its box is carried on until it touches (
short_arrowwarns about it first).
As the model wrote it |
|
2 of 5 boxes recognised, 10 warnings | 5 boxes, 0 warnings, 5 fixes |
ascii2svg diagram.txt -o diagram.svg --repair --json{"status": "ok", "summary": "Repaired 5 misalignments. Rendered 5 boxes and 3 arrows (22x51); 1:1 self-check exact.",
"repair": {"edits": [{"line": 2, "col": 23, "fix": "moved the right wall '│' 1 col left"},
{"line": 6, "col": 12, "fix": "moved '│' 1 col left to line it up"}, "..."],
"text": "┌─────────────────────┐\n│ 📱 Mobile app │\n..."}}What it never does: change your words. Only line characters and spaces move or appear: into empty cells, or, when a box grows, along that box's own connector, which gets shorter. A test strips every line character from each row, before and after, and checks that what remains is identical.
What you get back: every edit with its line and column, and the corrected text in
repair.text, ready to paste back where the diagram came from. Diagrams that were already right come back untouched.
In the playground, a diagram with warnings shows a Fix alignment button.
Trees and mind maps that fold
Call trees, dependency trees, file trees and mind maps are usually drawn with a JavaScript library
fed a hand-written JSON tree. Here the tree is the text: what tree, npm ls, cargo tree,
pipdeptree, mvn dependency:tree, gradle dependencies or pstree print, a call tree from a
profiler or an LLM, or a mind map you sketch with ├── and ╰──. In the
playground, paste any of them and the
branches fold by themselves.
tree src | ascii2svg - -o src.svg --preset explore # colour per branch, branches fold
cargo tree | ascii2svg - -o deps.svg --preset explore --fold 1 # start with only the top level open
ascii2svg calls.txt --check --describe # the hierarchy as JSON: report.diagram.treeWhat counts as a tree: plain connectors between words or boxes, with the parent above or to the left of its children:
├──└──│in Unicode,|--and`--in ASCII,├─┬asnpm lsdraws it,+---/\---(Gradle) and+-/\-(Maven),─┬─aspstreedraws it, a box whose┬fans out to other boxes, or branches going right as in a mind map. A diagram with arrowheads stays a flowchart.Folding (
--interactive, or--preset explore): click a node or its ⊖ button, or Tab to it and press Enter. Shift folds or unfolds the whole branch.--fold Nstarts with depth N folded. Hover lights up the branch below a node.Where it folds: wherever the SVG's own script may run: the file opened in a browser, a page made with
-o tree.html, an<object>or<iframe>, the playground. As an<img>(GitHub, most docs sites) scripts never run, and the reader sees the full drawing, still 1:1 and self-checked.Colours (
--coloron a tree with no arrows): one colour per main branch, used for its lines and a tint behind its label; the root sits on a dark pill; boxes take their branch's tint.
Gallery
All plain text, all 1:1. The sources are in docs/examples/, and every one is in the playground's example picker.
The flows follow the real wiring: through junctions, down both branches of a fan-out, and across
the edge of a container. The text is tests/fixtures/complex_unicode.txt.
Pick a look
Same diagram, same guarantee, five ways:
Default | Colour | Dark | Alive | |
(no options) |
|
|
|
|
Or let the destination decide: --preset readme|slides|chat|print|dark|page|explore.
Destination | Use |
GitHub README, docs site |
|
A tall diagram people scroll through |
|
A tree or mind map people explore |
|
Slides (Keynote, Google Slides, PowerPoint) |
|
Slack, email, Jira: anywhere SVG isn't shown |
|
Printed docs, a PDF |
|
Dark-mode apps |
|
Option | What it does |
| Soft tints grouped by what contains what: each top-level group gets its own hue, nested boxes keep it. Arrows turn accent blue. |
|
|
| The diagram draws itself once, top to bottom: lines are sketched in accent blue and settle to ink, boxes fade in, arrowheads pop, bars grow. |
|
|
| For tall diagrams, as a web page: each part appears as the reader scrolls to it, and long connectors grow with the scroll. |
| A standalone web page with the diagram inline. Double-click to open, or email it. |
| Depth under the boxes. The glow shrinks automatically so it never sits behind a label. |
| Keep corners square (they are rounded by default). |
| Fix typical misalignment first (see LLM diagrams, fixed). |
| Trees and mind maps fold when clicked (see Trees and mind maps that fold). |
| One |
| Your brand colour for arrows and animation, a font to try first (e.g. |
The animation is careful about where it runs:
It never changes what's drawn. An animated file is the static file plus timing. When the animation ends, you're looking at exactly what the self-check verified; tools that don't play animation (PNG export, most editors) show the finished drawing.
It respects the reader. With reduce motion turned on in the OS, nothing moves.
drawandflowneed no JavaScript. They use CSS and SVG<animate>only, so they play inside a plain<img>tag, which is how GitHub, Notion and most docs sites show images.scrollis a web page, not just an SVG, because an image can't see how far you've scrolled (and CSS scroll timelines don't drive SVG shapes: we tested it). The page adds about 2 KB of plain JavaScript; the SVG inside it is the same self-checked drawing.
How it compares
ascii2svg | Diagram DSLs (Mermaid, PlantUML) | A screenshot of the text | |
You write | the picture itself, in any editor or chat | code in the tool's language; the layout is automatic | the picture |
Diagrams you, or an LLM, already have | render as they are | need rewriting in the DSL | work as they are |
Output | SVG: sharp at any size, light and dark, animated | SVG where the renderer is supported | pixels: blurry when scaled, one theme |
Proof it's faithful | reads its own SVG back, cell by cell | – | – |
Misaligned LLM output |
| – | shows the mistakes |
Collapsible trees and mind maps | click to fold, from plain text ( | fixed layout, nothing folds | – |
Output of | pipe it in as it is | needs converting | works, as pixels |
Where the picture goes | exactly where you drew it | the layout engine decides | where you drew it |
Choose a DSL when you want the layout done for you. Choose ascii2svg when the text diagram already exists, or when an LLM writes it, and you want it to look designed without changing it. Related projects such as svgbob and goat also turn ASCII art into SVG and draw more freeform shapes; ascii2svg focuses on box diagrams, a verified 1:1 result, and agent workflows.
What gets drawn
Source | Drawn as lines when… | Otherwise |
─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼ ╭ ╮ ╰ ╯ ═ ║ ╔ ╗ ╚ ╝ ╪ ▼ ▲ ▶︎ ◀︎ | always | – |
Dashed ╌ ╎ ┄ ┆ ┈ ┊ | always, with 2, 3 or 4 dashes per cell; they join, box and carry arrows like any line | – |
ASCII | they form a closed box, or attach to one directly or through | stay text |
ASCII rounded corners | they close a box ( | stay text ( |
ASCII lines between plain words: | an arrowhead points at a word and every loose end rests on one (with a space between on a row); a label set into the line is carried over and reported | stay text ( |
ASCII | they end a line that is drawn, or point at a box (touching, or one space away) | stay text |
ASCII trees | a column of | stay text (markdown tables, |
╱ ╲ ╳, and ASCII | Unicode always; ASCII when two or more run along their own slope, with no letter or digit beside them | stay text |
ASCII UML heads | on a line that touches a box (across, or one space short), or right against a box's top or bottom edge with | stay text |
ASCII dashed | they join a box or end in an arrowhead that points into one; flow pulses hop the gaps | stay text ( |
UML heads △ ▽ ◁ ▷ ◇ ◆ | a line joins them: triangles touch the parent, diamonds sit on the whole | stay text (bullets, symbols) |
ER marks | /` on vertical lines | on a connector between two boxes: across ( |
Block elements █ ▓ ▒ ░ ▀ ▄ ▌ ▐ ▁ ▂ ▃ ▅ ▆ ▇ ▏ ▎ ▍ ▋ ▊ ▉ ▖ ▗ ▘ ▝ ▚ ▞ ▙ ▛ ▜ ▟ | always, as exact rectangles, so bars and shading have no seams | – |
When unsure, a character stays text, so the worst case is the character itself in its own cell,
never a wrong shape. a->b, --dry-run, user_id, C:\temp, yes/no, TCP/IP, markdown
tables and |-- file trees all stay exactly as written.
How 1:1 is guaranteed: every run parses the SVG it just wrote (lines, curves, diagonals,
arrowheads, rectangles, rings, feet, text positions) back into a character grid and compares it
with the input, cell by cell. ASCII characters may only appear as the line they stand for
(-→─, |→│, +→corner or junction, v→▼, /→╱). Any mismatch is exit code 2. This
covers every look, including animated ones and the still frame used for PNGs.
Install
Python 3.9+ and nothing else:
pip install ascii2svg # adds the `ascii2svg` command and the `ascii2svg` module
pip install "ascii2svg[width,png]" # optional: wcwidth (character widths) + cairosvg (--png)It is a single file with no dependencies, so you can also just copy
scripts/ascii2svg.py into your project.
Node and the browser, with no Python install:
npm install @satyadip28/asciitosvg
npx @satyadip28/asciitosvg diagram.txt -o diagram.svg --preset readmeimport { render } from "@satyadip28/asciitosvg";
const { markup, report } = await render(diagram, { preset: "readme", repair: true });The npm package runs this same Python module in Pyodide (CPython on
WebAssembly). Its tests render every test diagram in five looks both ways and require
byte-identical SVG and reports. The CLI and the MCP server (npx -y @satyadip28/asciitosvg --mcp)
work as with pip; only --png needs the Python package. Details:
npm/README.md.
import ascii2svg
svg, report = ascii2svg.render(open("diagram.txt").read(), color=True, theme="auto", animate="flow")
assert report["roundtrip"] == "exact" # the 1:1 self-check passed
open("diagram.svg", "w", encoding="utf-8").write(svg)
page, report = ascii2svg.render(text, color=True, animate="scroll", html=True) # a scroll-reveal pagerender() takes the same options as the CLI and returns the markup plus the same report as
--json. It raises ValueError for empty or oversized input and for unknown options.
Download ascii2svg.skill
from the latest release (or build it: python3 tools/package_skill.py), then:
claude.ai / Claude desktop: Customize → Skills → upload
ascii2svg.skill.Claude Code: unzip it into
~/.claude/skills/(you get~/.claude/skills/ascii2svg/).
SKILL.md tells Claude when to use it, which look fits which destination,
to add --repair for model-drawn diagrams, and how to read the report before handing you the file.
ascii2svg [INPUT ...] [-o OUT.svg|OUT.html|DIR/] [--preset NAME] [--json] [--check] [--describe] [--brief]
[--color] [--theme light|dark|auto] [--animate [draw|flow|scroll]] [--html] [--repair]
[--style glow|shadow|flat] [--square] [--accent #HEX] [--font NAME] [--width PX]
[--all-blocks] [--block N] [--unescape] [--strict] [--schema] [--mcp]
[--png [PATH]] [--text TEXT] [--tab-size N] [--title TEXT]Input | How |
File |
|
stdin |
|
Inline |
|
Markdown | The first |
stdout is always exactly one thing: the SVG (or the page, with --html), or (with --json) the
report. A one-line summary goes to stderr.
Built for agents
Every outcome is machine-readable, nothing hangs, and every problem comes with a fix. The loop: draft the diagram, check it, fix what the hints say, then render.
ascii2svg draft.txt --check --describe # validate + structure; writes nothing
ascii2svg draft.txt -o out.svg --preset readme --json --brief{"status": "warnings",
"summary": "Rendered 2 boxes and 0 arrows (8x8); 1:1 self-check exact. 1 warning, first: row 4 col 4 (dangling_line): the arrowhead 'v' at row 5 col 5 is one column right; move one of them so they line up",
"exit_code": 0, "...": "..."}One JSON object on stdout for every outcome with
--json(or--check), including usage errors:{"status": "usage_error", "hint": "'--colour': did you mean --color?"}.statusandsummarycome first, so a truncated report still says what happened.Warnings you can act on: each has a stable
code, a 1-basedrow/col, the sourceline, and ahint. When a line misses its partner by one cell, the hint says where it is.No false alarms on well-formed diagrams: a line may end at a label, meet another line side-on (sequence messages
│───▶│), or stop in open space (axis ticks, lifeline ends).--describesays what the diagram means: boxes (name, title, text, position, parent) and edges (Gateway → Orders), with akindwhere the notation says more:inheritance,aggregation,composition,relationshipwith ERcardinality(["one", "zero or many"]), orlinkfor a plain line, and thelabelset into a line (--HTTP-->). An endpoint that is not a box is the word it points at ({"text": "Postgres"}).No hangs: if you forget the input and stdin stays silent, it fails after 5 seconds with
bad_input.--schemaprints every option, preset, exit code, warning code and report field as JSON: enough to build a correct tool definition without reading docs.
As an MCP server (Claude Code, Claude Desktop, Cursor, any MCP client):
claude mcp add ascii2svg -- ascii2svg --mcp{"mcpServers": {"ascii2svg": {"command": "ascii2svg", "args": ["--mcp"]}}}Two tools, no dependencies: check_diagram validates and describes, render_diagram writes
.svg or .html with any preset or style option, and both take repair. The diagram travels as a
JSON string, so the escaped-newline problem can't happen. Tested against the official MCP Python SDK.
Field | Meaning |
|
|
| One sentence to pass on to the user |
| See exit codes; |
|
|
|
|
| With |
| With |
| What was found |
| Nodes that fold (with |
| The look that was rendered |
| Every clean-up applied (tabs, odd spaces, zero-width and control characters, colour codes, code fence, indentation, bad UTF-8, |
| Suggestions, e.g. |
| Output paths, or the markup itself when there is no |
| Only when |
Exit code | Meaning |
0 | OK (warnings allowed) |
1 | Bad input or usage: read |
2 | Self-check failed: the output is not 1:1. Don't use it |
3 |
|
Many diagrams at once:
ascii2svg README.md --all-blocks -o diagrams/ --preset readme # every diagram in the file
ascii2svg docs/*.txt -o out/ --check # several files, one report each
ascii2svg README.md --block 3 -o flow.svg # just the third code blockCode blocks without lines or boxes are skipped and listed under skipped. Every warning carries
source_line/source_col: its position in the file you passed.
As a tool in any agent framework: pass the diagram on stdin, never through --text
(escaped newlines are the most common way agents break diagrams):
import json, subprocess
def render_ascii_diagram(diagram, output_path, preset="readme", describe=False):
args = ["ascii2svg", "-", "-o", output_path, "--preset", preset, "--json", "--brief", "--repair"]
p = subprocess.run(args + (["--describe"] if describe else []), input=diagram.encode(), capture_output=True)
return json.loads(p.stdout) # always one JSON object, including on errorsRoadmap
Boxes, arrows and junctions, in ASCII and Unicode, verified 1:1
Colour, light/dark/auto themes, draw and flow animation, scroll-reveal pages
Agent CLI: JSON reports, hints,
--describe, presets,--schema, MCP server, Claude skillBrowser playground (Pyodide), with share links and PNG export
--repairfor LLM-drawn diagramsBlock-element charts, diagonals and diamonds, dashed lines, UML heads, ER crow's feet
ER crow's feet on vertical connectors (
-+-ticks,orings,/|\and\|/feet)ASCII UML heads (
<|--<>--*--) and ASCII dashed and dotted lines (- - ->....>:)Repairing bigger misalignments: boxes that must grow, walls and edges up to 12 columns off, lines split 3-6 apart, arrows that stop short
ASCII rounded corners and bends (
.--.'--')Arrows between plain words (
A --> B,A --HTTP--> B,|andvunder a label)Vertical ASCII UML heads (
/_\<>*under or over a box)On npm:
@satyadip28/asciitosvg, the same module in WebAssembly, byte-identical by testTrees and mind maps that fold (
--interactive,--preset explore), a colour per branch, ASCIItreeoutput,--describetreesSVGs about half the size: a
<text>per word, one path per line style, a lighter glow
Everything planned has shipped. Have an idea, or a diagram that doesn't render the way you meant? Open an issue.
Contributing
Issues and pull requests are welcome, and a diagram that renders wrongly is the most useful bug report there is: paste the text and say what you expected.
python3 tests/test_ascii2svg.py # 73 tests over 36 test diagrams (or: python3 -m pytest tests)
cd npm && npm install && npm test # the npm package: byte-identical to Python on every test diagram
python3 docs/build.py # regenerate every image on this page and the playground filesNew shapes come with a test diagram in tests/fixtures/, and every fixture
must round-trip exactly in every style and look. That's the one rule: never a wrong picture.
round-trip in every style and every look; animation that ends on the static drawing and respects reduced motion
flow routes that start at the right box; scroll reveal driven by the page, with no script inside the SVG
colour groups; glow never behind a label; planted faults that must be caught; byte-identical repeat runs
the ASCII traps; width fallback vs
wcwidth; UTF-8 output on Windows consoles; therender()library APIthe agent contract: JSON usage errors, status and summary, near-miss hints, escaped-newline and broken-box detection,
--describeedges, presets,--schema, no hang on a forgotten inputevery diagram in a markdown file, several inputs, positions mapped back to the file, the MCP protocol
the browser playground runs exactly this module, and every playground example round-trips
no false alarms on sequence diagrams, timelines, charts and dashed boundaries; real mistakes still warn
--repair: every LLM fixture repaired took, text provably unchanged, good diagrams untouched; a box grows for a long label or emoji, a split line is joined (never doubled), a short arrow reaches its boxblock elements as exact rectangles;
/ \only as runs, never insideyes/noorC:\Usersdashed lines keep their dash count, form boxes and carry arrows; ASCII
- - ->,....>and:too, whileLoading..., dot leaders and- - -stay text; ASCII UML heads<|<>*are drawn and describedUML triangles and diamonds, ER ticks, rings and crow's feet across and up and down;
--describenames each relationship and its cardinalitytrees: call trees,
npm ls,cargo tree,tree,pipdeptree, Maven, Gradle,pstreeand Windowstreeoutput, left-to-right mind maps and box fan-outs read into the right hierarchy; flowcharts and timelines are not trees; an interactive SVG is the static drawing plus a script; fold data is escaped; branch colours only on pure trees; PNG frames place every character aloneASCII UML heads up and down (
/_\<>*), drawn and described; rounded ASCII boxes and bends; arrows between plain words and labels set into lines, whilea-->b,x -> y,p->next,--dry-run, markdown tables andprint(" -->")stay text
They pass with and without the optional packages.
License
MIT. Use it, change it and ship it, commercially too; keep the copyright notice.
Available Tools
2 toolscheck_diagramA
Validate an ASCII/Unicode box diagram without writing anything. Returns 'status', 'summary', warnings with concrete 'hint's (e.g. 'the arrowhead v at row 5 col 5 is one column right'), and the structure: boxes and edges (which box each arrow connects). Use it to confirm a diagram means what you intended before rendering.
| Name | Required | Description | Default |
|---|---|---|---|
| repair | No | Also fix typical misalignment; report.repair lists the edits and report.repair.text is the corrected diagram | |
| diagram | Yes | The diagram as plain text with real line breaks (a markdown code block is fine). Boxes: +--+ / | | / +--+ or ┌─┐ │ │ └─┘. Arrows end in v ^ < > or ▼ ▲ ▶ ◀ touching (or one space from) the box they point at. | |
| describe | No | Include boxes and edges (default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It clearly states the tool is non-writing, describes the return structure (status, summary, warnings with hints, boxes/edges), and provides an example of a hint. This is solid disclosure for a read-only validation tool, though it omits potential error conditions or edge cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long, front-loaded with the core action and output. The only minor redundancy is 'without writing anything' and 'before rendering', which both emphasize non-mutating behavior. Overall, every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter tool with 100% schema coverage and no output schema, the description covers the main purpose, return values, and usage timing. It does not describe error handling or repair specifics, but those are covered by the schema. The description is sufficiently complete for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description adds little beyond the schema: it mentions boxes/edges and an example hint, but these are already implied by the schema descriptions. No new parameter meaning is introduced.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Validate' with a clear resource 'ASCII/Unicode box diagram', and explicitly states it does so 'without writing anything', distinguishing it from the sibling render_diagram. The purpose is immediately clear and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Use it to confirm a diagram means what you intended before rendering', which gives a clear contextual trigger. It implies but does not explicitly name render_diagram as the alternative, and offers no 'when not to use' conditions, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
render_diagramA
Render an ASCII/Unicode box diagram as SVG (or a web page), keeping every character in its exact cell. Writes output_path and returns a JSON report: read 'status' (ok | warnings | self_check_failed | bad_input) and 'summary'. For warnings, apply each 'hint' (it names the row/col to fix) and render again. Pick 'preset' from where the diagram is going. Run check_diagram first on a new diagram.
| Name | Required | Description | Default |
|---|---|---|---|
| fold | No | With interactive: start with nodes at this depth folded | |
| font | No | Font family to try first, e.g. JetBrains Mono | |
| color | No | Tint boxes by group and colour the arrows | |
| style | No | ||
| theme | No | ||
| title | No | Accessible title stored in the output | |
| width | No | Scale the output to this width in pixels | |
| accent | No | Accent colour for arrows and animation, e.g. #0969da | |
| preset | No | readme: GitHub/docs, animated, follows dark mode · slides · chat · print · dark · page: a web page that reveals as you scroll (needs a .html path) | |
| repair | No | Fix typical misalignment first (ragged walls, drifting connectors, short arrows); the fixed text is in report.repair.text | |
| square | No | Square box corners | |
| animate | No | ||
| diagram | Yes | The diagram as plain text with real line breaks (a markdown code block is fine). Boxes: +--+ / | | / +--+ or ┌─┐ │ │ └─┘. Arrows end in v ^ < > or ▼ ▲ ▶ ◀ touching (or one space from) the box they point at. | |
| describe | No | Also return boxes and edges (which box each arrow connects) | |
| portable | No | One <text> per character, for design tools such as Inkscape or Figma (browsers don't need it) | |
| interactive | No | Trees and mind maps fold when clicked (in a browser; as an image it is the full drawing) | |
| output_path | No | File to write: .svg, or .html for a web page. Prefer an absolute path. Omit to get the markup back. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It covers the side effect of writing output_path, the JSON report contract with statuses, and the warning remediation workflow via 'hint'. It could elaborate on bad_input/self_check_failed handling, but the disclosed behavior is substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five short sentences, each carrying distinct information: core purpose, side effect and return contract, warning handling, preset selection, and prerequisite. The most important information is front-loaded and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 17-parameter tool with no output schema, the description covers the core workflow, expected report shape, and prerequisite validation step. It does not enumerate every parameter, but the schema handles those details; minor gaps remain around what happens on self_check_failed or bad_input beyond reading the status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 82%, so the schema already documents most parameters. The description adds useful semantic context for preset ('Pick preset from where the diagram is going') and diagram ('keeping every character in its exact cell'). It does not explain all styling parameters, but the schema covers those adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete verb and resource: 'Render an ASCII/Unicode box diagram as SVG (or a web page)'. It also adds a precise scope constraint, 'keeping every character in its exact cell', and distinguishes itself from the sibling by saying 'Run check_diagram first on a new diagram'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context: run check_diagram first on a new diagram, and pick preset based on where the diagram is going. It does not explicitly state when not to use render_diagram, but the check-versus-render split is strongly implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.17.0- Changed
render_diagram4 fields changed- added
Input schema / properties / foldAdded value: +{ + "description": "With interactive: start with nodes at this depth folded", + "type": "integer" +} - added
Input schema / properties / interactiveAdded value: +{ + "description": "Trees and mind maps fold when clicked (in a browser; as an image it is the full drawing)", + "type": "boolean" +} - added
Input schema / properties / portableAdded value: +{ + "description": "One <text> per character, for design tools such as Inkscape or Figma (browsers don't need it)", + "type": "boolean" +} - changed
Input schema / properties / preset / enumPrevious value: -[ - "readme", - "slides", - "chat", - "print", - "dark", - "page" -]New value: +[ + "readme", + "slides", + "chat", + "print", + "dark", + "page", + "explore" +]
2 tool updates
v1.15.0- First observed
check_diagram - First observed
render_diagram
TDQS
Scored across 2 tools
Each tool has a single, distinct role in the pipeline: check_diagram validates and reports diagnostics, while render_diagram writes the output file. There is no overlap or ambiguity about which tool to call for a given step.
Both tool names follow the same verb_noun snake_case pattern: check_diagram and render_diagram. The action-object relationship is immediately clear and consistent.
Two tools is slightly below the typical 3-15 range, but for this narrow ASCII-to-SVG purpose the count is reasonable and each tool is essential to the workflow. It feels minimal rather than padded.
The validate-then-render lifecycle is fully covered: check_diagram provides structural feedback and hints, and render_diagram produces the output with a status report. There are no obvious missing operations for the stated domain.
Maintenance
Related MCP Connectors
Generate and vectorize clean, editable SVG graphics from text, images, or both.
Create and edit architecture diagrams from your AI agent; get an SVG and a live editable canvas.
Render, validate, encode/decode PlantUML diagram-as-code; 22 diagram types. Free, no auth.
Render, verify, describe, and safely edit Mermaid diagrams through MCP.
Related MCP Servers
- FlicenseAqualityCmaintenanceExposes ASCIIFlow drawing primitives as tools to enable AI assistants to generate ASCII wireframes and diagrams from natural language descriptions. It provides commands for creating canvases and drawing boxes, lines, arrows, and text using a character-grid coordinate system.82-
- AlicenseNot gradedqualityDmaintenanceEnables creating and iterating on animated SVG diagrams from text input, photos of sketches, and YAML specifications, with support for shapes, connections, SMIL animations, and file output.1MIT
- AlicenseBqualityBmaintenanceEnables AI assistants to create, animate, and export ASCII art using natural language, with live browser sync.96116 npm9MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI to create ASCII and SVG art through a character canvas, with tools for drawing, previewing, and exporting to multiple formats, as well as composing stop-motion animations with optional voice-over.MIT