Skip to main content
Glama
m9810223

tldraw-mcp

by m9810223

tldraw-m9810223

A Claude Code plugin: 26-tool MCP server for editing tldraw .tldr files via JSON manipulation (headless, no browser needed), plus a tldraw-screenshot skill that renders a .tldr to PNG via tldraw.com so Claude can SEE the diagram.

Status

Working skeleton. Schema validation is wired (@tldraw/tlschema validators run before every write), fractional indexing uses @tldraw/utils, file writes are guarded by proper-lockfile. Output verified end-to-end against the real tldraw runtime via Store.loadStoreSnapshot() in the contract test layer.

Quick Start

Requires Node ≥ 20.

1. Install as a Claude Code plugin (one command registers the marketplace, the second installs the bundled MCP server + skill):

claude plugin marketplace add m9810223/tldraw-m9810223
claude plugin install tldraw-m9810223@tldraw-m9810223

Restart Claude Code. /mcp lists tldraw-m9810223 (26 tools); /plugin lists tldraw-m9810223; the tldraw-screenshot skill is available too.

If you'd rather wire just the MCP server (no skill), see Install / Update / Remove below.

2. Try the demo prompt in Claude Code:

Draw the Shai-Hulud supply-chain attack flow described in this article with MCP `tldraw-m9810223`, save to `./demo.tldr`:
https://semgrep.dev/blog/2026/malicious-dependency-in-pytorch-lightning-used-for-ai-training/

- Match the actors and how data/control flows between them
- Polish the result at the end

3. View the result — drop ./demo.tldr onto tldraw.com, or use the tldraw VS Code extension for live preview.

Shai-Hulud supply-chain attack flow recreated by tldraw-m9810223

Source file: docs/demo.tldr

Tools

File / page lifecycle

Tool

What it does

create_empty_file

Create a fresh .tldr with a default page

create_page

Add a new page

list_pages

List pages with id, name, ordering index

move_to_page

Move shapes; bindings: 'error' | 'pull' | 'cut' controls binding handling

Shapes

Tool

What it does

create_rect

Create a rectangle (geo shape)

create_text

Create a text shape

create_group

Group shapes by reparenting them

ungroup

Dissolve a group, reparenting its children to the group's parent

connect

Arrow + bindings between two same-page shapes

list_shapes

List shapes — id, type, x, y, label only

get_shape

Full record of one shape by id

update_shape

Shallow-merge patch (use nested { "props": {...} } for prop edits)

delete_shape

Delete by id; cascade: true (default) also removes attached arrows + bindings

Layout / text fitting

Tool

What it does

fit_to_text

Resize a geo/text shape to fit its current text content

align

Align shapes on an axis (left/right/top/bottom/center-x/center-y)

distribute

Even-space shapes between the outermost two

auto_layout

Lay shapes out in a horizontal/vertical chain

graph_layout

Dagre layout for arrow-connected shapes (best for non-chain topologies)

measure_arrow_labels

Report label sizes + endpoint distances for labeled arrows

bend_overlapping_arrows

Bend parallel arrows (same shape pair) symmetrically; priority[] keeps important arrows straight. graph_layout calls this automatically.

polish_layout

One-shot finisher: fit_to_text every node + graph_layout (auto-bends arrows). Use as the last step after building a fresh diagram.

Discovery & escape hatch

Tool

What it does

Token cost

search_api

List supported shape types + curated required props. Pass {type, verbose:true} to dump live prop names from @tldraw/tlschema for any type (including ones not in the curated list)

low / medium

exec_jq

Run a jq filter against the file. write=true persists (auto-checkpoint first)

varies

Checkpoints (safety)

Tool

What it does

Token cost

save_checkpoint

Copy .tldr to a timestamped backup

low

list_checkpoints

List backups, newest first

low

restore_checkpoint

Restore a backup (most recent if checkpoint omitted)

low

The token-saving design: tools take primitive args, return ids or ok. The full JSON only enters context when you call get_shape deliberately.

Install / Update / Remove

jq only needed for exec_jq (brew install jq / apt-get install jq).

# Install (user scope by default)
claude plugin marketplace add m9810223/tldraw-m9810223
claude plugin install tldraw-m9810223@tldraw-m9810223

# Update
claude plugin update tldraw-m9810223

# Remove
claude plugin uninstall tldraw-m9810223
claude plugin marketplace remove tldraw-m9810223
rm -rf ~/.claude/plugins/cache/tldraw-m9810223   # optional — also drop the cached clone

# Verify clean (both should print nothing)
claude plugin list | grep tldraw
claude mcp list | grep -i tldraw

MCP server only (no skill)

Use this if you want the editing tools but not the screenshot skill, or you're on a Claude client that doesn't speak Code's plugin system.

# Install — user scope: every project on this machine
claude mcp remove tldraw-m9810223 -s user 2>/dev/null; rm -rf ~/.npm/_npx
claude mcp add -s user tldraw-m9810223 -- npx -y github:m9810223/tldraw-m9810223

# Install — local scope (default): only the current project directory
claude mcp remove tldraw-m9810223 2>/dev/null; rm -rf ~/.npm/_npx
claude mcp add tldraw-m9810223 -- npx -y github:m9810223/tldraw-m9810223

The first arg (tldraw-m9810223) is the local server name — pick whatever you like, then refer to it the same way in subsequent commands. Restart Claude Code, then /mcp lists it with 26 tools.

Wire up to other MCP clients

Same JSON shape, different config file location:

Client

Config path

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

Cursor

~/.cursor/mcp.json

VS Code

.vscode/mcp.json

Bootstrapping a .tldr file

Use the create_empty_file tool, or save an empty canvas from tldraw.com and point tools at the absolute path.

create_empty_file({ file: "/tmp/demo.tldr" })

Viewing / editing the output

Tool

Notes

tldraw-screenshot skill (bundled)

Programmatic render to PNG via playwright-cli + tldraw.com. Triggers automatically when Claude wants to see a .tldr

tldraw.com

Drag the .tldr file onto the page

tldraw VS Code extension

Native .tldr preview + edit inside VS Code; survives file changes from the MCP server

Tldraw Desktop / official editor

Drop the file in

The VS Code extension is the smoothest dev loop — keep code path/to/file.tldr open in a tab while the MCP edits it; the editor refreshes on disk change.

The tldraw-screenshot skill is the smoothest agent loop — Claude edits via the MCP, renders via the skill, looks at the PNG, edits again. See skills/tldraw-screenshot/SKILL.md for the workflow and gotchas. Requires playwright-cli on PATH.

Design comparison vs official tldraw-mcp-app

The Cloudflare-hosted official MCP exposes only search + exec (run any JS in a live tldraw Editor). This skeleton goes the opposite way — typed JSON edits over .tldr files — and borrows the discovery pattern (search_api) and escape hatch (exec_jq) so an LLM can fall through when typed tools don't cover an operation.

Official tldraw-mcp-app

This skeleton

Transport

streamable-http + sse (Cloudflare)

stdio (works in Claude Code directly)

Runtime

Real tldraw Editor in widget iframe

Pure Node, edits raw JSON

Tools

2 (search, exec) + checkpoints

26: file/page (4) + shape (9) + layout (8) + discovery (2) + ckpt (3)

Live preview

Yes (widget iframe)

No (open the file in tldraw to view)

Coverage

Whole Editor API

Geo / text / arrow + jq escape hatch

Known gaps

  • index (z-order) only supports appending above the current max — no insert-between

  • No image / video / asset support

  • Schema version pinning is informational only — opening a file in a newer tldraw may trigger migrations

  • search_api curated list is hand-maintained alongside the live @tldraw/tlschema reflection

Architecture

.claude-plugin/
  plugin.json       Plugin metadata + pointers to mcpServers + skills
  marketplace.json  Marketplace manifest so `claude plugin install` can find this
.mcp.json           Plugin-scoped MCP server declaration (npx-from-github)

skills/
  tldraw-screenshot/
    SKILL.md        Workflow for rendering .tldr → PNG via playwright-cli + tldraw.com

src/
  index.ts       MCP server entry, tool registration (stdio transport)
  tools.ts       Tool handlers + zod input schemas
  shapes.ts      tldraw record factories (geo/text/arrow/group/binding)
  store.ts       Load/save .tldr + withFileLock; helpers (id gen, indexing, find, page-of-shape, bindings-for-shape)
  template.ts    Empty .tldr generator using @tldraw/tlschema serialize()
  validate.ts    validateShape / validateBinding using createShapeValidator + createBindingValidator
  checkpoint.ts  Timestamped backups under .tldraw-mcp-checkpoints/
  jq.ts          Shell-out to jq for the exec_jq escape hatch
  text-metrics.ts Text size heuristics for autoFit + label measurement
  graph-layout.ts Dagre wrapper for graph_layout
  arrow-bending.ts Detect parallel-edge overlap + assign symmetric bend values

test/
  unit/          store + validate + text-metrics + arrow-bending (34 tests)
  integration/   tools end-to-end on tmp .tldr (39 tests)
  contract/      loadStoreSnapshot against real @tldraw/store (4 tests)
  boundary/      N-1 / N / N+1 limits + concurrent writes (89 tests)

Pure JSON manipulation — no @tldraw/store, no DOM, no React.

Install Server
F
license - not found
A
quality
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

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/m9810223/tldraw-m9810223'

If you have feedback or need assistance with the MCP directory API, please join our Discord server