Excalidraw MCP for Cursor: Visual Diagrams in AI Code

GuidesAugust 24, 20268 min readBy PinVari
Excalidraw MCP for Cursor: Visual Diagrams in AI Code

Excalidraw MCP for Cursor is a Model Context Protocol server that lets the Agent read and update an Excalidraw board as structured tools instead of guessing from a screenshot. You keep the .excalidraw file in the repo, add a server block to .cursor/mcp.json, and the Agent can list shapes, add a node, or rewrite a flow without you pasting a JPEG.

Most teams still drop a PNG into chat and hope the model counts the arrows. That works once. It fails the first time two boxes share a label.

What is Excalidraw MCP for Cursor, in practice?

Excalidraw is a JSON document that happens to look like a whiteboard. MCP is a wire that exposes tools. Cursor is the client that calls those tools.

The useful product is the combination. The Agent asks for the current scene. The server returns element ids, types, text, and links. The Agent then mutates one id instead of redrawing the whole page from pixels.

Read what an MCP server is if the handshake still feels abstract. Then treat the board as a database of shapes.

A screenshot of the board is still useful for humans. It is a terrible source of truth for an Agent that has to keep a sequence diagram honest across a sprint.

Key

The protocol is plumbing. The payload is the scene graph. Rank an Excalidraw MCP by whether it returns ids you can edit, not a prettier canvas.

Named elements on the board beat a vision pass over a PNG.

How do I wire Excalidraw MCP into Cursor for a whole team?

Cursor reads two files. Global: ~/.cursor/mcp.json. Project: .cursor/mcp.json in the repo root.

Project wins on a name collision. Put the Excalidraw server in the project file so every clone gets the same command and the same board path.

A stdio block looks like this:

{
  "mcpServers": {
    "excalidraw": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-everything"],
      "env": {
        "EXCALIDRAW_PATH": "${workspaceFolder}/docs/architecture.excalidraw"
      }
    }
  }
}

That snippet is a shape, not a blessed package name. Use the server your team actually runs. Keep secrets out of the file. Dotfile repos leak mcp.json.

The Cursor MCP setup page is the longer install path. This page is the diagram workflow.

Fully quit Cursor after you edit either file. A window reload does not always re-read the config.

Tip

Commit the .excalidraw file. Do not commit API keys. One person owning the board in iCloud is how teams get three versions of the same flow.

If you also run a Mac spatial capture connector, keep it in the global file. That connector talks to an app on 127.0.0.1:3402 and should not be repo-specific.

Why do pasted Excalidraw screenshots fail at team scale?

Vision is expensive. A 4K whiteboard is a lot of tokens for one missing arrow.

The Agent then invents a box that was never there. You spend the next review saying "no, the cache sits behind the gateway."

A tool result with element ids skips that loop. The Agent can say "update element rect-12 text to Checkout API" and the file stays mergeable.

Two people editing a PNG in Slack is not version control. Two people editing JSON in a pull request is.

I have watched a five-person team argue about a screenshot that was two days stale. The live .excalidraw file in docs/ would have ended the argument in a minute.

Ask, never guess applies to diagrams the same way it applies to UI. If the server cannot find the node, it should say so.

Heads up

If the board is AX-blind canvas in a browser tab, a screen-capture tool will not give you shape ids. Use the Excalidraw file or the MCP scene tools. Do not invent a node id you did not see.

What should a good Excalidraw MCP tool list look like?

I want a short list. I do not want twenty tools that all mean "draw."

list_scene

Type: read.

Capture: element id, type, text, group, frame.

Resolution: a shape, not a pixel.

Use it so the Agent stops asking you to paste the board into chat.

get_element

Type: read.

Capture: one id and its links.

Resolution: a single node.

Use it when the Agent is about to edit one box and should not reload the whole scene.

upsert_element

Type: write.

Capture: create or update text, links, and group.

Resolution: the same id after the write.

Refuse tools that only return a new PNG. A PNG is a side effect. The file is the product.

export_png (optional)

Type: read.

Capture: a preview for humans.

Resolution: none.

Keep it optional. Reviews still want a picture. Agents should not treat the picture as source.

The MCP server examples catalog covers other shapes. Here I only care that Cursor's Agent can mutate a diagram without leaving the repo.

How do I run this with Claude Code and Cursor on the same team?

Some seats live in Cursor. Some live in a terminal agent. The board should not care.

Cursor reads mcp.json. Claude Code reads a user-scope MCP entry. The file on disk is shared.

For Claude Code the honest add looks like this when you also use PinVari:

claude mcp add --scope user pinvari -- "$HOME/.pinvari/mcp/pinvari-mcp"

Never the bare claude mcp add pinvari. That form errors.

The Excalidraw server is a separate entry. Add it with the same --scope you use for the rest of the team tools, or keep it project-local next to the .excalidraw file.

PinVari is the layer for a running UI. Hold ⌥⌘A, circle a control, speak the change. Transcription stays on-device. The Agent gets role, label, frame, confidence, and circled-versus-dwelled provenance.

That is not a substitute for a sequence diagram. It is how you correct the running app after the diagram said one thing and the screen said another.

The pricing block for PinVari is $39 launch for the first 500 licenses, then $59, one-time. Team seats are available. No subscription for the core app.

You still bring your own model. Cursor's bill is Cursor's bill.

How should a team store boards so Agents do not fork reality?

One board per concern. docs/checkout-flow.excalidraw. docs/auth-sequence.excalidraw. Not a 200-box kitchen sink.

Name boxes with the same words you use in code. CheckoutService on the board should match CheckoutService in the repo. Cute labels like "the money box" are how Agents invent files.

Put a one-line rule in Cursor rules: when the user mentions a flow, call the Excalidraw tools before editing code. Rules do not replace tools. They tell the Agent when to call them.

Lock exports. If someone must paste a PNG into Slack, export from the committed file, not from a local unsaved tab.

On a multi-display desk, people screenshot the wrong monitor. The file does not have that problem.

Crash-safe habits matter. If Cursor dies mid-edit, the .excalidraw JSON should still parse. Teach the Agent to write valid JSON or not write at all.

Bring your own agent still applies. The server does not replace Cursor. It feeds it a scene.

How do I test Excalidraw MCP for Cursor in fifteen minutes?

Pick one real flow. Not a demo todo app.

Ask Agent to list the scene and rename one box. Watch the first tool result.

If you still have to paste a screenshot, the server lost.

If the JSON diff is a single element and the preview still looks right, keep it.

If the server hangs, check the process. Local stdio children die when you quit the parent.

Then ask a second seat to pull the branch and list the same scene. If they see a different board, your path is wrong.

What should I refuse to add next to the diagram server?

Anything that screenshots the whole desktop on every turn.

Anything that needs a cloud key to read a file that already lives in git.

Anything whose tool names collide with a server you already trust.

A long list of red tools in Settings, MCP is not a stack. It is latency.

I also refuse servers that claim they "understand the diagram" when they only ship a PNG. Understanding is an id, a type, and a write that survives merge.

Jam.dev still wins for browser-only console capture. It cannot own your architecture board. CleanShot X still wins for a pretty Mac screenshot. It will not give the Agent a shape id.

FAQ

Is Excalidraw MCP for Cursor the same as pasting the board into chat?

No. Paste is a picture. MCP is tools over a scene graph. The Agent can update one element and leave the rest alone.

Can I use the official Excalidraw web app with this?

Yes, as a human editor. Save the file back into the repo. The Agent should read the file or the MCP scene, not a random browser tab.

Does every teammate need the same MCP package version?

Yes, or you will see missing tools on one seat. Pin the version in the project config or in a documented npx argument. Drift is how "it works on my Mac" starts.

What if the green dot never appears in Cursor?

Quit Cursor fully. Confirm the command path exists. Confirm Node can run the server. Then reopen Settings, MCP. A stale stdio child is the usual fault.

Should the Agent also get a screenshot of the running product?

When the bug is on screen, yes. Use a local spatial server that returns a named Accessibility element, not another JPEG of the whole desk. Hold ⌥⌘A and speak. Below about 0.8 confidence, the Agent should ask.

Can I keep the board in Notion or a wiki instead?

You can. The Agent then depends on a hosted export. I keep the source in git so a pull request is the review surface. Wikis drift. Files get diffs.

A team-scale diagram habit is boring on purpose. One file, one server, one rule that says "read the board before you rewrite the flow."

I would rather have that honesty than a prettier gallery of MCP logos.

Pick Excalidraw MCP for Cursor by reading one tool result. If it names the box, you are done shopping.

Hand your agent the exact element

PinVari resolves what you point at into a named, executable instruction — on-device, no keys, your own agent. One click inside PinVari connects Claude Code, Cursor, VS Code or Codex — or paste one CLI line from pinvari.com/connect.

PinVari → Connect → your agent (one click)
Get PinVari — $39 →