ASCIICHARTS

An agent skill for charts made of text — drawn right

Ask Claude for a chart in a reply, a PR, a commit message or a terminal: bars, lines, sparklines, histograms, pies, heatmaps — lengths that match the values, frames that stay straight in any font, series you can tell apart without color. It draws them by hand from the principles, or renders them exactly when a renderer is at hand.

Claude Codea plugin, from the repository's own marketplace; it updates itself
in a session
/plugin marketplace add boligolov/asciicharts
/plugin install asciicharts@asciicharts
from a shell — an agent can run it
claude plugin marketplace add boligolov/asciicharts
claude plugin install asciicharts@asciicharts
Claude.ai · Claude Desktopupload under Settings → Capabilities → Skills
Any agent that reads skill foldersunpack the folder into ~/.claude/skills (or the agent's own skills folder)
macOS · Linux
curl -fsSL https://asciicharts.online/asciicharts.skill -o /tmp/asciicharts.zip
mkdir -p ~/.claude/skills && unzip -o /tmp/asciicharts.zip -d ~/.claude/skills
Windows · PowerShell
Invoke-WebRequest https://asciicharts.online/asciicharts.skill -OutFile $env:TEMP\asciicharts.zip
Expand-Archive $env:TEMP\asciicharts.zip $env:USERPROFILE\.claude\skills -Force

Then just ask for a chart. More on installing

hbar · grouped
╭──────────────────────────────────────────────────────────────────────╮
│                       Build time by stage (s)                        │
├──────────────────────────────────────────────────────────────────────┤
│ Compile                                                              │
│   before caching │ ██████████████████████████████████████████████ 64 │
│   after caching  │ █████████████████████████████░░░░░░░░░░░░░░░░░ 40 │
│                                                                      │
│ Test                                                                 │
│   before caching │ ███████████████████████░░░░░░░░░░░░░░░░░░░░░░░ 32 │
│   after caching  │ ████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 22 │
│                                                                      │
│ Lint                                                                 │
│   before caching │ ████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 16 │
│   after caching  │ ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 10 │
│                                                                      │
│ Package                                                              │
│   before caching │ ██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8  │
│   after caching  │ ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5  │
╰──────────────────────────────────────────────────────────────────────╯╭──────────────────────────────────────────────────────────────────────╮
│                       Build time by stage (s)                        │
├──────────────────────────────────────────────────────────────────────┤
│ Compile                                                              │
│   before caching │ ██████████████████████████████████████████████ 64 │
│   after caching  │ █████████████████████████████░░░░░░░░░░░░░░░░░ 40 │
│                                                                      │
│ Test                                                                 │
│   before caching │ ███████████████████████░░░░░░░░░░░░░░░░░░░░░░░ 32 │
│   after caching  │ ████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 22 │
│                                                                      │
│ Lint                                                                 │
│   before caching │ ████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 16 │
│   after caching  │ ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 10 │
│                                                                      │
│ Package                                                              │
│   before caching │ ██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8  │
│   after caching  │ ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5  │
╰──────────────────────────────────────────────────────────────────────╯

Real render_chart() output, frame and title included — flip MONO / COLOR or BLACK / WHITE right on the chart.

// knowledge first

The principles

asciicharts principles v1.4 — how to build charts out of text characters right, for a person, an agent, or a port to another language. A chart conforms when it meets the requirements; a renderer conforms when it reproduces theconformance suitebyte for byte. Licensed CC BY 4.0: use them, adapt them, build on them — with credit.

A grid of equal cells

A text chart is a rectangle of cells, one glyph each. Lengths are counted in cells — never eyeballed — and every line has the same display width: CJK counts two columns, a combining accent none.

Glyphs every font has

A glyph missing from the reader's font is borrowed from another one and breaks the alignment. The safe alphabet is WGL4 — whole █ blocks, light box lines, four shades — plus a pure-ASCII mode for anywhere.

Arithmetic, written down

cells = round(v / max × W), half away from zero. A non-zero value never disappears. Stacks split by the largest remainder, so equal totals get equal lengths.

Zero is an axis

Negative values grow the other way from a zero line that belongs to no bar — stacked bars too — so +3 and −3 are the same length and zero draws nothing.

Identity without color

Text often has no color. Every series gets its own glyph, densest first, and a legend with the same glyph; numbers are printed wherever the grid is only approximate.

Every rule has a reason

Each rule is tied to the mistake that made it: a pie slice that vanished, a label that read −28.00 for −28, a boxplot median missing from Consolas. Normative requirements, MUST and SHOULD, in §15.

READ THE PRINCIPLES ▸

// the reference implementations

Two, byte for byte

Go — one static binary for the command line, a library, an MCP server — and Python, one standard-library file. Both pass the conformance suite and agree on tens of thousands of random specs.

Deterministic

A pure function of the spec: no clock, no randomness, no terminal probing. Same input, same bytes — safe to snapshot, diff and commit.

Built to be called by machines

Strict, bounded input and one-line errors that say what to fix — error: row 3, column "v" is not a number: "n/a" — so a script or an agent can correct itself. Text from untrusted data can't smuggle escape codes into a terminal.

Gets the hard cases right

Negative values grow both ways from a zero line, stacked ones too. Dirty CSV numbers ($1,200, 12%, decimal commas) are parsed, not silently dropped. Labels in any script — 東京, été, 🍕 — keep the frame straight.

Font-safe by default

Whole █ blocks, glyphs even Consolas has, a pure-ASCII mode for terminals and mail. No ragged right edges.

No side effects

The renderer writes nothing and opens no sockets. The server is stateless and records nothing.

// four ways in

Pick the one that fits

Agent skill

Claude Code and other agents

Teaches an agent to draw a correct text chart by hand — lengths computed, rows counted, then checked — and to use a renderer when there is one.

/plugin marketplace add boligolov/asciicharts
/plugin install asciicharts@asciicharts

Command line

scripts, CI, terminals

One static binary (Go), or one Python file. A JSON spec or a CSV file in, a chart out.

$ achart --csv latency.csv \
--chart hbar --sort -p99 --limit 3

Library

Go and Python programs

The same renderer in your code: a pure function from a spec to a string, standard library only.

>>> from asciicharts import render_chart
$ go get github.com/boligolov/asciicharts/go

MCP server

any MCP client, one shared deployment

Two tools: list_charts (the catalogue) and render_chart. stdio or stateless streamable HTTP. One static Go binary.

$ go install github.com/boligolov/asciicharts/go/cmd/asciicharts-mcp@latest
$ claude mcp add asciicharts -- asciicharts-mcp
v1.4
PRINCIPLES
455
CONFORMANCE CASES
2
IMPLEMENTATIONS
12
CHART TYPES