Skip to main content
Glama
README.md
# scribbleviz-mcp

> An [MCP](https://modelcontextprotocol.io) server that turns structured input into **hand-drawn "study-notes" style** graphics — charts, concept maps, mind maps, timelines, sketch notes and 2×2 matrices — rendered with matplotlib's `plt.xkcd()` wobble.

<p align="center">
  <img src="docs/images/swot_icons.png" alt="SWOT matrix with hand-drawn icons" width="640">
</p>

Give an LLM client a loose brief; it picks the right format and calls the matching tool. Everything is drawn procedurally in the sketch style — including the icons — so it all shares the same tremulous, notebook look. **No files are written to disk**: each tool renders to an in-memory buffer and returns a native MCP `ImageContent` (base64 PNG).

## Features

- **6 formats** — bar/hbar/pie/line charts, concept maps, radial mind maps, timelines, post-it sketch notes, 2×2 quadrant matrices (SWOT, Eisenhower, …).
- **Hand-drawn icons** — 20 procedural icons (`star`, `bulb`, `check`, `warning`, `target`, …) usable on **every** tool, via a parallel `icons` list or inline `[name]` tokens in labels.
- **6 color palettes** — `notebook` (default), `sepia`, `blueprint`, `forest`, `candy`, `mono` — plus fully custom colors.
- **Zero disk I/O** — renders to `io.BytesIO`, returns base64 PNG as MCP `ImageContent`.
- **Tiny footprint** — one file, two dependencies (`mcp`, `matplotlib`).

## Gallery

| Line chart w/ stars | Bar chart w/ icons |
|:---:|:---:|
| ![line](docs/images/line_stars.png) | ![bar](docs/images/bar_icons.png) |

| Sketch note | Timeline |
|:---:|:---:|
| ![note](docs/images/sketch_note.png) | ![timeline](docs/images/timeline.png) |

## Requirements

- Python **3.10+**
- [`mcp`](https://pypi.org/project/mcp/) (SDK 2.x; falls back transparently to 1.x)
- `matplotlib` 3.8+

## Install

```bash
git clone https://github.com/cadeos/scribbleviz-mcp.git
cd scribbleviz-mcp
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```

> **Handwritten font (optional).** If a handwriting font (e.g. *xkcd Script*, *Humor Sans*, *Comic Neue*) is installed on your system the text uses it; otherwise it falls back to the default font while keeping the xkcd stroke. The benign `findfont` warning can be ignored.

## Quick start

The server speaks the standard MCP **stdio** transport, so it works with any MCP-compatible client (Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, your own agent, …). Run it directly:

```bash
python server.py
```

Or explore it interactively with the MCP Inspector:

```bash
mcp dev server.py
```

### Register it in an MCP client

Almost every client uses the same JSON shape — a command to launch plus its arguments. Point `command` at the venv's Python so `mcp` and `matplotlib` are on the path, and use **absolute** paths:

```json
{
  "mcpServers": {
    "scribbleviz": {
      "command": "/absolute/path/to/scribbleviz-mcp/.venv/bin/python",
      "args": ["/absolute/path/to/scribbleviz-mcp/server.py"]
    }
  }
}
```

On Windows use `.venv\\Scripts\\python.exe`. Some clients nest this under a different top-level key (e.g. `"servers"` or `"mcp.servers"`) — the `command`/`args` pair is the part that stays the same. Where each client stores its config:

| Client | Config location |
|---|---|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) · `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
| Cursor | `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per-project) |
| Cline / Continue / Zed / Windsurf | see each client's "MCP servers" settings; paste the same `command` + `args` |

After saving, restart (or reload) the client; the six `generate_*` tools appear in its tool list.

## Tools

Every tool accepts the common parameters `palette`, `roundness`, `colors`, `font`, `icons`, `background`.

| Tool | Purpose | Key parameters |
|---|---|---|
| `generate_sketch_chart` | Quantitative chart | `chart_type` (`bar`\|`hbar`\|`pie`\|`line`), `title`, `labels`, `values`, `x_label`, `y_label` |
| `generate_concept_map` | Concept map (nodes + relations) | `title`, `nodes`, `edges`, `directed` |
| `generate_mind_map` | Radial mind map | `title`, `central_topic`, `branches` |
| `generate_timeline` | Dated timeline | `title`, `events` |
| `generate_sketch_note` | Post-it study card | `title`, `sections` |
| `generate_quadrant` | 2×2 matrix (SWOT, …) | `title`, `quadrants`, `x_axis`, `y_axis`, `headings_outside`, `icon_focus` |

Each returns an MCP `ImageContent` (base64 PNG, `image/png`) on success, or a `TextContent` error message when the input is malformed.

### Icons

Add hand-drawn icons in two interchangeable ways (a parallel list wins over an inline token for the same label):

```jsonc
// parallel list — "" skips a label
{ "chart_type": "line", "title": "Sales", "labels": ["Q1","Q2","Q3","Q4"],
  "values": [12,18,15,27], "icons": ["", "", "", "star"] }

// inline token — stripped from the displayed text
{ "title": "Roadmap", "events": [["Jan","Kickoff [flag]"], ["Jun","Release [star]"]] }
```

Available icons: `arrow_down`, `arrow_up`, `bolt`, `book`, `bulb`, `check`, `clock`, `cross`, `drop`, `flag`, `gear`, `heart`, `home`, `leaf`, `pin`, `plus`, `star`, `sun`, `target`, `warning`.

For `generate_quadrant`, `icon_focus=true` renders each quadrant's icon **large and centered** (title on top, no bullet list) — ideal for an all-icon SWOT.

### Palettes

`notebook` (default) · `sepia` · `blueprint` · `forest` · `candy` · `mono`. Pass a list to `colors` for a fully custom series (box tints are derived automatically for readability).

Set `background` to override the page color — any matplotlib color (e.g. `"white"`, great for embedding on Medium or light docs) or `"transparent"` for an alpha PNG. Empty keeps the palette's paper.

## License

[MIT](LICENSE)