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 "Install 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.
🚀 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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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.3,023MIT
- 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.3,023MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to collaboratively draw and annotate Excalidraw diagrams in real-time via MCP tools, synced to a browser canvas.6Apache 2.0
Related MCP Connectors
Real-time collaborative whiteboard — AI agents and humans edit the same board live over MCP.
AI agent draws editable hand-drawn diagrams (flowchart, ER, architecture) via MCP, not static images
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/lesleslie/excalidraw-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server