Skip to main content
Glama

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 // --repair lines 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.

  • 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, animation

From 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_arrow warns about it first).

As the model wrote it

--repair

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.

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

Print

Alive

(no options)

--color

--theme dark--color

--style flat--square

--animate--color--theme auto

Or let the destination decide: --preset readme|slides|chat|print|dark|page.

Destination

Use

GitHub README, docs site

--preset readme (--theme auto --color --animate), then commit the .svg

A tall diagram people scroll through

--preset page → an .html page that reveals as you scroll

Slides (Keynote, Google Slides, PowerPoint)

--color --animate draw for a live build; --color --png for a still

Slack, email, Jira: anywhere SVG isn't shown

--color --png (needs pip install cairosvg)

Printed docs, a PDF

--style flat --square

Dark-mode apps

--theme dark --color

Option

What it does

--color

Soft tints grouped by what contains what: each top-level group gets its own hue, nested boxes keep it. Arrows turn accent blue.

--theme light|dark|auto

auto follows the reader's system light/dark setting, which suits GitHub READMEs and docs sites.

--animate draw

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.

--animate flow (or bare --animate)

draw, then glowing pulses keep travelling along every connector toward its arrowhead.

--animate scroll

For tall diagrams, as a web page: each part appears as the reader scrolls to it, and long connectors grow with the scroll.

-o page.html (or --html)

A standalone web page with the diagram inline. Double-click to open, or email it.

--style glow|shadow|flat

Depth under the boxes. The glow shrinks automatically so it never sits behind a label.

--square

Keep corners square (they are rounded by default).

--repair

Fix typical misalignment first (see LLM diagrams, fixed).

--accent #hex · --font NAME · --width PX

Your brand colour for arrows and animation, a font to try first (e.g. JetBrains Mono), and the output width.

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.

  • draw and flow need 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.

  • scroll is 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

--repair fixes it and says what moved

–

shows the mistakes

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 + junctions

stay text

ASCII rounded corners . above, ' or ` below

they close a box (.--. over '--'), or bend a connector that is drawn (---. over |)

stay text (It's, a.b, tree output)

ASCII lines between plain words: A --> B, A --HTTP--> B, | and v under a label

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 (a-->b, x -> y, p->next, --dry-run)

ASCII v ^ < >

they end a line that is drawn, or point at a box (touching, or one space away)

stay text

╱ ╲ ╳, 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 <| |> <> *, and /_\ <> * on a vertical line

on a line that touches a box (across, or one space short), or right against a box's top or bottom edge with | or : on the other side: inheritance, aggregation, composition

stay text

ASCII dashed - - -> and dotted ....> -.-.->, : down a column

they join a box or end in an arrowhead that points into one; flow pulses hop the gaps

stay text (Loading..., dot leaders, - - -)

UML heads △ ▽ ◁ ▷ ◇ ◆

a line joins them: triangles touch the parent, diamonds sit on the whole

stay text (bullets, symbols)

ER marks | o < > { }, and -+- o /|\ `\

/` on vertical lines

on a connector between two boxes: across (+--||--o<, even with a foot set in the wall) or up and down

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 readme
import { 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 page

render() 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

ascii2svg diagram.txt -o out.svg

stdin

cat diagram.txt | ascii2svg > out.svg

Inline

ascii2svg --text "$DIAGRAM" --json (the SVG comes back inside the JSON when there's no -o)

Markdown

The first ``` code block is used; --all-blocks renders every diagram in the file

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?"}. status and summary come first, so a truncated report still says what happened.

  • Warnings you can act on: each has a stable code, a 1-based row/col, the source line, and a hint. 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).

  • --describe says what the diagram means: boxes (name, title, text, position, parent) and edges (Gateway → Orders), with a kind where the notation says more: inheritance, aggregation, composition, relationship with ER cardinality (["one", "zero or many"]), or link for a plain line, and the label set 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.

  • --schema prints 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

status

ok · warnings · self_check_failed · bad_input · usage_error

summary

One sentence to pass on to the user

exit_code, ok

See exit codes; ok is false only when the self-check failed

roundtrip

exact: the output was read back and matches the input cell for cell

warnings

{code, row, col, char, line, issue, hint}; codes: dangling_line, broken_join, short_arrow, unclosed_box, escaped_newlines, no_structure

diagram

With --describe: {boxes: [...], edges: [{from, to, kind?, cardinality?, label?}]}; an endpoint is {box, name}, {text} or {cell}

repair

With --repair: {edits: [{line, col, fix}], text}

rows, cols, boxes, arrowheads, flows, text_cells

What was found

style, theme, color, animate, html, preset

The look that was rendered

normalized

Every clean-up applied (tabs, odd spaces, zero-width and control characters, colour codes, code fence, indentation, bad UTF-8, --unescape)

tips

Suggestions, e.g. --animate scroll when a timed animation would finish off-screen

svg / html, png

Output paths, or the markup itself when there is no -o (unless --brief / --check)

self_check_problems

Only when roundtrip isn't exact

Exit code

Meaning

0

OK (warnings allowed)

1

Bad input or usage: read error and hint

2

Self-check failed: the output is not 1:1. Don't use it

3

--strict and there were warnings

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 block

Code 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 errors

Roadmap

  • 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 skill

  • Browser playground (Pyodide), with share links and PNG export

  • --repair for LLM-drawn diagrams

  • Block-element charts, diagonals and diamonds, dashed lines, UML heads, ER crow's feet

  • ER crow's feet on vertical connectors (-+- ticks, o rings, /|\ 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, | and v under a label)

  • Vertical ASCII UML heads (/_\ <> * under or over a box)

  • On npm: @satyadip28/asciitosvg, the same module in WebAssembly, byte-identical by test

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        # 65 tests over 32 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 files

New 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; the render() library API

  • the agent contract: JSON usage errors, status and summary, near-miss hints, escaped-newline and broken-box detection, --describe edges, presets, --schema, no hang on a forgotten input

  • every 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 to ok, 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 box

  • block elements as exact rectangles; / \ only as runs, never inside yes/no or C:\Users

  • dashed lines keep their dash count, form boxes and carry arrows; ASCII - - ->, ....> and : too, while Loading..., dot leaders and - - - stay text; ASCII UML heads <| <> * are drawn and described

  • UML triangles and diamonds, ER ticks, rings and crow's feet across and up and down; --describe names each relationship and its cardinality

  • ASCII UML heads up and down (/_\ <> *), drawn and described; rounded ASCII boxes and bends; arrows between plain words and labels set into lines, while a-->b, x -> y, p->next, --dry-run, markdown tables and print(" -->") 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 tools
check_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
repairNoAlso fix typical misalignment; report.repair lists the edits and report.repair.text is the corrected diagram
diagramYesThe 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.
describeNoInclude boxes and edges (default true)

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fontNoFont family to try first, e.g. JetBrains Mono
colorNoTint boxes by group and colour the arrows
styleNo
themeNo
titleNoAccessible title stored in the output
widthNoScale the output to this width in pixels
accentNoAccent colour for arrows and animation, e.g. #0969da
presetNoreadme: GitHub/docs, animated, follows dark mode · slides · chat · print · dark · page: a web page that reveals as you scroll (needs a .html path)
repairNoFix typical misalignment first (ragged walls, drifting connectors, short arrows); the fixed text is in report.repair.text
squareNoSquare box corners
animateNo
diagramYesThe 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.
describeNoAlso return boxes and edges (which box each arrow connects)
output_pathNoFile to write: .svg, or .html for a web page. Prefer an absolute path. Omit to get the markup back.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does well: it discloses file-writing side effects ('Writes output_path'), the exact JSON report structure ('status' with its four possible values, plus 'summary'), and the hint/repair mechanism. The only gap is not stating whether an existing output_path file is overwritten or whether rendering is destructive to input.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each earning its place: purpose, behavior, warning-handling workflow, and sibling routing. Purpose is front-loaded. It is compact for a 14-parameter tool and avoids redundancy with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 14 parameters, no output schema, and no annotations, the description covers the critical workflow well: return format, status values, hint loop, and preset selection. It doesn't explain every parameter, but the schema covers 79% of them and the core rendering/checking loop is fully specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 79%, so the schema already documents most parameters in detail (preset enums with platform notes, output_path formats, diagram syntax). The description adds workflow-level context (pick preset by destination, run check first) but adds little param-level semantics beyond what the schema provides, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Render'), resource ('ASCII/Unicode box diagram'), and output format ('as SVG (or a web page)'), plus a precise constraint ('keeping every character in its exact cell'). This clearly differentiates it from the sibling check_diagram, whose purpose is validation, not rendering.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs the agent to 'Run check_diagram first on a new diagram', naming the alternative and the precondition that selects it. It also gives concrete workflow guidance for post-render handling ('For warnings, apply each hint... and render again') and parameter selection ('Pick preset from where the diagram is going'). Nothing is left to inference.

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. 2 tool updatesv1.15.0
    • First observedcheck_diagram
    • First observedrender_diagram

TDQS

A4.3/5.0

Scored across 2 tools

Disambiguation5/5

Each tool has a distinct role: one validates the diagram structure and meaning, the other renders it to SVG. The descriptions are explicit about when to use each, and render_diagram even instructs running check_diagram first, eliminating ambiguity.

Naming Consistency5/5

Both tool names follow a consistent verb_noun pattern: check_diagram and render_diagram. The verb clearly conveys the action while the shared noun signals the common domain.

Tool Count3/5

With only two tools, the server feels minimal, but for a focused ascii-to-svg conversion task the validate-then-render workflow is reasonable. It is borderline thin rather than excessively small.

Completeness5/5

The tool set covers the full intended workflow: optionally validate a diagram, then render it to SVG or a web page. It provides feedback and hints for fixing issues, so there are no obvious dead ends for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers