inkscape
Drives the user's live, open Inkscape 1.4 window on macOS so an AI agent and the human can edit the same document simultaneously, with the agent's edits appearing immediately and landing on Inkscape's normal undo stack. Provides reading tools (status, outline, find, inspect, selection, render with object boxes/ids drawn, window screenshots, change diffs), layout tools built on Inkscape's own commands (align, distribute with equal or exact gaps, move by or to millimetre coordinates, resize to an exact visual width/height, styling, attributes, grouping and z-order, undo/redo history), content tools (setting or find/replacing text, inserting SVG/PNG/JPEG files, drawing arbitrary SVG markup in millimetres, and running arbitrary inkex Python code), and export tools (PDF, SVG, EPS, PS or PNG of the page, drawing, selected objects or a region) plus access to any of Inkscape's ~1,070 searchable actions. Every read and edit carries a revision fingerprint with an optional expected_revision guard to prevent clobbering concurrent human edits, and edits are verified as landed.
Click on "Deploy 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., "@inkscapealign the three section headers to the left edge of the sidebar"
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.
inkscape-live-mcp
An MCP server that lets an AI agent (built for Claude Code) work in the Inkscape window you have open, at the same time as you. Its edits appear in your window as they happen and sit on Inkscape's normal undo stack, so Cmd+Z takes them back. Your edits are visible to the agent the next time it looks, because it reads the live document, not a saved file.
macOS, Inkscape 1.4.
Why
Shared, live editing. No export–edit–reimport loop. You drag a panel; the agent sees it moved. The agent aligns six headers; you watch them snap into place and can undo it.
Exact layout by numbers. Every coordinate is millimetres from the page's top-left corner, measured on the visual bounding box (stroke and glyph edges included) that Inkscape itself reports. "Align these to the left edge of that panel", "stack them 8 mm apart", "make this exactly 70 mm wide" are one call each, computed, not eyeballed; there is no render–nudge–render loop.
Safe to share a document. Every read returns a revision; an edit given that revision refuses to run if you have changed the drawing since. Every edit reports whether it actually landed.
Related MCP server: inkscape-mcp
Requirements
macOS (tested on macOS 27, Apple Silicon) and Inkscape 1.4 (tested on 1.4.4) in
/Applications.Homebrew for
dbus(the installer runsbrew install dbusif needed).uv (
brew install uv).An MCP client. The installer registers the server with Claude Code; any client that runs stdio servers works.
Install
git clone https://github.com/declanbx/inkscape-live-mcp.git
cd inkscape-live-mcp
./install.shinstall.sh is idempotent (re-run it after pulling). It builds .venv with uv, links extension/ into
Inkscape's user extensions folder, creates ~/Applications/Inkscape (Claude).app, and runs
claude mcp add --scope user inkscape …. Flags: --no-register (skip the Claude Code registration),
--no-app (skip the launcher). For another client, register
<checkout>/.venv/bin/python <checkout>/run_server.py as a stdio server.
Optional, for Claude Code: cp -r skills/inkscape-live ~/.claude/skills/ adds a skill that teaches the
agent the workflow (route by cost, lay out by numbers, share the window safely).
Quick start
Open Inkscape (Claude).app, or drop an
.svgon it. It is the same Inkscape with your usual preferences, started so that the agent can reach it. (A window opened the normal way is not reachable; see How it works.)In Claude Code, ask in plain words: "align the six section headers to the left edge of the Summary panel", "space column 2's boxes 8 mm apart", "what did I change?", "make these the same width as the map" (with objects selected), "replace the title".
Save with Cmd+S as usual. The agent never saves over your file; it can write a copy (
save_copy).
Tools (server name inkscape)
Reading | Layout: Inkscape's own commands, ~0.1–1 s, one undo step each | Content: one undo step per batch | Other |
|
|
|
|
Safety nets on every call
Revision guard. Every read and edit ends with
revision <id>, a fingerprint of every object's id and visual box in paint order, read live from Inkscape. Every editing tool takes an optionalexpected_revision; if the document no longer matches it, the tool refuses, changes nothing, and lists what changed since (moved/added/removed objects).changesreports the current revision and makes it the new baseline;changes(since_revision=…)diffs against any revision read this session.historytakes it too, so an undo never takes back something you did after the agent's edit.Landed verification. After each edit the touched objects' live boxes are compared with what the edit planned: exact positions for moves and gaps, a shared edge for alignment, equal spacing for distribution, new ids present and deleted ids gone for inserts and deletes. The result says
Landed: confirmed,NOT LANDED as planned: …(with what is where), orLanded: unconfirmedfor an edit with no geometric trace, such as a colour.No-op batches add no undo step. The bridge compares the document before and after a batch; if it is byte-identical it hands nothing back, so Inkscape adds no undo entry and your next Cmd+Z still undoes the last real change.
Exports are read back.
exportreopens the file it wrote and checks it against what was asked: the PDF page size in mm (read with macOS Quartz), the PNG's pixel size, the SVG's document size, and whether fonts are embedded or text was turned into outlines (text_to_path=True).Raw actions say what Inkscape did. If Inkscape logs a rejection (
transform-translate abc→ "requires two comma separated numbers"),actionsreturns an error with that reason; otherwise it reports whether the geometry changed, because Inkscape ignores some malformed arguments without a word.Uncertain completion is reported, never retried. If Inkscape does not answer in time (a dialog is open, a huge document), the call returns
UNCERTAIN COMPLETIONinstead of an error or a silent retry: the edit may still apply. The next call waits for Inkscape to finish it before reading or editing.
Cost model
Measured with tests/bench.py on a synthetic A0 document of 50,082 objects (15 MB, one 8 MB embedded
image), Apple Silicon laptop, through the MCP server:
Operation | Time |
status | 0.3 s |
align / move / style (native) | 0.6–0.7 s |
distribute five panels to an exact gap | 1.1 s |
changes (geometry diff) | 0.3 s |
find / outline (tree cached) | 0.25 s |
first outline of an unedited file (read from disk) | 1.6 s |
first outline of an edited document (via the bridge) | 1.7 s |
render the whole page / one panel | 0.8 s / 0.4 s |
bridge edit (text, add_svg, insert, python) | 3.0–3.2 s |
bridge batch that changes nothing | 2.2 s |
undo of a bridge edit | 1.2 s |
export the page as PDF / one panel as PDF (via a headless copy) | 3.4 s / 3.0 s |
export the page as PNG at 150 dpi | 1.1 s |
On a 2,000-object figure everything is under 0.6 s. Bridge edits grow with document size, because
Inkscape serialises the whole document to the extension and reloads its result: on a real 100,000-element
poster with heavily clipped figures one bridge edit took about 16 s. So batch content edits: text
takes a list, add_svg and python take many elements at once.
How it works
Native route.
launch.shstarts a private D-Bus session bus (~/.inkscape-mcp/bus.sock) and opens Inkscape as the unique applicationorg.inkscape.Inkscape.claudeon it (--app-id-tag=claude). Inkscape then publishes its actions overorg.gtk.Actions;inkscape_live_mcp/bus.pycalls them and reads query output (query-all,select-list) from Inkscape's stdout, whichlaunch.shlogs to a file.Bridge route. For what no action can do (text content, inserting markup or files, reparenting, arbitrary edits),
extension/claude_bridge.pyis an effect extension the server triggers over the same bus. It reads a request file, applies the whole batch atomically (if any operation fails, nothing changes), and hands the document back as one undo step.Reading. Boxes come from
query-allon every call. The XML tree is cached and re-read only when the set of objects changes; when the window shows no unsaved changes it is read straight from the file.Choosing an instance.
INKSCAPE_MCP_TAG(defaultclaude) names the instance andINKSCAPE_MCP_STATE(default~/.inkscape-mcp) its state folder, so several instances can run side by side; the test suite uses this to run on its own instance.
Quirks, and how they are handled
Launch constraints silently disable Python extensions when Inkscape is exec'd from a shell, so no edit through the bridge would work.
launch.shtherefore starts Inkscape through LaunchServices (open -n -a … --env … --args --app-id-tag=…).GTK on macOS exports no
/window/Nobjects on D-Bus, only the application and/document/N(confirmed on 1.4.4 by the test suite). Every operation uses application-level actions plus/document/Nfor undo, redo and extensions; window-level actions such as save and zoom are left to you.Open-file limit. Inkscape 1.4.2 on macOS can crash the first time it runs an extension if it inherits a ~1M soft
RLIMIT_NOFILE, common under IDEs and agent hosts (reported in aravindev/inkscape_mcp#33). Launched through LaunchServices, Inkscape does not inherit the caller's limit: from a shell with 1,048,576 the extension sees 2,560 (Inkscape 1.4.4). The test suite asserts it stays at or below 4,096.Wrong boxes for groups that contain a nested
<svg>. Inkscape 1.4 adds the nested viewBox size, in parent units, to the group's box (an inserted 70 mm legend is reported 105.8 mm wide). The server rebuilds those groups' boxes from their children and aligns them with computed moves rather than Inkscape's own Align.Export settings persist inside a running Inkscape, and some cannot be switched back (measured on 1.4.4): once text-to-path is on, setting it off has no effect, and the page/drawing area mode can be changed but never unset. PNG exports therefore pass an explicit area and pixel size every time; PDF, SVG, EPS and PS exports write the live document to a temporary copy, crop the copy to the page, the drawing, the chosen objects or a region, and export it with a fresh headless Inkscape. Your window's export state is never touched, and a region works for PDF too (Inkscape's own vector export ignores one).
Inkscape's own "drawing" area is wrong for documents holding a nested
<svg>(the bug below), soexport(area="drawing")uses the corrected boxes.Some action arguments are ignored silently. A bare or misspelled
object-aligndoes nothing and logs nothing;transform-translate abclogs a reason. See "Raw actions say what Inkscape did".select-by-idadds to the selection: every command clears it first, then restores your selection.export-areacannot be cleared once set, so every render passes an explicit area.A saved copy keeps its source's internal document name, so the front window is matched by file name first.
Two sessions driving one Inkscape would interleave on the bridge files and the stdout log, so every client call holds a cross-process lock (
~/.inkscape-mcp/client.lock).
Limitations
macOS only. On Linux the same D-Bus mechanism works natively; see Related work.
The revision sees geometry, not paint. A colour-only or attribute-only edit you make does not change the revision, and
Landedcannot confirm such an edit.changes(deep=True)re-reads the document and reports text and style differences.The guard is a check, not a lock: an edit you make in the milliseconds between the check and the agent's edit is not caught.
Bridge edits reload the whole document: seconds on large documents (see Cost model).
Tools act on the front window. With several documents open, the front one is identified from the window title; click the window you want if it is ambiguous.
Inkscape 1.4 only. Other versions are untested.
Security
No network access, no API keys, no telemetry. Everything runs on your machine.
python(andactions) run arbitrary code inside Inkscape's Python as you, by design, with the same trust as the agent's own shell access. Run the server only for agents you would give a shell to.The bus is a private
dbus-daemonwhose socket lives in~/.inkscape-mcp(mode 0700, as are its bridge files and logs).
Tests
.venv/bin/python tests/test_units.py # no Inkscape needed
.venv/bin/python tests/e2e.py # 62 checks over MCP on a private Inkscape instance
.venv/bin/python tests/bench.py # the cost table abovee2e.py and bench.py launch their own Inkscape with a fresh tag, a private bus, a temporary state folder
and a throwaway Inkscape profile, check before any edit that the server is driving that instance, and
quit it afterwards (--keep leaves it open). They never touch a window you have open.
Related work
aravindev/inkscape_mcp is the closest prior art: the same mechanism, a running Inkscape driven over D-Bus plus inkex extensions, together with a headless CLI mode and a much broader tool surface, on Linux and Windows (macOS support is an open pull request). This project adds layout by Inkscape-measured visual boxes in millimetres (with the nested-
<svg>box correction), exact align/distribute/resize tools, renders annotated with object ids, a change diff and revision guard for editing alongside a person, edit-landed verification, and macOS support today. The check for actions Inkscape rejected follows its CLI wrapper's stderr scan.Shriinivas/inkmcp: live control of a running Inkscape over D-Bus with an extension and inkex code execution (Linux).
tspspi/mcpinkscape: an offline SVG backend plus an optional native C++ Inkscape extension for live editing with snapshots, polling and revision-conflict protection; the revision guard here follows its
expected_revisionidea.P1oN/inkscape-mcp-server: a native Rust server with guarded, verified edits; the landed check, the "uncertain completion" result and the no-op-adds-no-undo rule here follow its design.
Files
launch.sh (bus + Inkscape) · install.sh · run_server.py (entry point) · inkscape_live_mcp/
(bus.py D-Bus and stdout log, client.py operations, revision guard and landed checks, svgtree.py
tree and box model, server.py MCP tools) · extension/ (claude_bridge.inx/.py) · tests/
(_instance.py private test instance, e2e.py, bench.py, test_units.py, fixtures/) ·
skills/inkscape-live/SKILL.md (a Claude Code skill for using the tools well).
State and logs: ~/.inkscape-mcp/ (inkscape.out.log, inkscape.err.log, bridge/bridge.log, renders).
Troubleshooting
Tools say "not running": open
Inkscape (Claude).app(a normal Inkscape window is not reachable).UNCERTAIN COMPLETIONor a stuck call: callwindowto see Inkscape; a dialog may be open.After updating, re-run
install.shand restart Inkscape (Claude), which reads extensions at startup.
License
MIT, see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Lets AI agents use a real human as a tool: visual checks, taste, phone calls, unblocking, approvals
Create and edit architecture diagrams from your AI agent; get an SVG and a live editable canvas.
Agent-Native design tool - create and edit visual designs with agent assistance
Create and improve live, shared interactive documents with your agent.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceMCP server that lets AI agents drive Inkscape — interactively alongside the GUI or headlessly from the CLI296 PyPI70MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to control Inkscape for vector graphics editing via MCP tools.81MIT
- AlicenseAqualityDmaintenanceEnables AI agents to inspect, edit, validate, render, and export SVG/Inkscape documents safely with reversible operations and risk-classed tools.876MIT

Rayzia MCPofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to drive a live SVG/vector editor, allowing a full observe-and-act loop on a canvas with real tools, state reading, and PNG rendering.1MIT