Excalidraw
STDIOMCP server enabling AI agents to create and manipulate live Excalidraw diagrams in real-time
MCP server enabling AI agents to create and manipulate live Excalidraw diagrams in real-time
A comprehensive TypeScript-based system that combines Excalidraw's powerful drawing capabilities with Model Context Protocol (MCP) integration, enabling AI agents to create and manipulate diagrams in real-time on a live canvas.
๐ Choose Your Installation Method
| Component | Local | Docker | Status |
|---|---|---|---|
| Canvas Server | โ Fully Working | โ Fully Working | Production Ready |
| MCP Server | โ Fully Working | โ Fully Working | Production Ready |
| NPM Published | ๐ง In Progress | N/A | Development testing |
This system consists of two independent components:
You can choose any combination:
Both local and Docker setups are fully working and production-ready!
See MCP Excalidraw in Action!
Watch how AI agents create and manipulate diagrams in real-time on the live canvas
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Component 1 โ
โ ๐จ CANVAS SERVER โ
โ (Runs Independently) โ
โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ Canvas Server โโโโโโโโโโถโ Frontend โ โ
โ โ (src/server.js) โ โ (React + WS) โ โ
โ โ Port 3000 โ โ Excalidraw UI โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ
โ ๐ Start: npm run canvas OR docker run (canvas) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โฒ
โ HTTP API
โ (Optional)
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Component 2 โ
โ ๐ค MCP SERVER โ
โ (Runs Independently) โ
โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ AI Agent โโโโโโโโโโถโ MCP Server โ โ
โ โ (Claude) โ โ (src/index.js) โ โ
โ โ Desktop/Code โ stdio โ MCP Protocol โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ
โ ๐ Configure in: claude_desktop_config.json OR .mcp.json โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ฏ Key Points:
โข Canvas and MCP server are SEPARATE processes
โข Canvas can run locally OR in Docker
โข MCP server can run locally OR in Docker
โข Canvas provides the visual interface (optional)
โข MCP server connects Claude to the canvas (via HTTP API)
create_from_mermaid tool from ClaudeThe canvas server provides the live Excalidraw interface.
git clone https://github.com/yctimlin/mcp_excalidraw.git cd mcp_excalidraw npm install
npm run build
# Production mode (recommended) npm run canvas
http://localhost:3000
Option B1: Use Pre-built Image from GHCR (Recommended)
docker pull ghcr.io/yctimlin/mcp_excalidraw-canvas:latest docker run -d -p 3000:3000 --name mcp-excalidraw-canvas ghcr.io/yctimlin/mcp_excalidraw-canvas:latest
Option B2: Build Locally
git clone https://github.com/yctimlin/mcp_excalidraw.git cd mcp_excalidraw docker build -f Dockerfile.canvas -t mcp-excalidraw-canvas . docker run -d -p 3000:3000 --name mcp-excalidraw-canvas mcp-excalidraw-canvas
http://localhost:3000
The MCP server connects your AI assistant (Claude) to the canvas. Choose local OR Docker format based on your preference.
You can mix and match any combination:
| Canvas Server | MCP Server | Status |
|---|---|---|
| โ Local | โ Local | Recommended |
| โ Local | โ Docker | Fully Working |
| โ Docker | โ Local | Fully Working |
| โ Docker | โ Docker | Fully Working |
Configuration examples are provided in the next section for:
| Script | Description |
|---|---|
npm start | Build and start MCP server (dist/index.js) |
npm run canvas | Build and start canvas server (dist/server.js) |
npm run build | Build both frontend and TypeScript backend |
npm run build:frontend | Build React frontend only |
npm run build:server | Compile TypeScript backend to JavaScript |
npm run dev | Start TypeScript watch mode + Vite dev server |
npm run type-check | Run TypeScript type checking without compilation |
npm run production | Build + start in production mode |
http://localhost:3000The MCP server provides these tools for creating visual diagrams:
// Create a rectangle { "type": "rectangle", "x": 100, "y": 100, "width": 200, "height": 100, "backgroundColor": "#e3f2fd", "strokeColor": "#1976d2", "strokeWidth": 2 }
{ "type": "text", "x": 150, "y": 125, "text": "Process Step", "fontSize": 16, "strokeColor": "#333333" }
{ "type": "arrow", "x": 300, "y": 130, "width": 100, "height": 0, "strokeColor": "#666666", "strokeWidth": 2 }
{ "elements": [ { "type": "rectangle", "x": 100, "y": 100, "width": 120, "height": 60, "backgroundColor": "#fff3e0", "strokeColor": "#ff9800" }, { "type": "text", "x": 130, "y": 125, "text": "Start", "fontSize": 16 } ] }
โ Ensure your canvas server is running (from Step 1):
npm run canvasdocker run -d -p 3000:3000 mcp-excalidraw-canvasCanvas should be accessible at http://localhost:3000
Choose your configuration based on IDE and preference:
| IDE | Config File | Format Options |
|---|---|---|
| Claude Desktop | claude_desktop_config.json | Local โญ / Docker โ |
| Claude Code | .mcp.json (project root) | Local โญ / Docker โ |
| Cursor | .cursor/mcp.json | Local โญ / Docker โ |
โญ = Recommended | โ = Fully Working
Edit your claude_desktop_config.json file:
{ "mcpServers": { "excalidraw": { "command": "node", "args": ["/absolute/path/to/mcp_excalidraw/dist/index.js"], "env": { "EXPRESS_SERVER_URL": "http://localhost:3000", "ENABLE_CANVAS_SYNC": "true" } } } }
Important: Replace /absolute/path/to/mcp_excalidraw with your actual installation path.
Using Pre-built Image from GHCR (Recommended):
{ "mcpServers": { "excalidraw": { "command": "docker", "args": [ "run", "-i", "--rm", "--network", "host", "-e", "EXPRESS_SERVER_URL=http://localhost:3000", "-e", "ENABLE_CANVAS_SYNC=true", "ghcr.io/yctimlin/mcp_excalidraw:latest" ] } } }
OR Build Locally:
cd mcp_excalidraw docker build -f Dockerfile -t mcp-excalidraw .
Then use mcp-excalidraw as the image name in the configuration above.
Create or edit .mcp.json in your project root:
{ "mcpServers": { "excalidraw": { "command": "node", "args": ["/absolute/path/to/mcp_excalidraw/dist/index.js"], "env": { "EXPRESS_SERVER_URL": "http://localhost:3000", "ENABLE_CANVAS_SYNC": "true" } } } }
Important: Replace /absolute/path/to/mcp_excalidraw with your actual installation path.
Using Pre-built Image from GHCR (Recommended):
{ "mcpServers": { "excalidraw": { "command": "docker", "args": [ "run", "-i", "--rm", "--network", "host", "-e", "EXPRESS_SERVER_URL=http://localhost:3000", "-e", "ENABLE_CANVAS_SYNC=true", "ghcr.io/yctimlin/mcp_excalidraw:latest" ] } } }
OR Build Locally:
cd mcp_excalidraw docker build -f Dockerfile -t mcp-excalidraw .
Then use mcp-excalidraw as the image name in the configuration above.
# Project-scoped (recommended) claude mcp add --scope project --transport stdio excalidraw \ -- docker run -i --rm --network host \ -e EXPRESS_SERVER_URL=http://localhost:3000 \ -e ENABLE_CANVAS_SYNC=true \ mcp-excalidraw # User-scoped (available across all projects) claude mcp add --scope user --transport stdio excalidraw \ -- docker run -i --rm --network host \ -e EXPRESS_SERVER_URL=http://localhost:3000 \ -e ENABLE_CANVAS_SYNC=true \ mcp-excalidraw
Edit .cursor/mcp.json:
{ "mcpServers": { "excalidraw": { "command": "node", "args": ["/absolute/path/to/mcp_excalidraw/dist/index.js"], "env": { "EXPRESS_SERVER_URL": "http://localhost:3000", "ENABLE_CANVAS_SYNC": "true" } } } }
Using Pre-built Image from GHCR (Recommended):
{ "mcpServers": { "excalidraw": { "command": "docker", "args": [ "run", "-i", "--rm", "--network", "host", "-e", "EXPRESS_SERVER_URL=http://localhost:3000", "-e", "ENABLE_CANVAS_SYNC=true", "ghcr.io/yctimlin/mcp_excalidraw:latest" ] } } }
OR Build Locally:
cd mcp_excalidraw docker build -f Dockerfile -t mcp-excalidraw .
Then use mcp-excalidraw as the image name in the configuration above.
| Setting | Purpose | Required |
|---|---|---|
EXPRESS_SERVER_URL | Canvas server URL | Yes (default: http://localhost:3000) |
ENABLE_CANVAS_SYNC | Enable real-time canvas sync | Yes (set to "true") |
--network host | Docker access to localhost | Required for Docker |
-i flag | Interactive stdin/stdout | Required for Docker |
Canvas is optional: The MCP server works without the canvas in API-only mode (for programmatic access only).
| Variable | Default | Description |
|---|---|---|
EXPRESS_SERVER_URL | http://localhost:3000 | Canvas server URL for MCP sync |
ENABLE_CANVAS_SYNC | true | Enable/disable canvas synchronization |
LOG_FILE_PATH | excalidraw.log | Path to the log file |
DEBUG | false | Enable debug logging |
PORT | 3000 | Canvas server port |
HOST | localhost | Canvas server host |
The canvas server provides these REST endpoints:
| Method | Endpoint | Description |
|---|---|---|
GET | /api/elements | Get all elements |
POST | /api/elements | Create new element |
PUT | /api/elements/:id | Update element |
DELETE | /api/elements/:id | Delete element |
POST | /api/elements/batch | Create multiple elements |
GET | /health | Server health check |
create_element - Create any type of Excalidraw elementupdate_element - Modify existing elementsdelete_element - Remove elementsquery_elements - Search elements with filtersbatch_create_elements - Create complex diagrams in one callgroup_elements - Group multiple elementsungroup_elements - Ungroup element groupsalign_elements - Align elements (left, center, right, top, middle, bottom)distribute_elements - Distribute elements evenlylock_elements / unlock_elements - Lock/unlock elementsget_resource - Access scene, library, theme, or elements datafrontend/src/)@excalidraw/excalidraw package with TypeScript typessrc/server.ts โ dist/server.js)src/index.ts โ dist/index.js)src/types.ts)npm run build completed successfullydist/index.html and dist/frontend/ directory existlsof -i :3000 (macOS/Linux) or netstat -ano | findstr :3000 (Windows)ENABLE_CANVAS_SYNC=true in MCP server environment configurationEXPRESS_SERVER_URL points to correct canvas server URL--network host flag is usedcurl http://localhost:3000/healthCanvas Container:
docker ps | grep canvasdocker logs mcp-excalidraw-canvasMCP Container:
--network host is used (required to access localhost:3000)-i flag is present (required for MCP stdin/stdout protocol)node_modules and dist/ directories, then run npm install && npm run buildnode --versionnpm run type-check to identify TypeScript issuesdist/ directory contains both index.js, server.js, and frontend/ after buildmcp_excalidraw/
โโโ frontend/
โ โโโ src/
โ โ โโโ App.tsx # Main React component (TypeScript)
โ โ โโโ main.tsx # React entry point (TypeScript)
โ โโโ index.html # HTML template
โโโ src/ (TypeScript Source)
โ โโโ index.ts # MCP server (TypeScript)
โ โโโ server.ts # Canvas server (Express + WebSocket, TypeScript)
โ โโโ types.ts # Comprehensive type definitions
โ โโโ utils/
โ โโโ logger.ts # Logging utility (TypeScript)
โโโ dist/ (Compiled Output)
โ โโโ index.js # Compiled MCP server
โ โโโ server.js # Compiled Canvas server
โ โโโ types.js # Compiled type definitions
โ โโโ utils/
โ โ โโโ logger.js # Compiled logging utility
โ โโโ frontend/ # Built React frontend
โโโ tsconfig.json # TypeScript configuration
โโโ vite.config.js # Vite build configuration
โโโ package.json # Dependencies and scripts
โโโ README.md # This file
We welcome contributions! If you're experiencing issues with the NPM package or Docker version, please:
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)This project is licensed under the MIT License - see the LICENSE file for details.