io.github.debu-sinha/excalidraw

Security-hardened Excalidraw MCP server with auth, rate limiting, and 14 tools

3MITdevtools

Install

Config snippet generator goes here (5 client tabs)

README

# excalidraw-mcp-server

The only Excalidraw MCP server with security hardening, inline diagram rendering, and real-time canvas sync.

[![CI](https://github.com/debu-sinha/excalidraw-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/debu-sinha/excalidraw-mcp-server/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/excalidraw-mcp-server)](https://www.npmjs.com/package/excalidraw-mcp-server)
[![npm downloads](https://img.shields.io/npm/dt/excalidraw-mcp-server)](https://www.npmjs.com/package/excalidraw-mcp-server)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Node](https://img.shields.io/badge/node-%3E%3D18-brightgreen.svg)](https://nodejs.org/)

<p align="center">
  <img src="docs/demo.gif" alt="Demo: architecture diagram being drawn element-by-element in real-time through WebSocket sync" width="720" />
</p>

## What it does

Ask your AI to draw a diagram, and it appears right inside the chat. The MCP server gives Claude Desktop, ChatGPT, VS Code, and Cursor a full set of drawing tools backed by the Excalidraw format -- with API authentication, rate limiting, and input validation on every operation.

v2.0 adds **MCP Apps support**: diagrams stream inline as interactive SVG widgets with draw-on animations, and you can export any diagram to excalidraw.com with one click.

## Two modes, zero config

**Standalone mode** (default) -- just install and go. The server runs with an in-process element store. No canvas server, no API keys, no setup. Your MCP client calls the tools, and diagrams render inline.

**Connected mode** -- start the optional canvas server for real-time browser sync. Multiple clients can collaborate on the same canvas through authenticated WebSocket connections. File persistence keeps state across restarts.

The server auto-detects which mode to use: if a canvas server is reachable, it connects to it. Otherwise it falls back to standalone.

## Architecture

<p align="center">
  <img src="docs/architecture-v2.svg" alt="Architecture: MCP clients connect via stdio to the server, which operates in standalone mode with an in-process store and inline widget, or in connected mode with a canvas server, WebSocket browser frontend, and file persistence" width="800" />
</p>

*Diagram created with excalidraw-mcp-server -- [edit in Excalidraw](docs/architecture-v2.excalidraw.json)*

## Features

**MCP Apps (v2.0)**
- Inline diagram rendering in Claude Desktop, ChatGPT, and VS Code
- Streaming SVG with draw-on animations as elements arrive
- Export to excalidraw.com with one click
- Element reference cheatsheet via `read_me` tool

**16 MCP tools**
- Create, update, delete, and query elements (rectangle, ellipse, diamond, arrow, text, line, freedraw)
- Batch create up to 100 elements at once
- Group, ungroup, align, distribute, lock, unlock
- Mermaid diagram conversion
- SVG and PNG export

**Security**
- API key authentication with constant-time comparison
- Origin-restricted CORS (no wildcards)
- WebSocket auth with token and origin validation
- Standard and strict rate limiting tiers
- Bounded Zod schemas with `.strict()` on every endpoint
- Helmet.js security headers with CSP

**Infrastructure**
- Real-time WebSocket sync across browser clients
- Optional atomic-write file persistence
- Structured pino audit logging

## Install

```bash
npm install -g excalidraw-mcp-server
```

Or run directly:

```bash
npx excalidraw-mcp-server
```

## Quick start

### Standalone (recommended for most users)

Just point your MCP client at the server. No canvas server needed.

```json
{
  "mcpServers": {
    "excalidraw": {
      "command": "npx",
      "args": ["excalidraw-mcp-server"]
    }
  }
}
```

Then ask your AI: *"Draw an architecture diagram showing a load balancer, three app servers, and a database"*

### Connected mode (real-time browser sync)

```bash
# Generate an API key
node scripts/generate-api-key.cjs

# Start the canvas server
EXCALIDRAW_API_KEY=<your-key> npm run canvas

# Open http://localhost:3000 to see the live canvas
```

Point your MCP client at the server with the same API key:

```json
{
  "mcpServers": {
    "excalidraw": {
      "command": "npx",
      "args": ["excalidraw-mcp-server"],
      "env": {
        "EXCALIDRAW_API_KEY": "<your-key>",
        "CANVAS_SERVER_URL": "http://127.0.0.1:3000"
      }
    }
  }
}
```

## MCP tools

| Tool | Description |
|------|-------------|
| `create_view` | Render elements as an inline SVG widget with streaming animations (MCP Apps) |
| `read_me` | Get the element reference cheatsheet (types, colors, sizing tips) |
| `create_element` | Create a single element (rectangle, ellipse, diamond, arrow, text, line, freedraw) |
| `update_element` | Update an existing element by ID |
| `delete_element` | Delete an element by ID |
| `query_elements` | Search elements by type, locked status, or group ID |
| `get_resource` | Get scene state, all elements, theme, or library |
| `batch_create_elements`