excalidraw-mcp
Allows AI agents to create and manipulate Excalidraw diagrams in real-time, including elements such as rectangles, ellipses, diamonds, arrows, text, lines, and supports batch operations, grouping, alignment, and locking.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@excalidraw-mcpdraw a rectangle labeled 'input'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Excalidraw MCP Server: AI-Powered Live Visual Diagramming
🙏 Acknowledgments This project is based on and extends the excellent work from yctimlin/mcp_excalidraw. Special thanks to the original contributors for creating the foundation that made this enhanced version possible.
A dual-language MCP server that combines Excalidraw canvas manipulation with AI-driven tool access for live diagram creation.
It uses a Python FastMCP server plus a TypeScript canvas server for separation of protocol handling, canvas state, and browser updates.
Quick Links
Related MCP server: Excalidraw MCP Server
Quality & CI
Crackerjack is used as the standard quality-control and CI/CD gate for the Python side of this repo. Pair it with the existing TypeScript build and test checks for cross-stack changes.
Installation via Bodai Marketplace
This repo ships as a Bodai-style Claude Code plugin. Register the local marketplace, then install the plugin — the manifest's mcpServers entry points at the colocated .mcp.json (HTTP transport, port 3032) and exposes the three slash commands in commands/. The TypeScript canvas server still needs to be running for live updates to flow through to the browser. Use claude plugin marketplace add /Users/les/Projects/bodai-plugins && claude plugin install excalidraw --marketplace bodai-plugins after the marketplace entry lands in bodai-plugins/.claude-plugin/marketplace.json.
🚀 What This System Does
🎨 Live Canvas: Real-time Excalidraw canvas accessible via web browser
🤖 AI Integration: MCP server allows AI agents (like Claude) to create visual diagrams
⚡ Real-time Sync: Elements created via MCP API appear instantly on the canvas
🔄 WebSocket Updates: Live synchronization across multiple connected clients
🏗️ Production Ready: Clean, minimal UI suitable for end users
🎥 Demo Video
See MCP Excalidraw in Action!

Watch how AI agents create and manipulate diagrams in real-time on the live canvas
🏛️ Architecture Overview
sequenceDiagram
participant AI as AI Agent<br/>(Claude)
participant MCP as MCP Server<br/>(Python FastMCP)
participant Canvas as Canvas Server<br/>(Express.js)
participant WS as WebSocket Server
participant UI as React Frontend<br/>(Excalidraw)
AI->>MCP: MCP Tool Call<br/>(create_element)
activate MCP
MCP->>MCP: Validate Request<br/>(Pydantic)
MCP->>Canvas: HTTP POST<br/>/api/elements
activate Canvas
Canvas->>Canvas: Store Element<br/>(in-memory Map)
Canvas->>WS: Broadcast Update
WS->>UI: WebSocket Message<br/>(element_created)
deactivate Canvas
UI->>UI: Render in Excalidraw
MCP-->>AI: Tool Response
deactivate MCP
Note over MCP,Canvas: Auto-management: Python server<br/>monitors and restarts canvas server
Note over WS,UI: Real-time: All connected clients<br/>receive updates simultaneouslyHybrid Architecture Benefits:
Python FastMCP: Handles MCP protocol, tool registration, and auto-manages canvas server
TypeScript Canvas: Express.js API + WebSocket for real-time canvas synchronization
Auto-Management: Python server monitors and restarts canvas server as needed
Type Safety: Comprehensive TypeScript definitions ensure consistency across the stack
🌟 Key Features
Modern TypeScript Architecture
Full TypeScript Migration: Complete type safety for backend and frontend
Comprehensive Type Definitions: Excalidraw elements, API responses, WebSocket messages
Strict Type Checking: Enhanced development experience and compile-time error detection
Type-Safe React Components: TSX components with proper props typing
Real-time Canvas Integration
Elements created via MCP appear instantly on the live canvas
WebSocket-based real-time synchronization
Multi-client support with live updates
Production-Ready Interface
Clean, minimal UI with connection status
Simple "Clear Canvas" functionality
No development clutter or debug information
Comprehensive MCP API
Element Creation: rectangles, ellipses, diamonds, arrows, text, lines
Element Management: update, delete, query with filters
Batch Operations: create multiple elements in one call
Advanced Features: grouping, alignment, distribution, locking
Robust Architecture
TypeScript-based Express.js backend with REST API + WebSocket
React frontend with official Excalidraw package and TypeScript
Dual-path element loading for reliability
Auto-reconnection and error handling
📦 Installation & Setup
✅ Quick Start (Recommended)
1. Clone and Setup
git clone https://github.com/lesleslie/excalidraw-mcp.git
cd excalidraw-mcp
# Install Python dependencies
uv sync
# Install Node.js dependencies from package-lock.json (node_modules not in repo)
npm install
npm run build2. Start the System
# The Python MCP server auto-starts the canvas server
uv run python excalidraw_mcp/server.py
# Or manually start canvas server (optional)
npm run canvas3. Access the Canvas
Open your browser and navigate to:
http://localhost:3031📋 Development Setup
# Development mode (TypeScript watch + Vite dev server)
npm run dev
# Or production mode
npm run productionDevelopment Workflow:
Setup →
uv sync && npm install && npm run buildDevelopment →
npm run dev(TypeScript watch + Vite dev server)Testing →
pytest(Python) +npm test(TypeScript)Quality Checks →
uv run ruff check+npm run type-checkIterate → Make changes, tests auto-reload
Commit → All quality checks pass
Development Modes:
Mode | Command | Use Case |
Dev |
| Active development with hot-reload |
Build |
| Compile TypeScript + React |
Canvas |
| Start canvas server only |
Production |
| Full build + start |
🔧 Available Scripts
Script | Description |
| Build and start MCP server ( |
| Build and start canvas server ( |
| Build and start canvas server in background |
| Build and start canvas server |
| Special script for npx usage |
| Start both servers together |
| Build both frontend and TypeScript backend |
| Build React frontend only |
| Compile TypeScript backend to JavaScript |
| Generate TypeScript declaration files only |
| Start TypeScript watch mode + Vite dev server |
| Start TypeScript in watch mode only |
| Run TypeScript type checking without compilation |
| Build + start in production mode |
| Run all tests |
| Run tests in watch mode |
| Run tests with coverage report |
| Run unit tests only |
| Run integration tests only |
🎯 Usage Guide
For End Users
Open the canvas at
http://localhost:3031Check connection status (should show "Connected")
AI agents can now create diagrams that appear in real-time
Use "Clear Canvas" to remove all elements
For AI Agents (via MCP)
The MCP server provides these tools for creating visual diagrams:
Basic Element Creation
// Create a rectangle
{
"type": "rectangle",
"x": 100,
"y": 100,
"width": 200,
"height": 100,
"backgroundColor": "#e3f2fd",
"strokeColor": "#1976d2",
"strokeWidth": 2
}Create Text Elements
{
"type": "text",
"x": 150,
"y": 125,
"text": "Process Step",
"fontSize": 16,
"strokeColor": "#333333"
}Create Arrows & Lines
{
"type": "arrow",
"x": 300,
"y": 130,
"width": 100,
"height": 0,
"strokeColor": "#666666",
"strokeWidth": 2
}Batch Creation for Complex Diagrams
{
"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
}
]
}🔌 Integration with Claude Code
✅ Recommended: uvx Configuration
Add this configuration to your Claude Code .mcp.json:
{
"mcpServers": {
"excalidraw": {
"command": "uvx",
"args": ["excalidraw-mcp"],
"env": {
"EXPRESS_SERVER_URL": "http://localhost:3031"
}
}
}
}Alternative: Local Development Configuration
For local development, use the console-script entry point installed by uv sync:
{
"mcpServers": {
"excalidraw": {
"command": "uv",
"args": ["run", "excalidraw-mcp"],
"cwd": "<absolute-path-to-cloned-excalidraw-mcp>"
}
}
}Important: Replace <absolute-path-to-cloned-excalidraw-mcp> with the actual
absolute path to your cloned repository. Running excalidraw_mcp/server.py
directly is not a supported entry point — use the excalidraw-mcp console
script (uv run excalidraw-mcp) or uv run python -m excalidraw_mcp instead.
🔧 Integration with Other Tools
Cursor IDE
Add to your .cursor/mcp.json:
{
"mcpServers": {
"excalidraw": {
"command": "uvx",
"args": ["excalidraw-mcp"],
"env": {
"EXPRESS_SERVER_URL": "http://localhost:3031"
}
}
}
}VS Code MCP Extension
For VS Code MCP extension, add to your settings:
{
"mcp": {
"servers": {
"excalidraw": {
"command": "uvx",
"args": ["excalidraw-mcp"],
"env": {
"EXPRESS_SERVER_URL": "http://localhost:3031"
}
}
}
}
}🛠️ Environment Variables
Variable | Default | Description |
|
| Canvas server URL for MCP sync |
|
| Auto-start canvas server with MCP server |
|
| Number of retry attempts for failed operations |
|
| Base delay between retry attempts (seconds) |
|
| Maximum delay between retry attempts (seconds) |
|
| Exponential base for backoff calculation |
|
| Enable/disable jitter for retry delays |
|
| Standard logging level ( |
|
| Emit structured JSON log records |
|
| Render log records as a single JSON line |
| (unset) | Optional path for the rotating log file |
| (unset) | Optional path for the tamper-evident audit log |
|
| Enable JWT-based authentication on the MCP HTTP transport |
| (unset, required when | Shared secret used to sign/verify JWTs |
| (unset) | Comma-separated CORS allow-list for the MCP HTTP transport |
|
| Enable the in-process monitoring agent |
|
| Expose Prometheus-style metrics on the MCP server |
|
| Send alerts when monitored thresholds are crossed |
|
| Engage the circuit breaker around outbound HTTP calls |
|
| Seconds between background health probes |
|
| CPU usage percent that triggers a monitoring alert |
|
| RSS memory percent that triggers a monitoring alert |
|
| Maximum elements permitted per canvas |
|
| Start the WebSocket collaboration server |
|
| Bind address for the WebSocket server |
|
| Listen port for the WebSocket server |
|
| Port for the WebSocket Prometheus metrics endpoint |
|
| Enable JWT auth on the WebSocket subscription layer |
| (unset) | JWT secret for the WebSocket subscription layer |
|
| JWT lifetime in seconds for the WebSocket layer |
Note:
PORT,HOST, andDEBUGare not consumed by the Python MCP server. The canvas server (TypeScript,src/server.ts) readsPORT(default3031) for its Express listener; the Python MCP HTTP transport listens on a fixed3032(seeexcalidraw_mcp/__main__.py). UseEXPRESS_SERVER_URLto point the Python server at a non-default canvas-server host/port, andLOG_LEVELto control log verbosity.
📊 API Endpoints
The canvas server provides these REST endpoints:
Method | Endpoint | Description |
|
| Get all elements |
|
| Create new element |
|
| Update element |
|
| Delete element |
|
| Create multiple elements |
|
| Server health check |
🎨 MCP Tools Available
Element Management
create_element- Create any type of Excalidraw elementupdate_element- Modify existing elementsdelete_element- Remove elementsquery_elements- Search elements with filters
Batch Operations
batch_create_elements- Create complex diagrams in one call
Element Organization
group_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 elements
Resource Access
get_resource- Access scene, library, theme, or elements data
WebSocket Monitoring
The MCP server also exposes five WebSocket-administration tools (registered by
excalidraw_mcp/mcp/websocket_tools.py). They are available whenever the
WebSocket collaboration server is enabled:
websocket_health_check- Liveness probe for the WebSocket serverwebsocket_get_status- Active connections, rooms, and per-room subscriber countswebsocket_list_rooms- Enumerate active diagram/cursor/presence/global roomswebsocket_broadcast_test_event- Publish a synthetic event to a room (development use)websocket_get_metrics- Throughput, rate-limit counters, and connection metrics
🏗️ Development Architecture
Frontend (frontend/src/)
React + TypeScript: Modern TSX components with full type safety
Vite Build System: Fast development and optimized production builds
Official Excalidraw:
@excalidraw/excalidrawpackage with TypeScript typesWebSocket Client: Type-safe real-time element synchronization
Clean UI: Production-ready interface with proper TypeScript typing
Canvas Server (src/server.ts → dist/server.js)
TypeScript + Express.js: Fully typed REST API + static file serving
WebSocket: Type-safe real-time client communication
Element Storage: In-memory with comprehensive type definitions
CORS: Cross-origin support with proper typing
Middleware: Custom Express middleware components
Storage: Element storage implementations
WebSocket: Dedicated WebSocket server components
Utils: Utility functions for various operations
MCP Server (excalidraw_mcp/server.py)
Python FastMCP: Python-based Model Context Protocol implementation
Canvas Sync: HTTP requests to canvas server for element synchronization
Element Management: Full CRUD operations for Excalidraw elements
Batch Support: Complex diagram creation through batch operations
Process Management: Canvas server lifecycle management
HTTP Client: Async HTTP client with retry mechanisms
Configuration: Centralized configuration management
Type System (src/types.ts)
Excalidraw Element Types: Complete type definitions for all element types
API Response Types: Strongly typed REST API interfaces
WebSocket Message Types: Type-safe real-time communication
Server Element Types: Enhanced element types with metadata
🐛 Troubleshooting
flowchart TD
Start[Issue Detected] --> IssueType{What's the problem?}
IssueType -->|Canvas Not Loading| CanvasCheck{Build succeeded?}
IssueType -->|Elements Not Syncing| SyncCheck{Canvas server<br/>running?}
IssueType -->|WebSocket Issues| WSVerify{Check console<br/>for errors}
IssueType -->|Build Errors| BuildClean{Node version<br/>OK?}
IssueType -->|Python Errors| DepCheck{uv sync<br/>succeeded?}
CanvasCheck -->|No| A1[Run npm run build]
CanvasCheck -->|Yes| A2{Server running?}
A2 -->|No| A3[Check port 3031<br/>lsof -i :3031]
A2 -->|Yes| A4{Health check OK?}
A4 -->|No| A5[Review console logs]
A4 -->|Yes| A6[Check firewall]
SyncCheck -->|No| B1[Python auto-starts<br/>canvas server]
SyncCheck -->|Yes| B2{EXPRESS_SERVER_URL<br/>set?}
B2 -->|No| B3[Set env variable]
B2 -->|Yes| B4{/health OK?}
B4 -->|No| B5[Check canvas<br/>server logs]
B4 -->|Yes| B6[Verify WebSocket<br/>connection]
WSVerify -->|Errors found| C1[Check firewall<br/>settings]
WSVerify -->|No errors| C2[Refresh browser<br/>page]
BuildClean -->|No| D1[Delete node_modules<br/>npm install]
BuildClean -->|Yes| D2[Run type-check<br/>npm run type-check]
DepCheck -->|No| E1[Run uv sync]
DepCheck -->|Yes| E2{Python 3.13+?}
E2 -->|No| E3[Install Python 3.13]
E2 -->|Yes| E4[Check uv<br/>installation]
style Start fill:#e3f2fd
style A1 fill:#c8e6c9
style A6 fill:#ffcdd2
style B1 fill:#c8e6c9
style E4 fill:#fff9c4Canvas Not Loading
Ensure
npm run buildcompleted successfullyVerify canvas server is running on port 3031
Python MCP server auto-starts canvas server - check console for errors
Elements Not Syncing
Python server automatically manages canvas server
Verify
EXPRESS_SERVER_URLpoints at a reachable canvas serverVerify canvas server health at
http://localhost:3031/health
WebSocket Connection Issues
Check browser console for WebSocket errors
Ensure no firewall blocking WebSocket connections
Try refreshing the browser page
Build Errors
Delete
node_modulesand runnpm installCheck Node.js version (requires 16+)
Run
npm run type-checkto identify TypeScript issuesRun
uv syncto update Python dependencies
Python Dependencies
Use
uv syncto install/update Python dependenciesEnsure Python 3.13+ is installed
Check
uv --versionto verify uv installation
📋 Project Structure
excalidraw-mcp/
├── examples/ # Usage examples
├── excalidraw_mcp/ # Python FastMCP server
│ ├── monitoring/ # Monitoring and health check utilities
│ ├── server.py # Main MCP server (Python)
│ ├── config.py # Configuration management
│ ├── element_factory.py # Element creation utilities
│ ├── http_client.py # HTTP client for canvas server
│ ├── process_manager.py # Canvas server lifecycle management
│ ├── retry_utils.py # Retry mechanisms for failed operations
│ ├── cli.py # Command-line interface
│ ├── mcp_tools.py # MCP tool implementations
│ ├── __init__.py # Package initialization
│ └── __main__.py # Main entry point
├── frontend/ # React frontend
│ ├── src/
│ │ ├── App.tsx # Main React component (TypeScript)
│ │ └── main.tsx # React entry point (TypeScript)
│ └── index.html # HTML template
├── src/ # TypeScript canvas server
│ ├── middleware/ # Express middleware components
│ ├── storage/ # Element storage implementations
│ ├── utils/ # Utility functions
│ ├── websocket/ # WebSocket server components
│ ├── config.ts # Server configuration
│ ├── server.ts # Express server + WebSocket (TypeScript)
│ └── types.ts # Type definitions
├── dist/ # Compiled TypeScript output
│ ├── server.js # Compiled canvas server
│ ├── server.d.ts # Server type definitions
│ ├── server.js.map # Server source maps
│ ├── types.js # Compiled type definitions
│ ├── types.d.ts # Type definition files
│ ├── types.js.map # Type definition source maps
│ ├── utils/ # Compiled utilities
│ ├── assets/ # Frontend assets
│ └── frontend/ # Built React frontend
├── tests/ # Python test suite
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ ├── security/ # Security tests
│ ├── performance/ # Performance tests
│ └── e2e/ # End-to-end tests
├── .github/ # GitHub configurations
├── pyproject.toml # Python project configuration
├── package.json # Node.js dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── README.md # This file📦 Package Naming
This project uses consistent naming across different contexts:
Python Package:
excalidraw_mcp(underscore) - used in imports and Python module referencesPyPI Distribution:
excalidraw-mcp(hyphen) - used foruvx excalidraw-mcpand pip installationnpm Package:
excalidraw-mcp(hyphen) - used for Node.js dependenciesMCP Server Name:
excalidraw- used in .mcp.json configuration
Example Usage:
# Python imports (underscore)
from excalidraw_mcp.server import main
# Shell commands (hyphen)
uvx excalidraw-mcp
pip install excalidraw-mcp🧪 Testing & Quality Assurance
Coverage Requirements
Python: 85% minimum test coverage (enforced by pytest)
TypeScript: 70% minimum test coverage (enforced by Jest)
Running Tests
# Python tests with coverage
pytest --cov=excalidraw_mcp --cov-report=html
pytest --cov=excalidraw_mcp --cov-report=term-missing
# TypeScript tests with coverage
npm run test:coverage
# Run all tests
pytest && npm test
# Specific test categories
pytest tests/unit/ # Python unit tests
pytest tests/integration/ # Python integration tests
pytest -m security # Security tests
pytest -m performance # Performance benchmarks
npm run test:unit # TypeScript unit tests
npm run test:integration # TypeScript integration testsQuality Standards
This project enforces strict quality standards:
All code must pass type checking (Pyright for Python, TSC for TypeScript)
Security scanning with Bandit for Python
Linting and formatting with Ruff (Python) and built-in TypeScript rules
Comprehensive test coverage as specified above
📦 Publishing & Distribution
PyPI Distribution
The Python package is published to PyPI as excalidraw-mcp:
# Install from PyPI (latest published release)
pip install excalidraw-mcp
# Use with uvx (recommended)
uvx excalidraw-mcpThe
pyproject.toml/CHANGELOG.mdversion may briefly lead the latest PyPI release while a publish is in flight; in that window preferpip install -e .from a fresh clone overpip install excalidraw-mcp.
Local Development
For local development and testing:
# Install in editable mode
pip install -e .
# Or use UV for development
uv sync
uv run python excalidraw_mcp/server.pyVersion Management
Semantic versioning (SemVer) is used
Version is managed in both
pyproject.tomlandpackage.jsonReleases are tagged in git with version numbers
🔮 Development Roadmap
✅ Python FastMCP Architecture: Modern hybrid implementation with auto-management
✅ TypeScript Canvas Server: Complete type safety for enhanced development experience
✅ Comprehensive Testing: Security, performance, and integration test suites
🔧 Enhanced Features: Additional MCP tools and canvas capabilities
🔧 Performance Optimization: Real-time sync improvements
🔧 Docker Deployment: Containerized deployment options
🤝 Contributing
We welcome contributions! Please:
Fork the repository
Create a feature branch (
git checkout -b feature/amazing-feature)Commit your changes (
git commit -m 'Add amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
Excalidraw Team - For the amazing drawing library
MCP Community - For the Model Context Protocol specification
This server cannot be deployed
Maintenance
Related MCP Connectors
Real-time collaborative whiteboard — AI agents and humans edit the same board live over MCP.
Create and manage Mermaid.js flowcharts and diagrams with AI agents via MCP.
AI agent draws editable hand-drawn diagrams (flowchart, ER, architecture) via MCP, not static images
Create and edit architecture diagrams from your AI agent; get an SVG and a live editable canvas.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables users to create and interact with hand-drawn Excalidraw diagrams featuring smooth viewport camera control and interactive fullscreen editing. It uses the MCP Apps extension to render collaborative virtual whiteboards directly within supported AI chat interfaces.-
- AlicenseNot gradedqualityFmaintenanceEnables AI agents to programmatically control a live Excalidraw canvas through element-level CRUD operations and real-time synchronization. It allows agents to iteratively build, inspect, and refine diagrams while providing visual feedback via screenshots and scene descriptions.1,608 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to programmatically control a live Excalidraw canvas with element-level CRUD operations and real-time synchronization. It supports iterative diagramming through scene descriptions, screenshots, and advanced layout tools for collaborative AI-human workflows.1,608 npm2MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to collaboratively draw and annotate Excalidraw diagrams in real-time via MCP tools, synced to a browser canvas.8Apache 2.0