inksmcp 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. inksmcp-0.3.0/.gitignore +25 -0
  2. inksmcp-0.3.0/CHANGELOG.md +69 -0
  3. inksmcp-0.3.0/LICENSE +21 -0
  4. inksmcp-0.3.0/PKG-INFO +138 -0
  5. inksmcp-0.3.0/README.md +111 -0
  6. inksmcp-0.3.0/docs/README.md +18 -0
  7. inksmcp-0.3.0/docs/development/README.md +60 -0
  8. inksmcp-0.3.0/docs/development/field-reports/README.md +39 -0
  9. inksmcp-0.3.0/experiments/README.md +44 -0
  10. inksmcp-0.3.0/pyproject.toml +56 -0
  11. inksmcp-0.3.0/src/inksmcp/__init__.py +3 -0
  12. inksmcp-0.3.0/src/inksmcp/checks.py +222 -0
  13. inksmcp-0.3.0/src/inksmcp/document.py +1429 -0
  14. inksmcp-0.3.0/src/inksmcp/engine.py +1403 -0
  15. inksmcp-0.3.0/src/inksmcp/files.py +247 -0
  16. inksmcp-0.3.0/src/inksmcp/grids.py +152 -0
  17. inksmcp-0.3.0/src/inksmcp/inkscape.py +249 -0
  18. inksmcp-0.3.0/src/inksmcp/layout.py +372 -0
  19. inksmcp-0.3.0/src/inksmcp/server.py +765 -0
  20. inksmcp-0.3.0/src/inksmcp/templates.py +152 -0
  21. inksmcp-0.3.0/tests/__init__.py +0 -0
  22. inksmcp-0.3.0/tests/conftest.py +29 -0
  23. inksmcp-0.3.0/tests/test_align.py +120 -0
  24. inksmcp-0.3.0/tests/test_docs.py +30 -0
  25. inksmcp-0.3.0/tests/test_document.py +101 -0
  26. inksmcp-0.3.0/tests/test_engine.py +87 -0
  27. inksmcp-0.3.0/tests/test_field_report_1.py +145 -0
  28. inksmcp-0.3.0/tests/test_field_report_2.py +215 -0
  29. inksmcp-0.3.0/tests/test_field_report_3.py +46 -0
  30. inksmcp-0.3.0/tests/test_fit.py +107 -0
  31. inksmcp-0.3.0/tests/test_foreign_files.py +217 -0
  32. inksmcp-0.3.0/tests/test_inkscape.py +73 -0
  33. inksmcp-0.3.0/tests/test_layout_connect.py +168 -0
  34. inksmcp-0.3.0/tests/test_page.py +137 -0
  35. inksmcp-0.3.0/tests/test_recipes.py +48 -0
  36. inksmcp-0.3.0/tests/test_repeat.py +96 -0
  37. inksmcp-0.3.0/tests/test_round2_bugs.py +130 -0
  38. inksmcp-0.3.0/tests/test_round2_step0.py +110 -0
  39. inksmcp-0.3.0/tests/test_round2_step1.py +110 -0
  40. inksmcp-0.3.0/tests/test_round2_step2.py +181 -0
  41. inksmcp-0.3.0/tests/test_round2_step3.py +59 -0
  42. inksmcp-0.3.0/tests/test_server.py +83 -0
  43. inksmcp-0.3.0/tests/test_z_order.py +122 -0
@@ -0,0 +1,25 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ venv/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+
9
+ # Node
10
+ node_modules/
11
+ dist/
12
+
13
+ # Editors / OS
14
+ .vscode/
15
+ .idea/
16
+ Thumbs.db
17
+ .DS_Store
18
+
19
+ # Local scratch / outputs
20
+ out/
21
+ tmp/
22
+ *.log
23
+
24
+ # Experiment outputs
25
+ experiments/out/
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project. Format loosely follows [Keep a Changelog](https://keepachangelog.com/).
4
+
5
+ ## Unreleased
6
+
7
+ ## 0.3.0 — 2026-10-06
8
+
9
+ First public release. Round-2 build from ten field reports, editing of files made elsewhere, and release packaging:
10
+ 24 tools, 160 tests against the real Inkscape.
11
+
12
+ ### Added
13
+ - 2026-09-28 — Release packaging: MIT license, PyPI metadata (`uvx inksmcp`), `server.json` for the MCP Registry, CI on Linux, Windows and macOS, a tag-triggered release workflow (PyPI trusted publishing, GitHub release, registry), user docs (getting started, recipes, a tool reference generated from the server), contributing and security notes. Development docs moved to `docs/development/`.
14
+ - 2026-09-28 — Editing files made elsewhere (D-030, experiment e30): `document_open` normalises page geometry (%, mismatched or offset viewBoxes, stretched pages) and root paint without changing the rendering, and says so in `notes`; `.svgz` open/save; `inspect` shows computed fill/stroke, `use` targets, flowed text and symbols, and `find` lists matches by type, colour, text, href or id prefix; `use` element type (`library.svg#symbol` copies a symbol in once); deleting elements removes defs only they used. 6 new tests (140 total).
15
+ - 2026-09-28 — Round-2 step 3 (D-028): `repeat` `cell` (rows placed by their own column/row numbers) and the `split` tool (a region divided into named cell rects by column ratios, height ratios and gutters). Tables are a documented `split` + `repeat` recipe. Experiment e28. 3 new tests (132 total).
16
+ - 2026-09-28 — Round-2 step 2 (D-027): automatic overlap warnings in editing responses (text on text, text across a shape edge, un-haloed text crossed by a line; stacked elements reported once); `place` key (stored below/above/left_of/right_of + gap + align, re-applied with `fit_to` in one dependency order, also after align/layout moves of the reference); `layout` items with an `anchor`. Experiment e27. 6 new tests (129 total).
17
+ - 2026-09-28 — Round-2 step 1, files in (D-026): `image` element (linked or embedded, natural size, `object_fit`), `import_file` tool (SVG as one scaled group with renamed ids and fixed references; images), `add_elements` `elements_path` and `repeat` `rows_path` (JSON/CSV). Experiments e25, e26; findings F33, F34. 4 new tests (123 total).
18
+ - 2026-09-28 — Round-2 step 0 (D-025): `clip` key on any element (element id or rect; clipped bbox; follows the element), text `halo` / `halo_width`, connector `start_gap` / `end_gap`, connectors placed in their ends' layer or a "Connectors" layer with `layers` and `labels` in the response, `repeat` `order: "column"`, shortened id runs in `repeat` responses, `id_prefix` clash error, clearer `repeat` / `align` / element descriptions. Experiment e24; findings F32, S11. 6 new tests (119 total).
19
+ - 2026-09-28 — `path_operation` returns `result`: the ids holding the outcome (combine keeps the top id, the other boolean ops the bottom one; E22, F30).
20
+ - 2026-09-28 — `grid` log axes: `labels: "decades" | "paper"`; decade labels follow `start` by default when it is given (D-023).
21
+ - 2026-09-27 — rect `fit_to` / `fit_padding` / `fit`: a box sized around other elements after wrapping, re-fitted when they are edited, chained in dependency order, usable in `repeat` templates. Decision D-020. 4 new tests (103 total).
22
+ - 2026-09-27 — `repeat` tool: stamp a template per data row (placeholders, local ids, step/columns, alternate mirroring that reflects shapes and moves texts/groups as blocks, off-page warnings, all or nothing). Experiment e21; finding F29; decision D-019. E20 timeline: 37 % less request text. 3 new tests (99 total).
23
+
24
+ ### Fixed
25
+ - 2026-09-28 — Windows: with Inkscape installed through Chocolatey (and other package managers whose shims start the GUI build), the server picked the shim on PATH and silently loaded nothing. The locator now prefers `inkscape.com` on PATH, then the install folders, and refuses a GUI-only build with a message (F39).
26
+ - 2026-09-28 — From field report 12 (re-run on 0.3.0) and the first CI run: text wrapped with `width` could overflow by up to 2.3 % in fonts other than Arial (lines are now measured, F38); `use` ignored width/height for symbols without a viewBox and drew library icons in the wrong units; `run_actions` extensions silently changed the whole drawing when `select` was given (now refused, F37); saved files reopened with a rounding "normalisation"; `find text` missed flowed text past 160 characters. `document_save` reports bytes, PNG exports their pixel size. 9 new tests (159 total); locator test (160).
27
+ - 2026-09-28 — From field report 11 (editing Inkscape's own sample files): `.svgz` could not be opened and unexpected errors reached the agent as an empty "Error executing tool"; pages whose viewBox didn't match their size were measured wrongly and `page_fit` wrote a non-uniform scale; `import_file` dropped the source root's fill/stroke, could stretch, and numbered id-less elements differently from `document_open`; `place` reported the move instead of the box; `sodipodi:docname` kept a temp name; the `defaults` error blamed every key when `type` was the problem; `find`-style lookups skipped elements at random (unstable proxy ids).
28
+ - 2026-09-28 — Overlap warnings no longer flag shapes hidden under a text's opaque balloon or caption box (comic page 2: 15 false warnings → 0), and findings are grouped per text (D-029, experiment e29). 2 new tests (134 total).
29
+ - 2026-09-28 — A crash of the Inkscape shell part-way through a tool left the document half-changed (e.g. elements written but not wrapped/fitted). Every tool now restores the document on failure, and a dead shell is retried once (E23, D-022). Errors name the exit code and command. 10 new tests (113 total).
30
+ - 2026-09-28 — `grid` silently dropped major lines and labels when `major` was a rounded multiple of `minor` (11.6667 / 2.3333); spacings that don't nest are now an error (D-023). `plot` no longer warns about edge points a hair outside.
31
+ - 2026-09-28 — `path_operation` described combine's surviving id wrongly.
32
+ - 2026-09-27 — The element help in the `add_elements` description showed a garbled em dash (`—`).
33
+ - 2026-09-27 — `vertical_anchor` placed texts inside transformed groups or layers wrongly: it compared the local `y` with document-space measurements.
34
+
35
+ ## 0.2.0 — 2026-09-27
36
+
37
+ Phase 1 (MVP) and Phase 2 (agent-load reducers): 21 tools, three field tests, benchmark baseline in `docs/development/benchmarks.md`.
38
+
39
+ ### Added
40
+ - 2026-09-27 — Reference benchmark (experiment e20, `docs/development/benchmarks.md`): calls, request/response size, image tokens and time for 5 tasks, plus tool-list size. Phase 2 baseline: 4–8 calls, 0.4k–1.9k tokens per task; tool list ≈ 6.3k tokens.
41
+ - 2026-09-27 — From field report 3 (flight infographic), cheap follow-ups: `plot` child ids follow the series id, `label_halo` and `label_anchor` options, label placement and halo documented; `grid` axis `"lines": false`; `bold_major` documented. Experiment e19; decision D-018. 2 new tests (96 total).
42
+ - 2026-09-27 — From field report 2 (heat-pump poster): `plot` tool and `grid` axis titles; connector `from_side`/`to_side`/`via` (own router, stays attached), label position/side/offset/font/halo; `marker_start`/`marker_end` on lines/paths; `arrow` element; text `width` wrapping; `move_to_layer` position. Experiments e17, e18; findings F26–F28, S10; decisions D-015–D-017. 13 new tests (94 total).
43
+ - 2026-09-27 — From field report 1 (log graph paper): `grid` tool (linear/log axes, weight classes, border, measured labels); `render_preview` `region` and zoom-by-ids; `export` `region`/`only_ids`; `add_elements` `defaults`; text `vertical_anchor`. Experiments e15, e16, e16b; findings F23–F25; decisions D-012–D-014. 9 new tests (81 total).
44
+ - 2026-09-27 — `z_order` (front/back/above/below exact; forward/backward overlap-based) and `move_to_layer`; cross-parent moves keep the visual position via affine compensation (`layout.py`).
45
+ - 2026-09-27 — Experiment e13; finding F22; decision D-011; `docs/development/field-reports/`. 9 new tests (70 total).
46
+ - 2026-09-27 — `inspect` summarises layers/groups with many children and supports `layer` drill-down (E14: 30,806 → 600 chars). 2 new tests (72 total).
47
+ - 2026-09-27 — `page_fit` (drawing or ids + margin, origin kept at 0,0, backgrounds resized, connectors follow) and `page_resize` (exact size, anchor top-left/center, off-page warnings).
48
+ - 2026-09-27 — Moves snapped to 0.001 user units and moved elements tidied to 4 decimals (no more `20.000042`).
49
+ - 2026-09-27 — Experiments e11, e12; findings F18–F21; decision D-010. 12 new tests (61 total).
50
+
51
+ ### Fixed
52
+ - 2026-09-27 — Multi-line text had a doubled first line gap and ignored `line_height` (F26); indents were collapsed.
53
+ - 2026-09-27 — A strip of the line showed past arrowhead tips (S10): flat-front arrowheads.
54
+ - 2026-09-27 — `render_preview`/`export` with several ids produced nothing (`export-id` takes one id, F23); "was not found" warnings now raise.
55
+ - 2026-09-27 — Shell work batched: grid with 74 labels 11.2 s → 1.2 s; test suite 22.7 s → 14.5 s (F25).
56
+ - 2026-09-27 — Connectors passed to a move (directly or as top-level content) were moved twice (F20).
57
+ - 2026-09-27 — `connect` tool: native Inkscape connectors (straight/elbow), per-colour arrow markers, midpoint labels with halo, warnings for text endpoints; connectors re-sync after `update_elements`; `delete_elements` cascades to attached connectors and labels.
58
+ - 2026-09-27 — `layout` tool: row/column/grid, items as id lists moved together, block placement (`at` / `to` + align).
59
+ - 2026-09-27 — Off-page warnings from `align` and `layout`.
60
+ - 2026-09-27 — Experiments e09, e09b, e10; findings F15–F18, S7–S9; decisions D-008, D-009. 13 new tests (49 total).
61
+ - 2026-09-27 — `align` tool: batch alignment to page / selection / element, `as_group`, `margin`; text centred by measured cap box so labels share baselines. New `layout.py` (pure maths), `Engine.measure` / `translate` / `align`. 10 new tests.
62
+ - 2026-09-27 — Experiments e07, e07b, e08; findings F12–F14, S4–S6; decision D-007.
63
+ - 2026-09-27 — Registered the server for Claude Code via project `.mcp.json`.
64
+ - 2026-09-27 — Phase 1 MVP: persistent Inkscape shell driver, lxml document model, Inkscape-backed engine, MCP server with 12 tools (`inkscape_info`, `document_create/open/save`, `inspect`, `add/update/delete_elements`, `path_operation`, `run_actions`, `export`, `render_preview`).
65
+ - 2026-09-27 — Test suite (26 tests) against real Inkscape, incl. end-to-end via in-process MCP client.
66
+ - 2026-09-27 — Experiments e01–e06 and findings F1–F11, S1–S3 in `docs/development/inkscape-notes.md`.
67
+ - 2026-09-27 — Decisions D-002…D-006; lessons learned; experiment-driven workflow in `docs/development/README.md`.
68
+ - 2026-09-27 — Initial docs skeleton: objectives, plan, architecture, features, Inkscape notes, decision log, lessons learned.
69
+ - 2026-09-27 — Git repository initialized.
inksmcp-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Bhanu Prakash Bheemaneni
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
inksmcp-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,138 @@
1
+ Metadata-Version: 2.5
2
+ Name: inksmcp
3
+ Version: 0.3.0
4
+ Summary: MCP server that lets AI assistants create, edit and export vector graphics with Inkscape
5
+ Project-URL: Homepage, https://github.com/bhanutpt/inksmcp
6
+ Project-URL: Documentation, https://github.com/bhanutpt/inksmcp/tree/main/docs
7
+ Project-URL: Issues, https://github.com/bhanutpt/inksmcp/issues
8
+ Project-URL: Changelog, https://github.com/bhanutpt/inksmcp/blob/main/CHANGELOG.md
9
+ Author-email: Bhanu Prakash Bheemaneni <sbvscp@gmail.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai,claude,inkscape,mcp,model-context-protocol,svg,vector-graphics
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: End Users/Desktop
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Multimedia :: Graphics :: Editors :: Vector-Based
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Requires-Python: >=3.12
24
+ Requires-Dist: lxml>=6.1.3
25
+ Requires-Dist: mcp>=2.2.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ # inksmcp
29
+
30
+ **An MCP server that lets AI assistants create, edit and export vector graphics with Inkscape.**
31
+
32
+ <!-- mcp-name: io.github.bhanutpt/inksmcp -->
33
+
34
+ [![CI](https://github.com/bhanutpt/inksmcp/actions/workflows/ci.yml/badge.svg)](https://github.com/bhanutpt/inksmcp/actions/workflows/ci.yml)
35
+ [![PyPI](https://img.shields.io/pypi/v/inksmcp)](https://pypi.org/project/inksmcp/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/inksmcp)](https://pypi.org/project/inksmcp/)
37
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/bhanutpt/inksmcp/blob/main/LICENSE)
38
+
39
+ Describe a poster, a diagram, a chart or a comic page to your assistant, and it builds a real SVG
40
+ document in Inkscape: measured, laid out and exported to PNG or PDF. It can also open drawings made
41
+ elsewhere and change them.
42
+
43
+ | | | |
44
+ |---|---|---|
45
+ | ![Comic page](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/comic.png) | ![Periodic table poster](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/periodic-table.png) | ![Swimlane flowchart](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/flowchart.png) |
46
+ | ![Floor plan](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/floor-plan.png) | ![Datasheet with four plots](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/datasheet.png) | ![Tamil alphabet poster](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/alphabet-poster.png) |
47
+
48
+ *Made by Claude through inksmcp during field tests, in 13 to 41 tool calls each. The SVG was never edited
49
+ by hand. The floor plan and the periodic table used a short script to prepare their data.*
50
+
51
+ ## Why inksmcp
52
+
53
+ Asking a model to write SVG by hand works for an icon, but it breaks down on real layouts. The model
54
+ can't measure text, keeps redoing coordinate arithmetic, and can't see what it drew. inksmcp takes
55
+ that work off the model:
56
+
57
+ - **Measured, not guessed.** Bounding boxes come from Inkscape itself, text included, in the
58
+ document's own units.
59
+ - **Relationships instead of coordinates.** `align` and `layout` arrange things. `place` keeps a
60
+ caption below a title's real glyphs. `fit_to` sizes a box around its content. `connect` draws arrows
61
+ that stay attached when things move.
62
+ - **Data-driven.** `repeat` stamps a template per data row (cards, timelines, legends, table rows,
63
+ character poses). `split` divides a page into panels or cells. Large data comes from JSON or CSV
64
+ files, so it doesn't pass through the conversation.
65
+ - **Works on existing files.** It opens `.svg`/`.svgz` drawings from other tools. `inspect find`
66
+ locates elements by colour, type, text or symbol. Symbols can be placed from icon libraries.
67
+ - **Safe and checkable.** Every tool is all-or-nothing. Editing responses warn about overlapping text,
68
+ and `render_preview` shows the agent what it drew.
69
+ - **Real output.** PNG, PDF (optionally with text as paths), plain SVG, EPS, EMF and more, rendered by
70
+ Inkscape.
71
+
72
+ ## Quick start
73
+
74
+ 1. Install [Inkscape](https://inkscape.org/release/) 1.x and [uv](https://docs.astral.sh/uv/).
75
+ 2. Add the server to your MCP client. For Claude Code:
76
+
77
+ ```bash
78
+ claude mcp add --scope user inkscape -- uvx inksmcp
79
+ ```
80
+
81
+ For Claude Desktop, Cursor and others:
82
+
83
+ ```json
84
+ { "mcpServers": { "inkscape": { "command": "uvx", "args": ["inksmcp"] } } }
85
+ ```
86
+
87
+ 3. Ask: *"Using the inkscape tools, make an A5 flyer for a book swap on Saturday at 10:00 in the library
88
+ garden, show me a preview, then export a PDF."*
89
+
90
+ Details for each OS and client, and troubleshooting, are in [getting started](https://github.com/bhanutpt/inksmcp/blob/main/docs/getting-started.md).
91
+
92
+ ## Tools
93
+
94
+ | Area | Tools |
95
+ |---|---|
96
+ | Documents | `document_create`, `document_open`, `document_save`, `inspect` (outline, real bboxes, `find`), `inkscape_info` |
97
+ | Elements | `add_elements` (rect, circle, ellipse, line, polyline, polygon, path, text, group, arrow, image, use), `update_elements`, `delete_elements`, `import_file`, `repeat` |
98
+ | Arrangement | `align`, `layout`, `split`, `connect`, `z_order`, `move_to_layer`, `page_fit`, `page_resize` |
99
+ | Charts | `grid` (linear/log graph paper and axes), `plot` (data series in data values) |
100
+ | Paths | `path_operation` (union, difference, intersection, combine, stroke to path, ...), `run_actions` (guarded raw Inkscape actions) |
101
+ | Output | `render_preview` (PNG back to the agent), `export` |
102
+
103
+ See the [recipes](https://github.com/bhanutpt/inksmcp/blob/main/docs/recipes.md) for how they combine, and the [tool reference](https://github.com/bhanutpt/inksmcp/blob/main/docs/tools.md) for every
104
+ parameter.
105
+
106
+ ## How it works
107
+
108
+ The document lives in the server as an lxml tree, which is the source of truth. Edits are applied
109
+ there directly. Anything that needs Inkscape (measuring, boolean operations, connectors, rendering,
110
+ export) goes to one persistent `inkscape --shell` process, so a call takes milliseconds instead of
111
+ the ~1 s it takes to start Inkscape. The [architecture notes](https://github.com/bhanutpt/inksmcp/blob/main/docs/development/architecture.md) have
112
+ the details.
113
+
114
+ ## Status
115
+
116
+ inksmcp is **beta** (0.3). It has been through eleven field tests, in which agents used it for real
117
+ tasks. The latest one edited files made in other tools. There are 160 tests, and they run against
118
+ the real Inkscape.
119
+
120
+ Known limits:
121
+ - It is developed on Windows with Inkscape 1.4.4. CI also runs on Linux and macOS.
122
+ - The tool list costs about 9k tokens of context per session.
123
+ - Gradients and patterns can't be created as style keys yet. They can be applied through raw `style`
124
+ when they already exist in the document.
125
+ - SVG 1.2 flowed text can be moved but not edited.
126
+
127
+ The [roadmap](https://github.com/bhanutpt/inksmcp/blob/main/docs/development/roadmap.md) lists what's next.
128
+
129
+ ## Contributing
130
+
131
+ Bug reports, field reports ("I asked for X, here's what the agent struggled with") and pull requests
132
+ are welcome. See [CONTRIBUTING.md](https://github.com/bhanutpt/inksmcp/blob/main/CONTRIBUTING.md). The project is built experiment-first: every
133
+ Inkscape behaviour it relies on is proven by a script in `experiments/` and guarded by a test. The
134
+ [development handbook](https://github.com/bhanutpt/inksmcp/blob/main/docs/development/README.md) explains the method.
135
+
136
+ ## License
137
+
138
+ [MIT](https://github.com/bhanutpt/inksmcp/blob/main/LICENSE). Inkscape is a separate program under the GPL; inksmcp calls it as an external process.
@@ -0,0 +1,111 @@
1
+ # inksmcp
2
+
3
+ **An MCP server that lets AI assistants create, edit and export vector graphics with Inkscape.**
4
+
5
+ <!-- mcp-name: io.github.bhanutpt/inksmcp -->
6
+
7
+ [![CI](https://github.com/bhanutpt/inksmcp/actions/workflows/ci.yml/badge.svg)](https://github.com/bhanutpt/inksmcp/actions/workflows/ci.yml)
8
+ [![PyPI](https://img.shields.io/pypi/v/inksmcp)](https://pypi.org/project/inksmcp/)
9
+ [![Python](https://img.shields.io/pypi/pyversions/inksmcp)](https://pypi.org/project/inksmcp/)
10
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/bhanutpt/inksmcp/blob/main/LICENSE)
11
+
12
+ Describe a poster, a diagram, a chart or a comic page to your assistant, and it builds a real SVG
13
+ document in Inkscape: measured, laid out and exported to PNG or PDF. It can also open drawings made
14
+ elsewhere and change them.
15
+
16
+ | | | |
17
+ |---|---|---|
18
+ | ![Comic page](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/comic.png) | ![Periodic table poster](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/periodic-table.png) | ![Swimlane flowchart](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/flowchart.png) |
19
+ | ![Floor plan](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/floor-plan.png) | ![Datasheet with four plots](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/datasheet.png) | ![Tamil alphabet poster](https://raw.githubusercontent.com/bhanutpt/inksmcp/main/docs/images/alphabet-poster.png) |
20
+
21
+ *Made by Claude through inksmcp during field tests, in 13 to 41 tool calls each. The SVG was never edited
22
+ by hand. The floor plan and the periodic table used a short script to prepare their data.*
23
+
24
+ ## Why inksmcp
25
+
26
+ Asking a model to write SVG by hand works for an icon, but it breaks down on real layouts. The model
27
+ can't measure text, keeps redoing coordinate arithmetic, and can't see what it drew. inksmcp takes
28
+ that work off the model:
29
+
30
+ - **Measured, not guessed.** Bounding boxes come from Inkscape itself, text included, in the
31
+ document's own units.
32
+ - **Relationships instead of coordinates.** `align` and `layout` arrange things. `place` keeps a
33
+ caption below a title's real glyphs. `fit_to` sizes a box around its content. `connect` draws arrows
34
+ that stay attached when things move.
35
+ - **Data-driven.** `repeat` stamps a template per data row (cards, timelines, legends, table rows,
36
+ character poses). `split` divides a page into panels or cells. Large data comes from JSON or CSV
37
+ files, so it doesn't pass through the conversation.
38
+ - **Works on existing files.** It opens `.svg`/`.svgz` drawings from other tools. `inspect find`
39
+ locates elements by colour, type, text or symbol. Symbols can be placed from icon libraries.
40
+ - **Safe and checkable.** Every tool is all-or-nothing. Editing responses warn about overlapping text,
41
+ and `render_preview` shows the agent what it drew.
42
+ - **Real output.** PNG, PDF (optionally with text as paths), plain SVG, EPS, EMF and more, rendered by
43
+ Inkscape.
44
+
45
+ ## Quick start
46
+
47
+ 1. Install [Inkscape](https://inkscape.org/release/) 1.x and [uv](https://docs.astral.sh/uv/).
48
+ 2. Add the server to your MCP client. For Claude Code:
49
+
50
+ ```bash
51
+ claude mcp add --scope user inkscape -- uvx inksmcp
52
+ ```
53
+
54
+ For Claude Desktop, Cursor and others:
55
+
56
+ ```json
57
+ { "mcpServers": { "inkscape": { "command": "uvx", "args": ["inksmcp"] } } }
58
+ ```
59
+
60
+ 3. Ask: *"Using the inkscape tools, make an A5 flyer for a book swap on Saturday at 10:00 in the library
61
+ garden, show me a preview, then export a PDF."*
62
+
63
+ Details for each OS and client, and troubleshooting, are in [getting started](https://github.com/bhanutpt/inksmcp/blob/main/docs/getting-started.md).
64
+
65
+ ## Tools
66
+
67
+ | Area | Tools |
68
+ |---|---|
69
+ | Documents | `document_create`, `document_open`, `document_save`, `inspect` (outline, real bboxes, `find`), `inkscape_info` |
70
+ | Elements | `add_elements` (rect, circle, ellipse, line, polyline, polygon, path, text, group, arrow, image, use), `update_elements`, `delete_elements`, `import_file`, `repeat` |
71
+ | Arrangement | `align`, `layout`, `split`, `connect`, `z_order`, `move_to_layer`, `page_fit`, `page_resize` |
72
+ | Charts | `grid` (linear/log graph paper and axes), `plot` (data series in data values) |
73
+ | Paths | `path_operation` (union, difference, intersection, combine, stroke to path, ...), `run_actions` (guarded raw Inkscape actions) |
74
+ | Output | `render_preview` (PNG back to the agent), `export` |
75
+
76
+ See the [recipes](https://github.com/bhanutpt/inksmcp/blob/main/docs/recipes.md) for how they combine, and the [tool reference](https://github.com/bhanutpt/inksmcp/blob/main/docs/tools.md) for every
77
+ parameter.
78
+
79
+ ## How it works
80
+
81
+ The document lives in the server as an lxml tree, which is the source of truth. Edits are applied
82
+ there directly. Anything that needs Inkscape (measuring, boolean operations, connectors, rendering,
83
+ export) goes to one persistent `inkscape --shell` process, so a call takes milliseconds instead of
84
+ the ~1 s it takes to start Inkscape. The [architecture notes](https://github.com/bhanutpt/inksmcp/blob/main/docs/development/architecture.md) have
85
+ the details.
86
+
87
+ ## Status
88
+
89
+ inksmcp is **beta** (0.3). It has been through eleven field tests, in which agents used it for real
90
+ tasks. The latest one edited files made in other tools. There are 160 tests, and they run against
91
+ the real Inkscape.
92
+
93
+ Known limits:
94
+ - It is developed on Windows with Inkscape 1.4.4. CI also runs on Linux and macOS.
95
+ - The tool list costs about 9k tokens of context per session.
96
+ - Gradients and patterns can't be created as style keys yet. They can be applied through raw `style`
97
+ when they already exist in the document.
98
+ - SVG 1.2 flowed text can be moved but not edited.
99
+
100
+ The [roadmap](https://github.com/bhanutpt/inksmcp/blob/main/docs/development/roadmap.md) lists what's next.
101
+
102
+ ## Contributing
103
+
104
+ Bug reports, field reports ("I asked for X, here's what the agent struggled with") and pull requests
105
+ are welcome. See [CONTRIBUTING.md](https://github.com/bhanutpt/inksmcp/blob/main/CONTRIBUTING.md). The project is built experiment-first: every
106
+ Inkscape behaviour it relies on is proven by a script in `experiments/` and guarded by a test. The
107
+ [development handbook](https://github.com/bhanutpt/inksmcp/blob/main/docs/development/README.md) explains the method.
108
+
109
+ ## License
110
+
111
+ [MIT](https://github.com/bhanutpt/inksmcp/blob/main/LICENSE). Inkscape is a separate program under the GPL; inksmcp calls it as an external process.
@@ -0,0 +1,18 @@
1
+ # Documentation
2
+
3
+ ## Using inksmcp
4
+
5
+ | Page | What it covers |
6
+ |---|---|
7
+ | [Getting started](getting-started.md) | Install Inkscape and the server, connect a client, first prompts, troubleshooting |
8
+ | [Recipes](recipes.md) | How the tools combine: posters, data-driven cards, panels and tables, flowcharts, charts, editing existing files, export. Every recipe is run by the test suite |
9
+ | [Tool reference](tools.md) | All 24 tools and their parameters, generated from the server |
10
+ | [Changelog](../CHANGELOG.md) | What changed in each version |
11
+
12
+ ## Developing inksmcp
13
+
14
+ The [development handbook](development/README.md) explains how the project is built (experiment →
15
+ finding → test → code → field test) and holds its history: roadmap, architecture, decision log,
16
+ Inkscape findings, lessons learned, benchmarks and the field reports from real agent sessions.
17
+ [Contributing](../CONTRIBUTING.md) covers setup and pull requests; [releasing](development/releasing.md)
18
+ covers publishing a version.
@@ -0,0 +1,60 @@
1
+ # Development handbook
2
+
3
+ How inksmcp is built, and where its history lives. For using it, see the [user docs](../README.md).
4
+
5
+ These are **living documents**: they grow with the code and are updated in the same commit.
6
+
7
+ ## Files
8
+
9
+ | File | What it holds |
10
+ |---|---|
11
+ | [objectives.md](objectives.md) | Goals, non-goals, success criteria |
12
+ | [roadmap.md](roadmap.md) | Phases, the current phase, next steps |
13
+ | [architecture.md](architecture.md) | Layers, abstractions, data flow |
14
+ | [features.md](features.md) | Every tool and feature with its status, the agent load it removes, and its tests |
15
+ | [inkscape-notes.md](inkscape-notes.md) | Inkscape and SVG facts proven by experiments (F#, S#) |
16
+ | [decisions.md](decisions.md) | Decision log, ADR-lite (D-###) |
17
+ | [lessons-learned.md](lessons-learned.md) | Pitfalls and what we do about them now |
18
+ | [benchmarks.md](benchmarks.md) | Calls and tokens for reference tasks, per phase |
19
+ | [field-reports/](field-reports/README.md) | Reports from agent sessions that used the tools for real tasks |
20
+ | [releasing.md](releasing.md) | How a version goes out (PyPI, GitHub, MCP Registry) |
21
+
22
+ Also: [CHANGELOG.md](../../CHANGELOG.md) for dated changes, [experiments/](../../experiments/README.md) for the probes behind every finding.
23
+
24
+ ## How we work (D-003)
25
+
26
+ Theory only at the level of principles; reality decides the details.
27
+
28
+ 1. **Question**: something we need to rely on ("are export options sticky?").
29
+ 2. **Experiment**: a small script in `experiments/eNN_*.py` against the real Inkscape.
30
+ 3. **Finding**: recorded in `inkscape-notes.md` with an id (F#, S#) and its source.
31
+ 4. **Test**: a test in `tests/` that fails if the finding stops being true or the code forgets it.
32
+ 5. **Code**: the smallest abstraction that removes the burden from the agent.
33
+ 6. **Real usage**: drive the server like an agent would (a field test, ideally by a fresh agent that sees only the tool descriptions); what the agent still has to compute becomes the next feature.
34
+
35
+ A surprising test failure is a new experiment result: record it, don't just patch it.
36
+
37
+ ## Commands
38
+
39
+ ```bash
40
+ uv sync # dev environment
41
+ uv run pytest # needs Inkscape; ~30 s
42
+ uv run inksmcp # the server on stdio
43
+ uv run python experiments/e30_foreign_files.py
44
+ uv run python scripts/gen_tools_doc.py # regenerate docs/tools.md after changing a tool
45
+ ```
46
+
47
+ While an MCP client holds the server open, `uv run` can't replace `.venv/Scripts/inksmcp.exe` on Windows: use `uv run --no-sync` (see lessons learned).
48
+
49
+ ## Maintenance rules
50
+
51
+ - **Every meaningful change updates the docs in the same commit.** Code without doc updates is incomplete.
52
+ - New feature → add or update a row in `features.md`; a changed tool signature or description → regenerate `docs/tools.md` (a test fails otherwise).
53
+ - A choice between alternatives → an entry in `decisions.md`.
54
+ - Something surprised us or cost time → `lessons-learned.md`.
55
+ - Discovered Inkscape behaviour → `inkscape-notes.md`.
56
+ - Phase progress → tick items in `roadmap.md`.
57
+ - User-visible change → `CHANGELOG.md` under `Unreleased`.
58
+ - A field report → a row in `field-reports/README.md`; each follow-up becomes experiment → test → fix, then is marked done there.
59
+ - Use absolute dates (`YYYY-MM-DD`), never "yesterday" or "last week".
60
+ - Placeholders are marked `TBD`: search for them to find gaps.
@@ -0,0 +1,39 @@
1
+ # Field reports
2
+
3
+ Reports written by agents (or people) who **used** inksmcp for a real task in a separate session —
4
+ not by the session that builds it. They are the "real usage" step of the method in
5
+ [../README.md](../README.md): what the agent still had to compute, work around or guess becomes
6
+ the next feature, finding or fix.
7
+
8
+ File name: `YYYY-MM-DD-<task>.md`. Template:
9
+
10
+ ```
11
+ # <task>
12
+ - Date / client / model:
13
+ - Result files:
14
+ - Tool calls (approx.) and time:
15
+
16
+ ## What worked well
17
+ ## What was awkward (agent had to compute, retry, or work around)
18
+ ## Missing tools or options
19
+ ## Bugs / surprising behaviour (with the exact call and response)
20
+ ## Suggestions
21
+ ```
22
+
23
+ | Date | Task | Outcome | Follow-ups |
24
+ |---|---|---|---|
25
+ | 2026-09-27 | [A4 log-log graph paper, 3 x 5 cycles](2026-09-27-log-graph-a4.md) | Done in 14 tool calls; all coordinates computed outside the tools | ✅ All addressed 2026-09-27 (E15, E16): multi-id export fixed, `region` + zoom-by-ids in `render_preview`, `grid` tool, `defaults`, `vertical_anchor`. Same sheet now takes 6 calls, no external script. |
26
+ | 2026-09-27 | [A4 landscape poster: How a Heat Pump Works](2026-09-27-heat-pump-poster.md) | Done in 31 tool calls; `grid` handled the chart axes; multi-line text renders with a doubled first gap; loop needed waypoint helpers; data points and block arrows computed by hand | ✅ Addressed 2026-09-27 (E17, E18): multi-line text fixed, arrow stub fixed, `plot` + axis titles, connector `from_side`/`to_side`/`via`, label position/side/offset/font/halo, `marker_start`/`marker_end`, `arrow` element, text `width` wrapping, `move_to_layer` position. Hard parts of the poster now 8 calls (was 31). Open: hanging indents / lists in wrapped text. |
27
+ | 2026-09-27 | [A3 portrait infographic: History of Flight 1903–1969](2026-09-27-flight-infographic.md) | Done in 26 tool calls; text wrapping + `wrapped_lines`, icon groups with transforms, `layout`/`align` baselines worked well; timeline positions and card heights computed by hand; bar chart faked with thick `plot` lines; plot labels have a hidden white halo | Partly addressed 2026-09-27 (E19): per-axis gridlines (`lines: false`), series-named `plot` ids, `label_halo`/`label_anchor` + docs; the bar chart now takes 5 calls with no fixes. `repeat` with alternate mirroring done (E21, D-019). rect `fit_to` done (D-020). Open: bar series + category axis in `plot`, bleed/crop marks on export. |
28
+ | 2026-09-28 | [A3 portrait poster: Tamil Alphabet for Beginners](2026-09-28-tamil-alphabet-a3.md) | Done in 13 tool calls, no errors; two `repeat` calls drew all 31 cards; Tamil shaping correct; in-card baselines guessed (descender collisions, one over-wide glyph) and fixed with a 24-item update | Deferred to the round-2 synthesis (D-021): measured stacking in templates, text runs, `max_width` shrink-to-fit, bulk update by template name, overflow warnings |
29
+ | 2026-09-28 | [A4 one-page comic: The Last Cookie](2026-09-28-comic-last-cookie.md) | Done in 18 tool calls; `repeat` with zero step + placeholder poses works as a character component (4 Mias, 3 cats); clipping via `run_actions object-set-clip`; balloon tails and panel geometry computed by hand; **one intermittent shell crash left add_elements half-applied** | ✅ Bug fixed 2026-09-28: all tools atomic + shell retry (E23–E23c, D-022; reproduced once when idle, cause unknown). Deferred to synthesis: balloon/callout with `tail_to`, component anchors, `clip` key, panel splitter, star shape, bulk update |
30
+ | 2026-09-28 | [A3 landscape poster: The Periodic Table (secondary school)](2026-09-28-periodic-table-a3.md) | Done in 17 tool calls, no crash; one `repeat` drew all 118 cells (590 elements); `align`/`connect` worked inside a scaled group; table positions and category colours prepared by an external script; one layout collision found by zooming | Deferred to the round-2 synthesis: grid-cell placement + style maps in `repeat`, overlap warnings (3rd report), place-relative, connector end gap, equal-height cards, compact `repeat` response |
31
+ | 2026-09-28 | [A4 architectural plan: 2 BHK furniture layout (monochrome)](2026-09-28-floor-plan-2bhk-a4.md) | Done in 16 tool calls, no errors; plan drawn in metres inside a 1:75 scaled group; poché walls via union/combine/difference; doors, windows, dimensions and room areas generated by a 150-line external script | ✅ Bug fixed 2026-09-28: `result` id returned, combine documented (E22, F30). Deferred to synthesis: dimension element, paper-space line weights, table element, specs from a file, overlap warnings (4th), section stacking; walls/openings are architecture-specific |
32
+ | 2026-09-28 | [A3 route map from OSM data: Bengaluru → Chennai via Chittoor](2026-09-28-route-map-blr-chennai-a3.md) | Done in 18 tool calls, no tool errors; OSRM route + Overpass layers projected/simplified by script; 51 kB of geometry too costly to pass through tools, so written to an SVG and opened with `document_open`; `repeat` with placeholder styles/glyphs labelled 53 map features; text halos via paint-order | Deferred to synthesis: import / specs-from-file (decisive for data-heavy work), overlap warnings (5th), `clip` key, text halo option, table, scale bar; geo layer is cartography-specific |
33
+ | 2026-09-28 | [A4 swimlane flowchart: From Pull Request to Production](2026-09-28-flowchart-pr-to-production-a4.md) | Done in 18 tool calls, **no external scripts**; one `connect` call routed 18 orthogonal arrows (sides + one `via` loop) with coloured Yes/No labels; connectors re-routed and re-labelled after node moves; legend with two `layout` calls | Deferred to synthesis: shape presets, grid-cell placement, place-relative, label-fit/overlap warnings (6th); small: connectors in a layer, label ids in the `connect` response |
34
+ | 2026-09-28 | [A4 datasheet page: LDO-317 (synthetic), 4 plots](2026-09-28-datasheet-ldo317-a4.md) | Done in ~41 tool calls (double the others: redos from 2 grid bugs); `plot` correct on linear and log axes; `layout` aligned 4 figure blocks by bbox, so plot frames were 0.5–1.4 mm off and fixed by hand; legend built from repeat + fit_to + z_order | ✅ Bugs fixed 2026-09-28: lines classed by index, log decade labels follow `start` (D-023). Deferred to synthesis: figure = one group, layout by anchor, plot legend, log label styles, table (4th), overlap warnings (7th) |
35
+ | 2026-09-28 | [A4 comic, page 2: The Cookie Trap (same cast, new layout + patterns)](2026-09-28-comic-last-cookie-p2.md) | Done in 27 tool calls on the round-2 build, no errors; `split` made panels and frames, `clip` key worked in templates (dots → dress) and on rows, `rows_path` for pose data, patterns via `repeat`; tails and starburst still by hand; 15 false-positive overlap warnings from a striped background | ✅ False overlap warnings fixed 2026-09-28: pairs under an opaque box skipped, one line per text (E29, D-029). Open: callout `tail_to` + anchors (step 4), star shape, repeat id namespacing, layer names in `clip` |
36
+ | 2026-09-28 | [Editing SVGs someone else made: flowsample, tiger.svgz, Inkscape logo, NPS symbols](2026-09-28-edit-existing-svgs.md) | Fresh subagent, tools only: ~100 calls over 3 jobs, all finished; 12 bugs/surprises on foreign files (.svgz, page scale, invisible colours, root paint, unstable ids, leftover defs); flowsample turned out to be flowed text, not a flowchart | ✅ Fixed 2026-09-28 (E30, D-030): normalise on open, .svgz, `inspect find` + computed paint, `use` from libraries, def pruning, messages. Open: flowRoot text editing (F36: Inkscape crashes converting it); re-run the jobs on the fixed build |
37
+ | 2026-09-28 | [Editing SVGs someone else made, re-run on 0.3.0: tiger.svgz, symbol legend, car.svgz](2026-09-28-edit-existing-svgs-rerun.md) | Fresh subagent: 62 calls, all jobs finished; 9 of 11's 12 bugs confirmed fixed (3 not retested); new: gradients can't be recoloured, `use` sizing, extensions ignore `select`, reopen rounding | ✅ Fixed 2026-09-28 (E31, D-032): `use` sizing, extension guard, clean reopen, flowtext search, bytes/pixels. Open: colour summary + gradient-aware recolour, overlap checks against curved artwork, closing a document |
38
+
39
+ **Round-2 synthesis** (reports 4–10, reviewed 2026-09-28, D-024): [2026-09-28-round-2-synthesis.md](2026-09-28-round-2-synthesis.md)
@@ -0,0 +1,44 @@
1
+ # Experiments
2
+
3
+ Small, runnable probes of real Inkscape behaviour. Each one answers a question; its answer is
4
+ recorded in [`docs/development/inkscape-notes.md`](../docs/development/inkscape-notes.md) and, if the code relies on
5
+ it, guarded by a test in `tests/`.
6
+
7
+ Run with `uv run python experiments/<file>.py`. Outputs go to `experiments/out/` (git-ignored).
8
+
9
+ | # | Question | Findings |
10
+ |---|---|---|
11
+ | e01 | How do export, query and action chains behave? Error reporting? | F1, S1, S2, timings |
12
+ | e02 | Does `--shell` work as a persistent process? Protocol? Latency? | F2, F3 |
13
+ | e03 | Does `style=""` survive boolean ops? Is inkex available? | S1, inkex note |
14
+ | e04 | Query units in mm docs, layer survival, missing files | F4, F8 |
15
+ | e05, e05b, e05c | Are export options sticky? How to reset? | F5, F6, F10 |
16
+ | e06 | Real usage over stdio: build a diagram as an agent would | S3, perf, Phase 2 backlog |
17
+ | e07 | Does `object-align` work headless? translate units? font metrics? dominant-baseline? | F12, F13, S4, S6 |
18
+ | e07b | Do generic font families differ? Unknown fonts? translate dy direction | S4, S5, F13 |
19
+ | e08 | Real usage: rebuild e06 with `align` — how much agent work disappears? | F14, D-007 |
20
+ | e09 | Markers in export? context-stroke? native connectors? custom attrs survive? | F15, S7–S9 |
21
+ | e09b | Native connectors: routing on load, circles, groups, text, orthogonal | F15–F17 |
22
+ | e10 | Real usage: flowchart from relationships only (layout/align/connect) | D-009 |
23
+ | e11 | `page-fit-to-selection` headless? backgrounds? non-zero viewBox origin? | F18, F21 |
24
+ | e12 | Real usage: fix an off-page flowchart with one `page_fit`; coordinate noise | F14, D-010 |
25
+ | e13 | Z-order actions: raise vs stack-up, top/bottom in layers, multi-selection | F22, D-011 |
26
+ | e14 | Scale: 325 elements in one call, inspect size, A4 300 dpi export | perf table, inspect summaries |
27
+ | e15 | Field report bugs: several export ids? export-area units? | F23, F24, D-012 |
28
+ | e16 | Redo field test 1 with `grid` + region zoom (14 → 6 calls) | D-013 |
29
+ | e16b | Shell batching: per-line vs joined line vs one selection | F25, D-014 |
30
+ | e17 | Field report 2: multi-line text layout, arrow stub, connection points, inline-size | F26–F28, S10 |
31
+ | e18 | Redo field test 2's hard parts with sides/arrow/width/plot (31 → 8 calls) | D-015–D-017 |
32
+ | e19 | Field test 3's bar chart with x-only gridlines, series ids, halo-free inside labels (5 calls, no fixes) | D-018 |
33
+ | e21 | `repeat` mechanics: reflected shapes/markers in translated groups, wrapping, block moves, connectors | F29, D-019 |
34
+ | e22 | Which id survives each path operation (order, layers)? | F30 |
35
+ | e23, e23b, e23c | Can the field-report-5 shell crash be reproduced (stress loop; idle shell; other Inkscape instances)? | F31, D-022 |
36
+ | e24 | Clip mechanics (clipped bbox, transformed groups, moves, round trips) and text halo bbox growth | F32, S11, D-025 |
37
+ | e25 | Image mechanics: href forms, preserveAspectRatio, sizes, JPEG export | F33, F34, D-026 |
38
+ | e26 | Real usage: 51 kB geometry file + CSV labels + photo inset through the tools (7 calls) | D-026 |
39
+ | e27 | Real usage for step 2: Tamil card placement, map label collisions, flowchart false positives, plot frames by anchor | D-027 |
40
+ | e28 | Real usage for step 3: comic panel grid, periodic-table cells from CSV, a table from split + repeat | D-028 |
41
+ | e29 | Overlap warnings on nine finished pages: which are hidden under an opaque box (comic page 2 report) | D-029 |
42
+ | e30 | Foreign files: .svgz, page geometry Inkscape uses for % / mismatched viewBoxes, rendering before/after normalising, ids on open vs import | F35, S12, D-030 |
43
+ | e31 | Do extension actions honour the selection in shell mode? | F37, D-032 |
44
+ | e20 | Reference benchmark: calls/tokens for flowchart, graph paper, bar chart, icon, timeline; tool-list size | `08-benchmarks.md` |
@@ -0,0 +1,56 @@
1
+ [project]
2
+ name = "inksmcp"
3
+ dynamic = ["version"]
4
+ description = "MCP server that lets AI assistants create, edit and export vector graphics with Inkscape"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{ name = "Bhanu Prakash Bheemaneni", email = "sbvscp@gmail.com" }]
9
+ requires-python = ">=3.12"
10
+ keywords = ["mcp", "model-context-protocol", "inkscape", "svg", "vector-graphics", "ai", "claude"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Environment :: Console",
14
+ "Intended Audience :: Developers",
15
+ "Intended Audience :: End Users/Desktop",
16
+ "Operating System :: OS Independent",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Topic :: Multimedia :: Graphics :: Editors :: Vector-Based",
21
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
22
+ ]
23
+ dependencies = [
24
+ "lxml>=6.1.3",
25
+ "mcp>=2.2.0",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/bhanutpt/inksmcp"
30
+ Documentation = "https://github.com/bhanutpt/inksmcp/tree/main/docs"
31
+ Issues = "https://github.com/bhanutpt/inksmcp/issues"
32
+ Changelog = "https://github.com/bhanutpt/inksmcp/blob/main/CHANGELOG.md"
33
+
34
+ [project.scripts]
35
+ inksmcp = "inksmcp.server:main"
36
+
37
+ [build-system]
38
+ requires = ["hatchling>=1.27"]
39
+ build-backend = "hatchling.build"
40
+
41
+ [tool.hatch.version]
42
+ path = "src/inksmcp/__init__.py"
43
+
44
+ [tool.hatch.build.targets.wheel]
45
+ packages = ["src/inksmcp"]
46
+
47
+ [tool.hatch.build.targets.sdist]
48
+ include = ["src/inksmcp", "tests", "README.md", "LICENSE", "CHANGELOG.md"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+
53
+ [dependency-groups]
54
+ dev = [
55
+ "pytest>=9.1.1",
56
+ ]
@@ -0,0 +1,3 @@
1
+ """inksmcp — MCP server that lets AI assistants drive Inkscape."""
2
+
3
+ __version__ = "0.3.0"