Skip to main content
Glama
README.md
# Tired of badly formatted markdown? Give your LLM a canvas. 🎨

**jarbobo** lets Claude (or any MCP client) draw **real, interactive diagrams inside your editor** β€”
not ASCII art, not a mermaid string it hallucinated half the syntax for, not a PNG in another tab.

Graphs, UML sequence diagrams, and class diagrams that live in Cursor as first-class tabs, where
**every node is a live pointer into your code**: hover it for the gist, click it and your editor
jumps to the exact `file:line`.

[![jarbobo demo β€” click to watch the full video](assets/poster.png)](assets/demo.mov)

*Above: exploring pybind11's internals β€” **click the image to watch the full demo** (0:14).
The diagram was drawn by Claude via MCP; clicking `struct internals` focuses `internals.h:302`
in the editor.*

---

## Why this exists

LLMs are great at *explaining* systems and terrible at *showing* them. Markdown gives them bullet
points; mermaid gives them a syntax to typo. jarbobo gives them a canvas with an interactivity
contract:

| The LLM sets… | You get… |
|---|---|
| `tooltip` | hover text on any node, edge, message, or class |
| `detail` | click β†’ side panel with the full explanation (lockable πŸ”’, click-outside to close) |
| `file` + `line` | **click β†’ your editor opens that source line** (⌘-click skips the detail panel and jumps straight there; hold βŒƒ while hovering to highlight the reference) |
| `refs` | an **ordered list** of code references per element β€” the click panel shows each one's actual code, **syntax-highlighted from disk**; opening one highlights its line `ranges` in the editor (disjoint ranges welcome: a signature + the interesting call site) |
| `href` | click β†’ docs / PR / dashboard |

Plus the viewer mechanics you'd expect from a real tool:

- πŸ—‚ **one tab per diagram** β€” compare views side by side, tear a tab out into its own window
- πŸ” **pan & zoom** β€” right-drag pans, scroll pans, ⇧-scroll pans horizontally, ⌘-scroll zooms
- 🧲 **persistent layouts** β€” drag nodes around; the arrangement survives close & reopen
- 🎯 **ref-target toggle** β€” open clicked references in the main code window or next to the diagram
- πŸ“Š **status bar** β€” `jarbobo: idle` / `jarbobo: 3 diagrams`, click for history

## The three tools

- **`draw_graph`** β€” architecture, dataflow, call graphs, state machines. Layered/force/grid/circle
  layouts, shapes (box, ellipse, diamond, hexagon, cylinder), labelled group containers for
  boundaries ("CPython interpreter" vs "your .so"), styled edges (solid/dashed/dotted, colors).
- **`draw_sequence_diagram`** β€” UML sequence: box/actor/database participants, sync/async/reply/self
  messages with automatic activation bars, side notes, and `loop / alt / opt / par` frames.
- **`draw_class_diagram`** β€” UML classes: Β«stereotypesΒ», attributes & methods with `+ - # ~`
  visibility, and honest UML relations β€” inheritance β–·, implements β‡’β–·, composition β—†,
  aggregation β—‡, association, dependency β‡’ β€” with cardinality labels.
- **`draw_swimlane_diagram`** β€” cross-functional flows: steps divided into lanes by owner
  (service, team, thread), horizontal or vertical, with automatic step ordering from the
  edges; box/diamond/ellipse steps and styled cross-lane edges.
- **`draw_timeline`** β€” milestones β—† and phase spans β–¬ on a categorical ordered axis
  (dates, versions, quarters β€” anything), with optional labelled tracks: release
  histories, migration plans, roadmaps, incident timelines.
- **`list_diagrams`** / **`open_diagram`** β€” enumerate saved diagrams and re-display any
  version of one (also returns its spec, so the LLM can roll back or build on it).
- **`export_diagram`** β€” export a diagram to a portable file: **Mermaid**, **draw.io**
  (diagrams.net, editable), **Graphviz DOT**, **LaTeX/TikZ**, or raw **JSON**. Rendered
  **SVG**, **PNG**, and self-contained **interactive HTML** (clickable elements with
  embedded, syntax-highlighted code snippets) are exported from the panel itself β€” via the
  titlebar **export** button or the **β€œJarbobo: Export Diagram…”** command β€” since they need
  the live layout.

**Edits are versioned.** Every draw call without an `id` creates a new diagram (new tab)
and returns its id; passing the id back **edits** it β€” the content saves as the next
version and the *existing tab updates in place*. A version picker in the panel's titlebar
lets you flip back to any older version; nothing is ever overwritten.

Validation is strict (unknown node ids, bad frame ranges β†’ the tool call fails with a fixable
message), so the LLM can't silently draw a broken picture.

**Code references are required by default.** A draw call is rejected when primary elements
(graph nodes, sequence messages, classes, swimlane steps, timeline items) carry neither a
`file`+`line` reference nor an explicit `noRef: true` opt-out β€” the rejection message tells
the LLM exactly which elements to fix, so it corrects itself in one round trip. Using jarbobo
for non-coding diagrams? Turn the check off:

```jsonc
// ~/.jarbobo/config.json
{ "requireCodeReferences": false }
```

## Quick start

```bash
git clone git@github.com:tch1001/jarbobo.git && cd jarbobo
npm install && npm run compile && npm run vendor
npx vsce package --allow-missing-repository
cursor --install-extension jarbobo-0.1.0.vsix     # or: code --install-extension …
```

**Stock VS Code 1.101+**: that's it β€” the extension self-registers its bundled MCP
server via `vscode.lm.registerMcpServerDefinitionProvider`, running on the editor's
own Node (`process.execPath`), so there's nothing else to configure.

**Cursor** doesn't implement that registration API yet ([tracked on the Cursor
forum](https://forum.cursor.com/t/support-vs-codes-register-mcp-server-definition-provider-api/133031)),
so register the server by hand:

```jsonc
// ~/.cursor/mcp.json
{
  "mcpServers": {
    "jarbobo": { "command": "node", "args": ["<abs-path>/jarbobo/out/mcp-server.js"] }
  }
}
```

```bash
# Claude Code β€” same manual step, any client that lacks the registration API
claude mcp add --scope user jarbobo node <abs-path>/jarbobo/out/mcp-server.js
```

Reload the editor once, then ask your agent something like
*β€œdraw a sequence diagram of what happens on import, and link every step to the source.”*

## Architecture

Two processes, one localhost bridge β€” so **any number of MCP clients draw into the same editor**:

```
Claude (Cursor agent / Claude Code / …)
   β”‚  stdio MCP: draw_graph / draw_sequence_diagram / draw_class_diagram
   β–Ό
mcp-server.js        validates (zod) β†’ saves a .jarbobo file next to the code it documents
   β”‚  POST /diagram  (port discovered via ~/.jarbobo/port.json)
   β–Ό
extension host       one webview tab per diagram Β· status bar Β· persists layouts
   β–Ό
webview              cytoscape (graphs) Β· hand-rolled SVG (sequence / UML)
   β”‚  click node with file:line
   β–Ό
your editor          reveals the line, respecting locked editor groups
```

## Panel cheat-sheet

| Action | How |
|---|---|
| pan | right-drag, or scroll / ⇧-scroll |
| zoom | ⌘-scroll (around cursor) |
| reset pan/zoom | **reset view** button |
| recompute layout (discard drags) | **reset layout** button |
| pin the detail panel | πŸ”“ β†’ πŸ”’ next to βœ• (click outside closes it when unlocked) |
| open a code ref directly (skip panel) | **⌘-click** the element |
| highlight a code ref while hovering | hold **βŒƒ Ctrl** |
| choose where refs open | **refs β†’ code window / this window** toggle |
| rearrange | drag graph nodes/class boxes; sequence lifelines, messages, frames, and notes have constrained movement β€” layout persists |
| switch diagram version | **v3 β–Ύ** picker in the titlebar (edits bump the version; old ones stay) |
| reopen anything | status bar item, or `Jarbobo: Open Recent Diagram` |

## Dev

`media/dev.html` is a standalone harness (serve `media/` and open `dev.html#graph|sequence|class`).
`node scripts/test-mcp.mjs` smoke-tests the MCP server over stdio.
`curl 127.0.0.1:$(jq .port ~/.jarbobo/port.json)/health` checks the bridge.

## Public repository viewer

`viewer/` is a static, client-only viewer for diagrams committed to public GitHub
repositories. Serve the repository root with any static host, then open:

```
/viewer/?repo=https%3A%2F%2Fgithub.com%2FOWNER%2FREPOSITORY
```

It discovers `*.jarbobo` files through the GitHub API, renders them with the
same browser renderer as the extension, and opens linked source in a side pane.
No token, backend, MCP process, or model key is required for public repos.
For portable links, new diagrams should use workspace-relative `path` values in
references (for example `src/extension.ts`); the viewer also attempts to match
legacy `file` references when their path suffix uniquely identifies a repo file.

MIT.