Labsco
yctimlin logo

Excalidraw

โ˜… 2,100

from yctimlin

An MCP server for creating, modifying, and manipulating Excalidraw drawings via an API.

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅโœ“ VerifiedFreeQuick setup

Excalidraw MCP Server & Agent Skill

Run a live Excalidraw canvas and control it from AI agents. This repo provides:

  • MCP Server: Connect via Model Context Protocol (Claude Desktop, Cursor, Codex CLI, etc.)

  • Agent Skill: Portable skill for Claude Code, Codex CLI, and other skill-enabled agents

Keywords: Excalidraw agent skill, Excalidraw MCP server, AI diagramming, Claude Code skill, Codex CLI skill, Claude Desktop MCP, Cursor MCP, Mermaid to Excalidraw.

Demo

AI agent creates a complete architecture diagram from a single prompt (4x speed). Watch full video on YouTube

Table of Contents

  • Demo

  • What It Is

  • How We Differ from the Official Excalidraw MCP

  • What's New

  • Quick Start (Local)

  • Quick Start (Docker)

  • Configure MCP Clients

  • Claude Desktop

  • Claude Code

  • Cursor

  • Codex CLI

  • OpenCode

  • Antigravity (Google)

  • Agent Skill (Optional)

  • MCP Tools (26 Total)

  • Testing

  • Troubleshooting

  • Known Issues / TODO

  • Development

What It Is

This repo contains two separate processes:

  • Canvas server: web UI + REST API + WebSocket updates (default http://127.0.0.1:3000)

  • MCP server: exposes MCP tools over stdio; syncs to the canvas via EXPRESS_SERVER_URL

How We Differ from the Official Excalidraw MCP

Excalidraw now has an official MCP โ€” it's great for quick, prompt-to-diagram generation rendered inline in chat. We solve a different problem.

Official Excalidraw MCP This Project Approach Prompt in, diagram out (one-shot) Programmatic element-level control (26 tools) State Stateless โ€” each call is independent Persistent live canvas with real-time sync Element CRUD No Full create / read / update / delete per element AI sees the canvas No describe_scene (structured text) + get_canvas_screenshot (image) Iterative refinement No โ€” regenerate the whole diagram Draw โ†’ look โ†’ adjust โ†’ look again, element by element Layout tools No align_elements, distribute_elements, group / ungroup File I/O No export_scene / import_scene (.excalidraw JSON) Snapshot & rollback No snapshot_scene / restore_snapshot Mermaid conversion No create_from_mermaid Shareable URLs Yes Yes โ€” export_to_excalidraw_url Design guide read_me cheat sheet read_diagram_guide (colors, sizing, layout, anti-patterns) Viewport control Camera animations set_viewport (zoom-to-fit, center on element, manual zoom) Live canvas UI Rendered inline in chat Standalone Excalidraw app synced via WebSocket Multi-agent Single user Multiple agents can draw on the same canvas concurrently Works without MCP No Yes โ€” REST API fallback via agent skill

TL;DR โ€” The official MCP generates diagrams. We give AI agents a full canvas toolkit to build, inspect, and iteratively refine diagrams โ€” including the ability to see what they drew.

What's New

v2.0 โ€” Canvas Toolkit

  • 13 new MCP tools (26 total): get_element, clear_canvas, export_scene, import_scene, export_to_image, duplicate_elements, snapshot_scene, restore_snapshot, describe_scene, get_canvas_screenshot, read_diagram_guide, export_to_excalidraw_url, set_viewport

  • Closed feedback loop: AI can now inspect the canvas (describe_scene) and see it (get_canvas_screenshot returns an image) โ€” enabling iterative refinement

  • Design guide: read_diagram_guide returns best-practice color palettes, sizing rules, layout patterns, and anti-patterns โ€” dramatically improves AI-generated diagram quality

  • Shareable URLs: export_to_excalidraw_url encrypts and uploads the scene to excalidraw.com, returns a shareable link anyone can open

  • Viewport control: set_viewport with scrollToContent, scrollToElementId, or manual zoom/offset โ€” agents can auto-fit diagrams after creation

  • File I/O: export/import full .excalidraw JSON files

  • Snapshots: save and restore named canvas states

  • Skill fallback: Agent skill auto-detects MCP vs REST API mode, gracefully falls back to HTTP endpoints when MCP server isn't configured

  • Fixed all previously known issues: align_elements / distribute_elements fully implemented, points type normalization, removed invalid label type, removed HTTP transport dead code, ungroup_elements now errors on failure

v1.x

  • Agent skill: skills/excalidraw-skill/ (portable instructions + helper scripts for export/import and repeatable CRUD)

  • Better testing loop: MCP Inspector CLI examples + browser screenshot checks (agent-browser)

  • Bugfixes: batch create now preserves element ids (fixes update/delete after batch); frontend entrypoint fixed (main.tsx)

Configure MCP Clients

The MCP server runs over stdio and can be configured with any MCP-compatible client. Below are configurations for both local (requires cloning and building) and Docker (pull-and-run) setups.

Environment Variables

Variable Description Default EXPRESS_SERVER_URL URL of the canvas server http://127.0.0.1:3000 ENABLE_CANVAS_SYNC Enable real-time canvas sync true

Claude Desktop

Config location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

Local (node)

Copy & paste โ€” that's it
{
 "mcpServers": {
 "excalidraw": {
 "command": "node",
 "args": ["/absolute/path/to/mcp_excalidraw/dist/index.js"],
 "env": {
 "EXPRESS_SERVER_URL": "http://127.0.0.1:3000",
 "ENABLE_CANVAS_SYNC": "true"
 }
 }
 }
}

Docker

Copy & paste โ€” that's it
{
 "mcpServers": {
 "excalidraw": {
 "command": "docker",
 "args": [
 "run", "-i", "--rm",
 "-e", "EXPRESS_SERVER_URL=http://host.docker.internal:3000",
 "-e", "ENABLE_CANVAS_SYNC=true",
 "ghcr.io/yctimlin/mcp_excalidraw:latest"
 ]
 }
 }
}

Claude Code

Use the claude mcp add command to register the MCP server.

Local (node) - User-level (available across all projects):

Copy & paste โ€” that's it
claude mcp add excalidraw --scope user \
 -e EXPRESS_SERVER_URL=http://127.0.0.1:3000 \
 -e ENABLE_CANVAS_SYNC=true \
 -- node /absolute/path/to/mcp_excalidraw/dist/index.js

Local (node) - Project-level (shared via .mcp.json):

Copy & paste โ€” that's it
claude mcp add excalidraw --scope project \
 -e EXPRESS_SERVER_URL=http://127.0.0.1:3000 \
 -e ENABLE_CANVAS_SYNC=true \
 -- node /absolute/path/to/mcp_excalidraw/dist/index.js

Docker

Copy & paste โ€” that's it
claude mcp add excalidraw --scope user \
 -- docker run -i --rm \
 -e EXPRESS_SERVER_URL=http://host.docker.internal:3000 \
 -e ENABLE_CANVAS_SYNC=true \
 ghcr.io/yctimlin/mcp_excalidraw:latest

Manage servers:

Copy & paste โ€” that's it
claude mcp list # List configured servers
claude mcp remove excalidraw # Remove a server

Cursor

Config location: .cursor/mcp.json in your project root (or ~/.cursor/mcp.json for global config)

Local (node)

Copy & paste โ€” that's it
{
 "mcpServers": {
 "excalidraw": {
 "command": "node",
 "args": ["/absolute/path/to/mcp_excalidraw/dist/index.js"],
 "env": {
 "EXPRESS_SERVER_URL": "http://127.0.0.1:3000",
 "ENABLE_CANVAS_SYNC": "true"
 }
 }
 }
}

Docker

Copy & paste โ€” that's it
{
 "mcpServers": {
 "excalidraw": {
 "command": "docker",
 "args": [
 "run", "-i", "--rm",
 "-e", "EXPRESS_SERVER_URL=http://host.docker.internal:3000",
 "-e", "ENABLE_CANVAS_SYNC=true",
 "ghcr.io/yctimlin/mcp_excalidraw:latest"
 ]
 }
 }
}

Codex CLI

Use the codex mcp add command to register the MCP server.

Local (node)

Copy & paste โ€” that's it
codex mcp add excalidraw \
 --env EXPRESS_SERVER_URL=http://127.0.0.1:3000 \
 --env ENABLE_CANVAS_SYNC=true \
 -- node /absolute/path/to/mcp_excalidraw/dist/index.js

Docker

Copy & paste โ€” that's it
codex mcp add excalidraw \
 -- docker run -i --rm \
 -e EXPRESS_SERVER_URL=http://host.docker.internal:3000 \
 -e ENABLE_CANVAS_SYNC=true \
 ghcr.io/yctimlin/mcp_excalidraw:latest

Manage servers:

Copy & paste โ€” that's it
codex mcp list # List configured servers
codex mcp remove excalidraw # Remove a server

OpenCode

Config location: ~/.config/opencode/opencode.json or project-level opencode.json

Local (node)

Copy & paste โ€” that's it
{
 "$schema": "https://opencode.ai/config.json",
 "mcp": {
 "excalidraw": {
 "type": "local",
 "command": ["node", "/absolute/path/to/mcp_excalidraw/dist/index.js"],
 "enabled": true,
 "environment": {
 "EXPRESS_SERVER_URL": "http://127.0.0.1:3000",
 "ENABLE_CANVAS_SYNC": "true"
 }
 }
 }
}

Docker

Copy & paste โ€” that's it
{
 "$schema": "https://opencode.ai/config.json",
 "mcp": {
 "excalidraw": {
 "type": "local",
 "command": ["docker", "run", "-i", "--rm", "-e", "EXPRESS_SERVER_URL=http://host.docker.internal:3000", "-e", "ENABLE_CANVAS_SYNC=true", "ghcr.io/yctimlin/mcp_excalidraw:latest"],
 "enabled": true
 }
 }
}

Antigravity (Google)

Config location: ~/.gemini/antigravity/mcp_config.json

Local (node)

Copy & paste โ€” that's it
{
 "mcpServers": {
 "excalidraw": {
 "command": "node",
 "args": ["/absolute/path/to/mcp_excalidraw/dist/index.js"],
 "env": {
 "EXPRESS_SERVER_URL": "http://127.0.0.1:3000",
 "ENABLE_CANVAS_SYNC": "true"
 }
 }
 }
}

Docker

Copy & paste โ€” that's it
{
 "mcpServers": {
 "excalidraw": {
 "command": "docker",
 "args": [
 "run", "-i", "--rm",
 "-e", "EXPRESS_SERVER_URL=http://host.docker.internal:3000",
 "-e", "ENABLE_CANVAS_SYNC=true",
 "ghcr.io/yctimlin/mcp_excalidraw:latest"
 ]
 }
 }
}

Notes

  • Docker networking: Use host.docker.internal to reach the canvas server running on your host machine. On Linux, you may need --add-host=host.docker.internal:host-gateway or use 172.17.0.1.

  • Canvas server: Must be running before the MCP server connects. Start it with npm run canvas (local) or docker run -d -p 3000:3000 ghcr.io/yctimlin/mcp_excalidraw-canvas:latest (Docker).

  • Absolute paths: When using local node setup, replace /absolute/path/to/mcp_excalidraw with the actual path where you cloned and built the repo.

  • In-memory storage: The canvas server stores elements in memory. Restarting the server will clear all elements. Use the export/import scripts if you need persistence.

Agent Skill (Optional)

This repo includes a skill at skills/excalidraw-skill/ that provides:

  • Workflow playbook (SKILL.md): step-by-step guidance for drawing, refining, and exporting diagrams

  • Cheatsheet (references/cheatsheet.md): MCP tool and REST API reference

  • Helper scripts (scripts/*.cjs): export, import, clear, healthcheck, CRUD operations

The skill complements the MCP server by giving your AI agent structured workflows to follow.

Install The Skill (Codex CLI example)

Copy & paste โ€” that's it
mkdir -p ~/.codex/skills
cp -R skills/excalidraw-skill ~/.codex/skills/excalidraw-skill

To update an existing installation, remove the old folder first (rm -rf ~/.codex/skills/excalidraw-skill) then re-copy.

Install The Skill (Claude Code)

User-level (available across all your projects):

Copy & paste โ€” that's it
mkdir -p ~/.claude/skills
cp -R skills/excalidraw-skill ~/.claude/skills/excalidraw-skill

Project-level (scoped to a specific project, can be committed to the repo):

Copy & paste โ€” that's it
mkdir -p /path/to/your/project/.claude/skills
cp -R skills/excalidraw-skill /path/to/your/project/.claude/skills/excalidraw-skill

Then invoke the skill in Claude Code with /excalidraw-skill.

To update an existing installation, remove the old folder first then re-copy.

Use The Skill Scripts

All scripts respect EXPRESS_SERVER_URL (default http://127.0.0.1:3000) or accept --url.

Copy & paste โ€” that's it
EXPRESS_SERVER_URL=http://127.0.0.1:3000 node skills/excalidraw-skill/scripts/healthcheck.cjs
EXPRESS_SERVER_URL=http://127.0.0.1:3000 node skills/excalidraw-skill/scripts/export-elements.cjs --out diagram.elements.json
EXPRESS_SERVER_URL=http://127.0.0.1:3000 node skills/excalidraw-skill/scripts/import-elements.cjs --in diagram.elements.json --mode batch

When The Skill Is Useful

  • Repository workflow: export elements as JSON, commit it, and re-import later.

  • Reliable refactors: clear + re-import in sync mode to make canvas match a file.

  • Automated smoke tests: create/update/delete a known element to validate a deployment.

  • Repeatable diagrams: keep a library of element JSON snippets and import them.

See skills/excalidraw-skill/SKILL.md and skills/excalidraw-skill/references/cheatsheet.md.

MCP Tools (26 Total)

Category Tools Element CRUD create_element, get_element, update_element, delete_element, query_elements, batch_create_elements, duplicate_elements Layout align_elements, distribute_elements, group_elements, ungroup_elements, lock_elements, unlock_elements Scene Awareness describe_scene, get_canvas_screenshot File I/O export_scene, import_scene, export_to_image, export_to_excalidraw_url, create_from_mermaid State Management clear_canvas, snapshot_scene, restore_snapshot Viewport set_viewport Design Guide read_diagram_guide Resources get_resource

Full schemas are discoverable via tools/list or in skills/excalidraw-skill/references/cheatsheet.md.

Testing

Canvas Smoke Test (HTTP)

Copy & paste โ€” that's it
curl http://127.0.0.1:3000/health

Local Bind Regression Test

Copy & paste โ€” that's it
npm run test:bind

MCP Smoke Test (MCP Inspector)

List tools:

Copy & paste โ€” that's it
npx @modelcontextprotocol/inspector --cli \
 -e EXPRESS_SERVER_URL=http://127.0.0.1:3000 \
 -e ENABLE_CANVAS_SYNC=true -- \
 node dist/index.js --method tools/list

Create a rectangle:

Copy & paste โ€” that's it
npx @modelcontextprotocol/inspector --cli \
 -e EXPRESS_SERVER_URL=http://127.0.0.1:3000 \
 -e ENABLE_CANVAS_SYNC=true -- \
 node dist/index.js --method tools/call --tool-name create_element \
 --tool-arg type=rectangle --tool-arg x=100 --tool-arg y=100 \
 --tool-arg width=300 --tool-arg height=200

Frontend Screenshots (agent-browser)

If you use agent-browser for UI checks:

Copy & paste โ€” that's it
agent-browser install
agent-browser open http://127.0.0.1:3000
agent-browser wait --load networkidle
agent-browser screenshot /tmp/canvas.png

Development

Copy & paste โ€” that's it
npm run type-check
npm run build