inkscape
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| INKSCAPE_MCP_TAG | No | Names the Inkscape instance (default `claude`), so several instances can run side by side; the test suite uses this to run on its own instance. | claude |
| INKSCAPE_MCP_STATE | No | The state folder for the instance (default `~/.inkscape-mcp`), so several instances can run side by side; the test suite uses this to run on its own instance. | ~/.inkscape-mcp |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| statusA | Is Inkscape (Claude) running; which documents are open; what is frontmost; what the user has selected. |
| launchB | Start Inkscape (Claude) if needed and open |
| outlineA | The object tree with ids, labels, text snippets and live bounding boxes (mm). root: start below this id (default: the whole page). depth: levels to expand; deeper content is summarised as counts. refresh: force re-reading the document (normally automatic). |
| findA | Find objects by any combination of: text content (case-insensitive substring), inkscape label, id regex, tag (text, g, rect, image, path…), a style substring (e.g. 'fill:#4b80ad'), or a page region [x0, y0, x1, y1] in mm (within = fully inside, overlaps = touches). top_level_only drops matches nested inside another match. |
| inspectB | Everything about specific objects: tag, label, where it sits in the tree, bounding box, every attribute (embedded images summarised), parsed style, full text, and its children. xml=True adds the raw XML (truncated to max_chars). |
| selectionA | Read what the user currently has selected (ids + boxes), or replace the selection with set_ids (useful to show the user which objects you mean). |
| renderA | Render the LIVE document to an image you can see. region_mm [x0, y0, x1, y1] or around=[ids] (+margin) choose the area; default is the whole page.
only=True hides everything except the |
| windowA | Screenshot of the Inkscape window itself (the user's view: zoom, selection handles, any open dialog). Use when something seems stuck or to see what the user is looking at. |
| changesA | What the user changed since you last looked or edited (or since |
| alignA | Align objects exactly. edges: 'left' | 'hcenter' | 'right' | 'top' | 'vcenter' | 'bottom', or one of each ('left top'). to: an object id to align to (it stays put), or first | last | biggest | smallest | page | drawing | selection. to_mm: align that edge to a page coordinate instead. as_group moves the ids as one block. expected_revision: refuse if the document changed since. |
| distributeB | Space objects along x or y. Without gap_mm: Inkscape's equal distribution between the outermost objects (mode gap | centers | left | right | top | bottom). With gap_mm: stack them in their current order with exactly that gap, starting at the first object (or at start_mm). |
| moveB | Move by (dx_mm, dy_mm) and/or place so the anchor point ('top-left', 'center', 'bottom-right', 'top-center'…) of the ids' joint box lands at (x_mm, y_mm). each=True places every object separately. |
| resizeB | Resize to an exact visual width or height (or by a scale factor), keeping the anchor corner fixed. keep_aspect=False with both width_mm and height_mm stretches (goes through the slower extension). |
| styleB | Set CSS style properties on objects, e.g. {"fill": "#4B80AD", "font-size": "11pt", "stroke-width": "0.5", "opacity": "0.8"}. A null value removes the property. Applies to groups too (children inherit unless they override — inspect them if a colour does not take). |
| attributesB | Set (or with null, remove) XML attributes: 'inkscape:label', 'width', 'rx', 'xlink:href', 'id'… |
| textC | Change text in ONE undoable batch. edits: [{"id": text id, "text": "new text; \n for new lines"}] keeps the first run's style. replace: [{"old": "…", "new": "…", "ids": optional scope}] swaps a substring inside existing runs, preserving mixed formatting (bold words, superscripts). |
| insertC | Place a figure file into the document with its top-left at (x_mm, y_mm), scaled to width_mm or height_mm (aspect kept). .svg is inlined as editable vector (ids namespaced so nothing collides); .png/.jpg are embedded (embed=False links the file instead). |
| add_svgA | Draw anything by writing SVG markup: shapes, lines, arrows, text, groups, gradients.
With x_mm/y_mm the markup's coordinates are |
| structureB | Rearrange objects. op: delete | duplicate | group | ungroup | pop_out (out of its group) |
raise | lower | top | bottom (z-order) | clone | unclone | reparent (move into |
| historyA | Undo or redo n steps in the live document (the same stack as the user's Cmd+Z). Pass expected_revision so an undo never takes back something the user did after your edit. |
| actionsA | Run any of Inkscape's ~1,070 actions, or search them. run: ["select-all", ["object-align", "left page"], ["transform-rotate", 90]] — returns what Inkscape printed, any complaint it logged (an action it rejected makes this an error), and whether the geometry changed (Inkscape ignores some malformed arguments silently). search: substring over action names and descriptions. Most act on the current selection; use selection(set_ids=…) first. To write files, prefer export. |
| pythonA | Run Python (inkex) against the live document in one undoable step — anything the other tools
cannot express. In scope: svg (root element), by_id(id), selected (ids), inkex, etree, Transform,
frames (frames.content(el) maps an element's coordinates to page px), to_px('3mm'), qname('inkscape:label'),
unique_id(base), parse_style/style_str. print() output and |
| exportA | Export the live document (unsaved changes included) to PDF, SVG, EPS, PS or PNG; the format comes from the file suffix (or format=). What to export: area='page' (default) or 'drawing' (everything drawn); or ids=[…] for those objects (only=False keeps whatever overlaps them); or region_mm=[x0, y0, x1, y1] (PNG only). dpi: PNG resolution, and the resolution filter effects are rasterised at in PDF/EPS/PS. text_to_path=True turns text into outlines (for printers that cannot take fonts). background: PNG background colour (default transparent). The file is read back afterwards: page size in mm, pixel size, fonts embedded. |
| save_copyA | Write the live document (unsaved changes included) to |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 24 tools
Most tools have clearly distinct purposes (e.g., outline vs inspect, find vs selection), but a few pairs overlap: export vs save_copy (both write files), move/align/distribute (positioning), actions vs python (general escape hatches), and style vs attributes (both set properties). Detailed descriptions help disambiguate, making it mostly distinct with a few confusable pairs.
All tool names are lowercase, using underscores only for multi-word names (save_copy, add_svg). The style is consistent, but the set mixes verbs (move, export) and nouns (selection, attributes, text), lacking a uniform verb_noun pattern.
24 tools is slightly above the typical 3-15 range, but the domain (full Inkscape control) is complex and each tool addresses a distinct area. Specialized tools plus general escape hatches (actions, python) are justified, though the set feels heavy.
The surface covers state reading, object manipulation, text/style/attribute editing, export, and general escape hatches. Minor gaps exist (no direct overwrite save, document close/switch), but actions and python provide workarounds.