Skip to main content
Glama

inkwire

A local MCP server with a shared drawing canvas, for collaborating visually with an AI agent on a codebase. You draw a system freehand in the browser; the server infers structure; Claude reads the board as data over MCP, edits it, and discusses it. Both of you write to the same board.

Quick start

yarn install
yarn build

Inkwire ships as a Claude Code plugin: the MCP server, a Stop hook, the /use-inkwire and /back-to-claude-code commands, and the model-invocable trace-path skill. Install it once; it then loads in every session:

claude plugin marketplace add /path/to/inkwire
claude plugin install inkwire@inkwire

Adjust CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS to 0 in your ~/.claude/settings.json

For a one-off run without installing, claude --plugin-dir /path/to/inkwire does the same for that session. Tool names carry the plugin prefix: mcp__plugin_inkwire_inkwire__boards_create.

The Session tab (below) needs two settings. Put them in ~/.claude/settings.json to make them permanent, or in the .claude/settings.json of the project you use inkwire from:

{
  "env": { "CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS": "0" },
  "permissions": { "defaultMode": "auto" }
}

The canvas works without them. This repo's own .claude/settings.json already carries both.

Inkwire runs as one daemon. The first Claude Code session starts it, and it stops 30 s after the last session closes. All sessions share the daemon and port 4691. Each session runs a small relay (dist/link/relay.js) that connects to the daemon.

Then ask Claude to create a board (boards_create). boards_create needs a project_root: the absolute path of the checkout that the board's code refs point into. The tool result contains the panel URL — open it in your browser:

http://127.0.0.1:4691/?board=<board id>

Draw with the pen (P), then press infer_structure (or ask Claude to run it). Closed shapes become nodes; connecting lines become edges. Claude renames the nodes after reading a screenshot.

Related MCP server: excalidraw-mcp

Many sessions

Many Claude Code sessions can use inkwire at the same time, in different repos. Each board has a maximum of one AI Author. The first Claude Code session that writes to a board becomes its Author. The other sessions are readers: they can read the board, but a write fails and names the Author. The panel shows the Author and the number of readers.

To give the board to a different session, click Release in the panel. Then the next write from a different session claims the board. The released session cannot claim that board again until a different session claims it, the released session closes, or you click Allow pid N in the panel. No agent can take authorship away from a different session.

For a git worktree, use boards_clone with the worktree as the new project_root. The session that clones the board becomes the Author of the clone.

After a rebuild

The daemon does not restart by itself after yarn build. When a Claude Code session starts with a newer build, the panel shows a stale-build notice. To use the new build, click Restart in the panel, or run yarn daemon:restart. When all Claude Code sessions close, the daemon stops after 30 s, and the next session starts the new build. A restart drops the undo history and every pending session_send on every board.

After a reconnect or a restart, each session keeps its current board. It does not keep its authorship or its inkwire mode. The next write claims the board again if the board is free (see Many sessions).

Session tab: talking in the panel

Type /use-inkwire in the terminal. Claude flips a server-held mode flag, and from then on delivers replies through the blocking session_send tool into the panel's SESSION tab, where you answer from the composer. A reply can carry a highlight: node and edge ids the canvas lights up. It can also carry a path: an ordered walk over a layer's edges, one caption per hop, that plays in the panel. The Layers tab lists each layer's paths; click ▸ on a path row to open the scrubber as a vertical walk under the row, one row per node and one per hop with its caption. Hold ▸ to peek the walk on the canvas. Drag the walk or press ← → to step; esc closes it. The /trace-path skill writes one when you ask "walk me through" or "what happens when". /back-to-claude-code (typed, or the button in the strip) brings replies back to the terminal.

Two requirements, both checked by the server when the mode goes on, and both covered by the settings above:

  • Permission mode auto or bypassPermissions — nobody is at the terminal to approve prompts. Switching modes inside the session works too; the check runs when /use-inkwire does.

  • CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS=0 — otherwise Claude Code moves the blocking call to a background task after two minutes.

The mode is per Claude Code session, and only the board's Author can turn it on. The mode is not persisted: after a reconnect or a daemon restart, the session is in the terminal again. A session_send that waits 20 minutes with no answer returns idle and flips the mode back.

Development

yarn dev          # dev daemon (tsx watch) + panel bundle (esbuild watch)
yarn dev:claude   # Claude Code with this repo as the plugin, on the dev daemon
yarn test         # full vitest suite
yarn health       # build, then run every MCP tool through a real daemon and relays
yarn typecheck

yarn dev runs the dev daemon on port 4692 with ~/.inkwire-dev and INKWIRE_IDLE_GRACE_MS=off, so it does not touch the daemon on 4691 or the data in ~/.inkwire. Panel URL: http://127.0.0.1:4692/?board=<id>.

yarn dev:claude starts Claude Code with --plugin-dir . and the dev port and data dir. The relay and the hook use the dev daemon. If yarn dev does not run, the relay starts a daemon from dist/ on 4692. The relay always runs from dist/, so after a change to the relay, run yarn build.

Tests use random ports and temp data dirs. They never use 4691, 4692, ~/.inkwire or ~/.inkwire-dev.

Health check: run yarn health after a change to the link, the daemon, the gate or any tool. It builds, starts a real daemon and two or more relays on a random port with a temp dir, and runs every MCP tool through the full link. A failed case names the tool or the part of the daemon lifecycle that is broken. yarn test skips the one case that needs dist/ when dist/build.json is missing or older than src/; yarn health never skips it (a stale dist/ fails it). yarn health deletes and rebuilds dist/, so do not run it in the checkout that live Claude Code sessions use as the plugin.

Configuration (env vars): INKWIRE_PORT (default 4691), INKWIRE_DATA_DIR (default ~/.inkwire — SQLite plus an images/ directory), INKWIRE_IDLE_GRACE_MS (daemon only; default 30000, off turns the idle stop off). There is no project-root env var: each board stores its own project_root (set it with boards_create, boards_clone, boards_import or boards_update), and every code ref on the board resolves against it.

The design handoff that specifies this project lives in design_handoff_inkwire/. See CLAUDE.md for architecture notes.

Upgrade notes

To the shared daemon

  1. Close all Claude Code sessions that use the old inkwire server. If an old session holds port 4691, the new relay stops with "port 4691 is held by an old inkwire server; close the old Claude Code sessions".

  2. Run yarn build and install the plugin update. yarn build deletes dist/ first, so the old dist/server/index.js is gone and an old .mcp.json (step 3) fails with a missing-file error. It does not start a hidden old server.

  3. A project .mcp.json that starts inkwire with node .../dist/server/index.js must change its args to .../dist/link/relay.js. Also remove INKWIRE_PROJECT_ROOT from its env: it has no effect now.

  4. Start one new Claude Code session and do the post-migration step.

Post-migration step: run boards_list and set a root on every root: unset board with boards_update. At migration time this is one board, b_8946f6 "Discover Config API — generateDiscoverConfig", root /Users/clayton.noyes/angel-studios (its 8 refs all start with content-collections/; verified 2026-10-08).

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A shared whiteboard for you and your AI agent I wanted my AI agent and me to be able to point at the same thing. Any MCP-capable agent can read the canvas, draw on it, drop thought bubbles, animate elements, and react when you sketch something.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to create and manipulate live visual diagrams on an Excalidraw canvas in real-time via MCP tools.
    3,111 npm
    38 PyPI
    15
    BSD 3-Clause
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to draw animated, hand-drawn diagrams on a live whiteboard through MCP tools, allowing users to visually explain concepts and edit scenes interactively.
    34 npm
    AGPL 3.0