Skip to main content
Glama
README.md
> Built as a portfolio project proving MCP breadth beyond data-query tools:
> this server takes a described system and produces a real, editable
> diagram file — not a data lookup, a generative/creative tool exposed the
> same way as the data-query MCP server in this portfolio.

# excalidraw-diagram-agent

An MCP server that turns a described system into a real, editable
`.excalidraw` diagram file. Describe an architecture in Claude Desktop
("draw me a diagram of a client talking to an API gateway, which routes to
an auth service and an order service, both writing to Postgres") and get
back a file you can open and keep editing in Excalidraw.

## What's here

- `layout.py` — a simple layered graph layout (no external graph library):
  positions nodes left-to-right by distance from a root, stacked vertically
  within each layer.
- `excalidraw_gen.py` — builds valid `.excalidraw` JSON: rectangles with
  properly **bound** text labels (they move together in the editor) and
  arrows with real `startBinding`/`endBinding` (they stay attached when you
  drag a box) — not just static lines dropped at fixed coordinates.
- `server.py` — the MCP server, one tool: `generate_diagram(title, nodes, edges)`.
- `requirements.txt` — one dependency, pinned.

## 1. Setup

```bash
cd excalidraw-diagram-agent
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

## 2. Test it standalone (no Claude needed yet)

```bash
python3 -c "
from server import generate_diagram
print(generate_diagram(
    title='Order Processing System',
    nodes=[
        {'id': 'client', 'label': 'Web Client'},
        {'id': 'gateway', 'label': 'API Gateway'},
        {'id': 'auth', 'label': 'Auth Service'},
        {'id': 'orders', 'label': 'Order Service'},
        {'id': 'db', 'label': 'Postgres DB'},
    ],
    edges=[
        {'from': 'client', 'to': 'gateway'},
        {'from': 'gateway', 'to': 'auth'},
        {'from': 'gateway', 'to': 'orders'},
        {'from': 'auth', 'to': 'db'},
        {'from': 'orders', 'to': 'db'},
    ],
))
"
```

Should print a confirmation with the file path. Open the generated file at
**excalidraw.com** (File > Open, or just drag the `.excalidraw` file onto
the page) to see the actual diagram.

## 3. Connect it to Claude Desktop

Same pattern as the rental-data MCP server (project 1) — add a second
entry to the same config file, `~/Library/Application Support/Claude/claude_desktop_config.json`,
alongside your existing `mcpServers` block:

```json
"diagram-agent": {
  "command": "/absolute/path/to/excalidraw-diagram-agent/venv/bin/python3",
  "args": ["/absolute/path/to/excalidraw-diagram-agent/server.py"]
}
```

(Both servers can live in the same `mcpServers` object — don't replace
`rental-data`, add `diagram-agent` next to it.) Fully quit and reopen
Claude Desktop, then check Settings > Developer to confirm both show as
running.

## 4. Demo prompts

- "Draw me a diagram of a typical 3-tier web app: client, API server, database"
- "Diagram a CI/CD pipeline: developer pushes to Git, triggers a build, runs tests, then deploys to staging and production"
- "Show me an event-driven architecture with a producer, a message queue, and two consumers"

Claude will figure out the nodes and edges from your description and call
the tool — you're not writing the JSON yourself, that's the point. Open
the resulting file at excalidraw.com to show it's a real, editable diagram,
not a static image.

## Architecture notes

- **Why a real Excalidraw file, not just a picture**: an LLM could
  describe a diagram in words, or even generate an SVG. Producing an
  actual `.excalidraw` file with correct element bindings means the output
  is a genuine editable artifact — drag a box, the arrows and label follow.
  That's a meaningfully different (and harder) target than a static image.
- **Layout**: intentionally simple (layered left-to-right) rather than a
  general-purpose graph layout library — sufficient for the kind of
  system/architecture diagrams this tool is aimed at, and keeps the
  dependency list at just the MCP SDK.
- **Validation**: `server.py` checks that every edge references a real
  node id before generating anything, returning a clear error instead of
  producing a broken file.

## Repo structure

```
excalidraw-diagram-agent/
├── README.md
├── requirements.txt
├── layout.py
├── excalidraw_gen.py
├── server.py
└── outputs/   (generated .excalidraw files, gitignored)
```