mcpinkscape 0.0.2__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.
- mcpinkscape-0.0.2/LICENSE.md +28 -0
- mcpinkscape-0.0.2/MANIFEST.in +8 -0
- mcpinkscape-0.0.2/PKG-INFO +288 -0
- mcpinkscape-0.0.2/README.md +258 -0
- mcpinkscape-0.0.2/USER_MANUAL.md +146 -0
- mcpinkscape-0.0.2/examples/mcpinkscape-remote.conf +44 -0
- mcpinkscape-0.0.2/examples/mcpinkscape.conf +21 -0
- mcpinkscape-0.0.2/freebsd/PORT_OVERLAY.md +50 -0
- mcpinkscape-0.0.2/freebsd/rc.d/mcpinkscape +76 -0
- mcpinkscape-0.0.2/freebsd/usr/ports/graphics/inkscape-mcpinkscape/Makefile +23 -0
- mcpinkscape-0.0.2/freebsd/usr/ports/graphics/inkscape-mcpinkscape/README.md +33 -0
- mcpinkscape-0.0.2/freebsd/usr/ports/graphics/inkscape-mcpinkscape/files/inkscape-mcpinkscape.mk +24 -0
- mcpinkscape-0.0.2/freebsd/usr/ports/graphics/inkscape-mcpinkscape/pkg-descr +6 -0
- mcpinkscape-0.0.2/freebsd/usr/ports/graphics/inkscape-mcpinkscape/pkg-plist.bridge +4 -0
- mcpinkscape-0.0.2/native/CMakeLists.txt +32 -0
- mcpinkscape-0.0.2/native/cmake-overlay.cmake +17 -0
- mcpinkscape-0.0.2/native/mcpinkscape-bridge-start.inx +10 -0
- mcpinkscape-0.0.2/native/mcpinkscape-bridge-status.inx +10 -0
- mcpinkscape-0.0.2/native/mcpinkscape-bridge-stop.inx +10 -0
- mcpinkscape-0.0.2/native/src/bridge_json.h +274 -0
- mcpinkscape-0.0.2/native/src/mcpinkscape_bridge.cpp +1770 -0
- mcpinkscape-0.0.2/native/tests/test_bridge_json.cpp +18 -0
- mcpinkscape-0.0.2/pyproject.toml +62 -0
- mcpinkscape-0.0.2/setup.cfg +4 -0
- mcpinkscape-0.0.2/skill/mcpinkscape/SKILL.md +76 -0
- mcpinkscape-0.0.2/skill/mcpinkscape/references/design-for-inkscape.md +218 -0
- mcpinkscape-0.0.2/skill/mcpinkscape/references/design-review.md +105 -0
- mcpinkscape-0.0.2/skill/mcpinkscape/references/rc1-tools.md +47 -0
- mcpinkscape-0.0.2/src/mcpinkscape/__init__.py +3 -0
- mcpinkscape-0.0.2/src/mcpinkscape/__main__.py +7 -0
- mcpinkscape-0.0.2/src/mcpinkscape/app/__init__.py +1 -0
- mcpinkscape-0.0.2/src/mcpinkscape/app/server.py +514 -0
- mcpinkscape-0.0.2/src/mcpinkscape/config/__init__.py +1 -0
- mcpinkscape-0.0.2/src/mcpinkscape/config/api_keys.py +65 -0
- mcpinkscape-0.0.2/src/mcpinkscape/config/config_manager.py +76 -0
- mcpinkscape-0.0.2/src/mcpinkscape/config/schema.py +68 -0
- mcpinkscape-0.0.2/src/mcpinkscape/errors.py +39 -0
- mcpinkscape-0.0.2/src/mcpinkscape/native_bridge.py +155 -0
- mcpinkscape-0.0.2/src/mcpinkscape/renderer.py +229 -0
- mcpinkscape-0.0.2/src/mcpinkscape/service.py +779 -0
- mcpinkscape-0.0.2/src/mcpinkscape/storage.py +102 -0
- mcpinkscape-0.0.2/src/mcpinkscape/svg_document.py +913 -0
- mcpinkscape-0.0.2/src/mcpinkscape.egg-info/PKG-INFO +288 -0
- mcpinkscape-0.0.2/src/mcpinkscape.egg-info/SOURCES.txt +56 -0
- mcpinkscape-0.0.2/src/mcpinkscape.egg-info/dependency_links.txt +1 -0
- mcpinkscape-0.0.2/src/mcpinkscape.egg-info/entry_points.txt +2 -0
- mcpinkscape-0.0.2/src/mcpinkscape.egg-info/requires.txt +11 -0
- mcpinkscape-0.0.2/src/mcpinkscape.egg-info/top_level.txt +1 -0
- mcpinkscape-0.0.2/tests/test_freebsd_rcd.py +16 -0
- mcpinkscape-0.0.2/tests/test_live_active_window_integration.py +64 -0
- mcpinkscape-0.0.2/tests/test_live_native_bridge_integration.py +166 -0
- mcpinkscape-0.0.2/tests/test_native_bridge.py +210 -0
- mcpinkscape-0.0.2/tests/test_native_package.py +82 -0
- mcpinkscape-0.0.2/tests/test_rc1_offline_integration.py +107 -0
- mcpinkscape-0.0.2/tests/test_renderer.py +51 -0
- mcpinkscape-0.0.2/tests/test_server.py +126 -0
- mcpinkscape-0.0.2/tests/test_service.py +99 -0
- mcpinkscape-0.0.2/tests/test_svg_document.py +156 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Copyright 2026, Thomas Spielauer
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
4
|
+
are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
7
|
+
list of conditions and the following disclaimer.
|
|
8
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
9
|
+
this list of conditions and the following disclaimer in the documentation
|
|
10
|
+
and/or other materials provided with the distribution.
|
|
11
|
+
* Products that incorporate or use this software must include the acknowledgment
|
|
12
|
+
“This product includes software developed by Thomas Spielauer.” in their
|
|
13
|
+
documentation, credits, “About” page, or other reasonably accessible
|
|
14
|
+
attribution notice.
|
|
15
|
+
* Neither the name of the copyright holder nor the names of its contributors may
|
|
16
|
+
be used to endorse or promote products derived from this software without
|
|
17
|
+
specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
20
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
21
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
23
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
24
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
25
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
26
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
28
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcpinkscape
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: MCP server for offline and live Inkscape documents
|
|
5
|
+
Author-email: Thomas Spielauer <pypipackages01@tspi.at>
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
Keywords: inkscape,mcp,model-context-protocol,svg,vector-graphics
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Classifier: Operating System :: POSIX :: BSD :: FreeBSD
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Multimedia :: Graphics :: Editors :: Vector-Based
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE.md
|
|
20
|
+
Requires-Dist: fastmcp<5.0.0,>=4.0.0
|
|
21
|
+
Requires-Dist: mcp<3.0.0,>=2.0.0
|
|
22
|
+
Requires-Dist: pydantic>=2.5.0
|
|
23
|
+
Requires-Dist: argon2-cffi>=23.1.0
|
|
24
|
+
Provides-Extra: remote
|
|
25
|
+
Requires-Dist: fastapi<1,>=0.141.1; extra == "remote"
|
|
26
|
+
Requires-Dist: uvicorn>=0.24.0; extra == "remote"
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# Inkscape MCP Server `mcpinkscape`
|
|
32
|
+
|
|
33
|
+
`mcpinkscape` is an MCP server for creating, inspecting, editing, rendering,
|
|
34
|
+
and exporting SVG/Inkscape documents. It provides a deterministic offline SVG
|
|
35
|
+
backend and a carefully limited bridge to a locally running Inkscape instance.
|
|
36
|
+
MCP clients use typed drawing tools; the server never exposes arbitrary shell
|
|
37
|
+
commands, Python execution, raw SVG replacement, or arbitrary Inkscape action
|
|
38
|
+
strings.
|
|
39
|
+
|
|
40
|
+
__WORK IN PROGRESS — RC1 implementation__
|
|
41
|
+
|
|
42
|
+
Offline SVG drawing, rendering, export, and the version-probed active-window
|
|
43
|
+
CLI compatibility bridge are implemented and tested on FreeBSD with Inkscape
|
|
44
|
+
1.4.3. The separately buildable native C++ extension provides secure
|
|
45
|
+
GUI-thread live editing, snapshots, revision-conflict protection, and polling;
|
|
46
|
+
the RC1 native workflow is live-tested against an ABI-matched FreeBSD Inkscape
|
|
47
|
+
1.4.4 fixture. Native capabilities remain dynamically advertised because the
|
|
48
|
+
extension is optional and its ABI must exactly match Inkscape.
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- offline SVG document lifecycle, layers, object inspection, selection, and
|
|
53
|
+
stable object IDs
|
|
54
|
+
- typed rectangles, ellipses, circles, lines, polylines, polygons, paths, and
|
|
55
|
+
text, including absolute SVG units such as `mm`, `cm`, `in`, `pt`, and `px`
|
|
56
|
+
- typed fill, stroke/border appearance, opacity, text appearance, page
|
|
57
|
+
background, linear/radial gradients, confined embedded PNG/JPEG placement,
|
|
58
|
+
movement, rotation, scale, grouping, stacking, duplication, and deletion
|
|
59
|
+
- Inkscape CLI rendering to registered PNG snapshots plus SVG, plain-SVG, PNG,
|
|
60
|
+
and PDF export
|
|
61
|
+
- active-window selection, style, transform, and document rendering through
|
|
62
|
+
only the actions advertised by the installed Inkscape executable
|
|
63
|
+
- stdio MCP transport and authenticated Streamable HTTP transport with
|
|
64
|
+
mcpFreeCAD-style API-key policy controls
|
|
65
|
+
- optional loaded C++ bridge extension over private UDS on FreeBSD/Linux, or
|
|
66
|
+
literal `127.0.0.1` TCP only on Windows
|
|
67
|
+
- repository-owned [coding-agent skill](skill/mcpinkscape/SKILL.md) and RC1
|
|
68
|
+
tool catalog
|
|
69
|
+
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
Install from this checkout in an existing Python environment containing the
|
|
73
|
+
declared dependencies:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
pip install -e .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
For remote HTTP mode, install the existing optional dependencies as well:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
pip install -e ".[remote]"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Neither command installs an Inkscape extension, creates a configuration file,
|
|
86
|
+
or changes user or system configuration.
|
|
87
|
+
|
|
88
|
+
## Quick Start
|
|
89
|
+
|
|
90
|
+
1. Copy [examples/mcpinkscape.conf](examples/mcpinkscape.conf) to a location
|
|
91
|
+
you control and set its `stdio.document_root`.
|
|
92
|
+
2. Start the stdio MCP server:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
mcpinkscape --config ./mcpinkscape.conf
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
3. From an MCP client, call `server_status`, then use `create_document`, the
|
|
99
|
+
typed `create_*` tools, `set_fill`/`set_stroke`, and `render_snapshot`.
|
|
100
|
+
|
|
101
|
+
The server starts successfully without a GUI or native extension. `server_status`
|
|
102
|
+
reports which offline, active-window, and native capabilities are actually
|
|
103
|
+
available.
|
|
104
|
+
|
|
105
|
+
For complete operator guidance and examples, see [USER_MANUAL.md](USER_MANUAL.md).
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
The configuration layout mirrors mcpFreeCAD. The server does not create or load
|
|
110
|
+
the example automatically. Its default configuration path is
|
|
111
|
+
`~/.config/mcpinkscape.conf`.
|
|
112
|
+
|
|
113
|
+
The repository ships two safe starting points:
|
|
114
|
+
|
|
115
|
+
- Local stdio mode: [examples/mcpinkscape.conf](examples/mcpinkscape.conf)
|
|
116
|
+
- Local authenticated HTTP mode:
|
|
117
|
+
[examples/mcpinkscape-remote.conf](examples/mcpinkscape-remote.conf)
|
|
118
|
+
|
|
119
|
+
Copy an example before changing it. The remote example deliberately binds only
|
|
120
|
+
to `127.0.0.1`, has no usable API key yet, and must be initialized explicitly:
|
|
121
|
+
|
|
122
|
+
```sh
|
|
123
|
+
mcpinkscape --config ./mcpinkscape-remote.conf --genkey drawing-agent
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The command prints the plaintext key once and stores only its derived verifier
|
|
127
|
+
in the configuration file. Preserve that key in your chosen secret store; do
|
|
128
|
+
not put it in a repository.
|
|
129
|
+
|
|
130
|
+
The local stdio example has this bridge and document-access structure:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"mode": "stdio",
|
|
135
|
+
"bridge": {
|
|
136
|
+
"mode": "auto",
|
|
137
|
+
"uds": "~/.local/state/mcpinkscape/bridge.sock",
|
|
138
|
+
"tcp_host": "127.0.0.1",
|
|
139
|
+
"tcp_port": 61779,
|
|
140
|
+
"timeout_seconds": 30.0,
|
|
141
|
+
"required": false
|
|
142
|
+
},
|
|
143
|
+
"stdio": {
|
|
144
|
+
"document_root": "./mcpinkscape-library",
|
|
145
|
+
"allow_document_write": true,
|
|
146
|
+
"allow_snapshots": true,
|
|
147
|
+
"allow_live_control": true
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`bridge.mode` is one of `auto`, `native_uds`, `active_window`, or `offline`.
|
|
153
|
+
On FreeBSD/Linux a native extension uses the private UDS path. On Windows the
|
|
154
|
+
native endpoint is accepted only at literal `127.0.0.1:tcp_port`; its default
|
|
155
|
+
port is `61779`. No bridge token is used.
|
|
156
|
+
|
|
157
|
+
## Connecting with Agents
|
|
158
|
+
|
|
159
|
+
### Codex example (stdio)
|
|
160
|
+
|
|
161
|
+
Add this to the Codex configuration, adjusting the configuration path to the
|
|
162
|
+
copy you created:
|
|
163
|
+
|
|
164
|
+
```toml
|
|
165
|
+
[mcp_servers.mcpinkscape]
|
|
166
|
+
command = "mcpinkscape"
|
|
167
|
+
args = [
|
|
168
|
+
"--config", "/path/to/mcpinkscape.conf"
|
|
169
|
+
]
|
|
170
|
+
startup_timeout_sec = 300
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Codex example (remote HTTP)
|
|
174
|
+
|
|
175
|
+
```toml
|
|
176
|
+
[mcp_servers.mcpinkscape]
|
|
177
|
+
url = "http://127.0.0.1:61780/mcp/mcp?api_key=<MCPINKSCAPE_API_KEY>"
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### PQC example (remote HTTP)
|
|
181
|
+
|
|
182
|
+
Add the following entry beneath `mcp.servers` in the PQC JSON configuration:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
"mcpinkscape": {
|
|
186
|
+
"enabled": true,
|
|
187
|
+
"transport": "http",
|
|
188
|
+
"url": "http://127.0.0.1:61780/mcp/mcp",
|
|
189
|
+
"auth": {
|
|
190
|
+
"mode": "query_param",
|
|
191
|
+
"token": "<MCPINKSCAPE_API_KEY>",
|
|
192
|
+
"param_name": "api_key"
|
|
193
|
+
},
|
|
194
|
+
"policy": {
|
|
195
|
+
"enabled": true,
|
|
196
|
+
"visible_by_default": true,
|
|
197
|
+
"approval_mode": "never",
|
|
198
|
+
"network_classification": "local"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### JSON MCP transport example
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"name": "mcpinkscape",
|
|
208
|
+
"type": "mcp",
|
|
209
|
+
"transport": {
|
|
210
|
+
"type": "http",
|
|
211
|
+
"url": "http://127.0.0.1:61780/mcp/mcp?api_key=<MCPINKSCAPE_API_KEY>"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### FreeBSD service
|
|
217
|
+
|
|
218
|
+
The server is not installed or enabled automatically. For a deliberate
|
|
219
|
+
`remotehttp` deployment, install the repository's
|
|
220
|
+
`freebsd/rc.d/mcpinkscape` as `/usr/local/etc/rc.d/mcpinkscape`, place a
|
|
221
|
+
reviewed configuration at `/usr/local/etc/mcpinkscape.conf`, then set:
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
mcpinkscape_enable="YES"
|
|
225
|
+
mcpinkscape_config="/usr/local/etc/mcpinkscape.conf"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
The script defaults to `remotehttp`, requires both command and configuration,
|
|
229
|
+
and supports `mcpinkscape_daemon_user`, `mcpinkscape_transport`, and
|
|
230
|
+
`mcpinkscape_flags` overrides. It does not install the native Inkscape bridge;
|
|
231
|
+
that remains a separately built, per-user extension.
|
|
232
|
+
|
|
233
|
+
Remote mode adds `remote_server` and `api_keys` entries. Generate or rotate a
|
|
234
|
+
remote API key explicitly with:
|
|
235
|
+
|
|
236
|
+
```sh
|
|
237
|
+
mcpinkscape --config ./mcpinkscape.conf --genkey drawing-agent
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
The plaintext key is printed once; it is not retained in normal status output.
|
|
241
|
+
|
|
242
|
+
## Running
|
|
243
|
+
|
|
244
|
+
Run stdio MCP mode:
|
|
245
|
+
|
|
246
|
+
```sh
|
|
247
|
+
mcpinkscape --config ./mcpinkscape.conf
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Run authenticated Streamable HTTP mode:
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
mcpinkscape --config ./mcpinkscape.conf --transport remotehttp
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The remote wrapper accepts `Authorization: Bearer <key>`, `X-API-Key: <key>`,
|
|
257
|
+
`?mcp=<key>`, or `?api_key=<key>`. Its `/status` endpoint is intentionally
|
|
258
|
+
public for local health checks; `/mcp` requires a configured API key.
|
|
259
|
+
|
|
260
|
+
## Native Extension
|
|
261
|
+
|
|
262
|
+
The `native/` directory is an Inkscape-source-overlay target, not an independent
|
|
263
|
+
binary build. It needs the exact matching Inkscape source, build headers,
|
|
264
|
+
compiler, and `inkscape_base` ABI. It supplies Start, Stop, and Status entries
|
|
265
|
+
under Inkscape’s Extensions menu. Installation is intentionally a separate
|
|
266
|
+
explicit action and is not performed by the Python package.
|
|
267
|
+
|
|
268
|
+
The extension implements bridge lifecycle, structured JSON framing, same-user
|
|
269
|
+
transport checks, typed live drawing/style/transform/structure operations,
|
|
270
|
+
named undo transactions, revision-conflict protection, page/drawing PNG
|
|
271
|
+
snapshot staging, and pollable document/selection changes—including edits made
|
|
272
|
+
directly by a human in Inkscape. Tools are advertised only when a connected
|
|
273
|
+
bridge implements the matching protocol method.
|
|
274
|
+
|
|
275
|
+
## Repository Layout
|
|
276
|
+
|
|
277
|
+
- `src/mcpinkscape/`: Python MCP server, offline SVG backend, transports, and
|
|
278
|
+
native bridge client
|
|
279
|
+
- `native/`: C++ loaded-extension source, `.inx` descriptors, and overlay CMake
|
|
280
|
+
target
|
|
281
|
+
- `examples/`: configuration example
|
|
282
|
+
- `skill/`: OpenAI-compatible coding-agent skill
|
|
283
|
+
- `tests/`: Python protocol, service, transport, and real-Inkscape tests
|
|
284
|
+
- `USER_MANUAL.md`: operator and MCP-client usage guide
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
This project is distributed under the BSD-style terms in [LICENSE.md](LICENSE.md).
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Inkscape MCP Server `mcpinkscape`
|
|
2
|
+
|
|
3
|
+
`mcpinkscape` is an MCP server for creating, inspecting, editing, rendering,
|
|
4
|
+
and exporting SVG/Inkscape documents. It provides a deterministic offline SVG
|
|
5
|
+
backend and a carefully limited bridge to a locally running Inkscape instance.
|
|
6
|
+
MCP clients use typed drawing tools; the server never exposes arbitrary shell
|
|
7
|
+
commands, Python execution, raw SVG replacement, or arbitrary Inkscape action
|
|
8
|
+
strings.
|
|
9
|
+
|
|
10
|
+
__WORK IN PROGRESS — RC1 implementation__
|
|
11
|
+
|
|
12
|
+
Offline SVG drawing, rendering, export, and the version-probed active-window
|
|
13
|
+
CLI compatibility bridge are implemented and tested on FreeBSD with Inkscape
|
|
14
|
+
1.4.3. The separately buildable native C++ extension provides secure
|
|
15
|
+
GUI-thread live editing, snapshots, revision-conflict protection, and polling;
|
|
16
|
+
the RC1 native workflow is live-tested against an ABI-matched FreeBSD Inkscape
|
|
17
|
+
1.4.4 fixture. Native capabilities remain dynamically advertised because the
|
|
18
|
+
extension is optional and its ABI must exactly match Inkscape.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- offline SVG document lifecycle, layers, object inspection, selection, and
|
|
23
|
+
stable object IDs
|
|
24
|
+
- typed rectangles, ellipses, circles, lines, polylines, polygons, paths, and
|
|
25
|
+
text, including absolute SVG units such as `mm`, `cm`, `in`, `pt`, and `px`
|
|
26
|
+
- typed fill, stroke/border appearance, opacity, text appearance, page
|
|
27
|
+
background, linear/radial gradients, confined embedded PNG/JPEG placement,
|
|
28
|
+
movement, rotation, scale, grouping, stacking, duplication, and deletion
|
|
29
|
+
- Inkscape CLI rendering to registered PNG snapshots plus SVG, plain-SVG, PNG,
|
|
30
|
+
and PDF export
|
|
31
|
+
- active-window selection, style, transform, and document rendering through
|
|
32
|
+
only the actions advertised by the installed Inkscape executable
|
|
33
|
+
- stdio MCP transport and authenticated Streamable HTTP transport with
|
|
34
|
+
mcpFreeCAD-style API-key policy controls
|
|
35
|
+
- optional loaded C++ bridge extension over private UDS on FreeBSD/Linux, or
|
|
36
|
+
literal `127.0.0.1` TCP only on Windows
|
|
37
|
+
- repository-owned [coding-agent skill](skill/mcpinkscape/SKILL.md) and RC1
|
|
38
|
+
tool catalog
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Install from this checkout in an existing Python environment containing the
|
|
43
|
+
declared dependencies:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For remote HTTP mode, install the existing optional dependencies as well:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
pip install -e ".[remote]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Neither command installs an Inkscape extension, creates a configuration file,
|
|
56
|
+
or changes user or system configuration.
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
1. Copy [examples/mcpinkscape.conf](examples/mcpinkscape.conf) to a location
|
|
61
|
+
you control and set its `stdio.document_root`.
|
|
62
|
+
2. Start the stdio MCP server:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
mcpinkscape --config ./mcpinkscape.conf
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. From an MCP client, call `server_status`, then use `create_document`, the
|
|
69
|
+
typed `create_*` tools, `set_fill`/`set_stroke`, and `render_snapshot`.
|
|
70
|
+
|
|
71
|
+
The server starts successfully without a GUI or native extension. `server_status`
|
|
72
|
+
reports which offline, active-window, and native capabilities are actually
|
|
73
|
+
available.
|
|
74
|
+
|
|
75
|
+
For complete operator guidance and examples, see [USER_MANUAL.md](USER_MANUAL.md).
|
|
76
|
+
|
|
77
|
+
## Configuration
|
|
78
|
+
|
|
79
|
+
The configuration layout mirrors mcpFreeCAD. The server does not create or load
|
|
80
|
+
the example automatically. Its default configuration path is
|
|
81
|
+
`~/.config/mcpinkscape.conf`.
|
|
82
|
+
|
|
83
|
+
The repository ships two safe starting points:
|
|
84
|
+
|
|
85
|
+
- Local stdio mode: [examples/mcpinkscape.conf](examples/mcpinkscape.conf)
|
|
86
|
+
- Local authenticated HTTP mode:
|
|
87
|
+
[examples/mcpinkscape-remote.conf](examples/mcpinkscape-remote.conf)
|
|
88
|
+
|
|
89
|
+
Copy an example before changing it. The remote example deliberately binds only
|
|
90
|
+
to `127.0.0.1`, has no usable API key yet, and must be initialized explicitly:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
mcpinkscape --config ./mcpinkscape-remote.conf --genkey drawing-agent
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The command prints the plaintext key once and stores only its derived verifier
|
|
97
|
+
in the configuration file. Preserve that key in your chosen secret store; do
|
|
98
|
+
not put it in a repository.
|
|
99
|
+
|
|
100
|
+
The local stdio example has this bridge and document-access structure:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"mode": "stdio",
|
|
105
|
+
"bridge": {
|
|
106
|
+
"mode": "auto",
|
|
107
|
+
"uds": "~/.local/state/mcpinkscape/bridge.sock",
|
|
108
|
+
"tcp_host": "127.0.0.1",
|
|
109
|
+
"tcp_port": 61779,
|
|
110
|
+
"timeout_seconds": 30.0,
|
|
111
|
+
"required": false
|
|
112
|
+
},
|
|
113
|
+
"stdio": {
|
|
114
|
+
"document_root": "./mcpinkscape-library",
|
|
115
|
+
"allow_document_write": true,
|
|
116
|
+
"allow_snapshots": true,
|
|
117
|
+
"allow_live_control": true
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`bridge.mode` is one of `auto`, `native_uds`, `active_window`, or `offline`.
|
|
123
|
+
On FreeBSD/Linux a native extension uses the private UDS path. On Windows the
|
|
124
|
+
native endpoint is accepted only at literal `127.0.0.1:tcp_port`; its default
|
|
125
|
+
port is `61779`. No bridge token is used.
|
|
126
|
+
|
|
127
|
+
## Connecting with Agents
|
|
128
|
+
|
|
129
|
+
### Codex example (stdio)
|
|
130
|
+
|
|
131
|
+
Add this to the Codex configuration, adjusting the configuration path to the
|
|
132
|
+
copy you created:
|
|
133
|
+
|
|
134
|
+
```toml
|
|
135
|
+
[mcp_servers.mcpinkscape]
|
|
136
|
+
command = "mcpinkscape"
|
|
137
|
+
args = [
|
|
138
|
+
"--config", "/path/to/mcpinkscape.conf"
|
|
139
|
+
]
|
|
140
|
+
startup_timeout_sec = 300
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Codex example (remote HTTP)
|
|
144
|
+
|
|
145
|
+
```toml
|
|
146
|
+
[mcp_servers.mcpinkscape]
|
|
147
|
+
url = "http://127.0.0.1:61780/mcp/mcp?api_key=<MCPINKSCAPE_API_KEY>"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### PQC example (remote HTTP)
|
|
151
|
+
|
|
152
|
+
Add the following entry beneath `mcp.servers` in the PQC JSON configuration:
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
"mcpinkscape": {
|
|
156
|
+
"enabled": true,
|
|
157
|
+
"transport": "http",
|
|
158
|
+
"url": "http://127.0.0.1:61780/mcp/mcp",
|
|
159
|
+
"auth": {
|
|
160
|
+
"mode": "query_param",
|
|
161
|
+
"token": "<MCPINKSCAPE_API_KEY>",
|
|
162
|
+
"param_name": "api_key"
|
|
163
|
+
},
|
|
164
|
+
"policy": {
|
|
165
|
+
"enabled": true,
|
|
166
|
+
"visible_by_default": true,
|
|
167
|
+
"approval_mode": "never",
|
|
168
|
+
"network_classification": "local"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### JSON MCP transport example
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"name": "mcpinkscape",
|
|
178
|
+
"type": "mcp",
|
|
179
|
+
"transport": {
|
|
180
|
+
"type": "http",
|
|
181
|
+
"url": "http://127.0.0.1:61780/mcp/mcp?api_key=<MCPINKSCAPE_API_KEY>"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### FreeBSD service
|
|
187
|
+
|
|
188
|
+
The server is not installed or enabled automatically. For a deliberate
|
|
189
|
+
`remotehttp` deployment, install the repository's
|
|
190
|
+
`freebsd/rc.d/mcpinkscape` as `/usr/local/etc/rc.d/mcpinkscape`, place a
|
|
191
|
+
reviewed configuration at `/usr/local/etc/mcpinkscape.conf`, then set:
|
|
192
|
+
|
|
193
|
+
```sh
|
|
194
|
+
mcpinkscape_enable="YES"
|
|
195
|
+
mcpinkscape_config="/usr/local/etc/mcpinkscape.conf"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The script defaults to `remotehttp`, requires both command and configuration,
|
|
199
|
+
and supports `mcpinkscape_daemon_user`, `mcpinkscape_transport`, and
|
|
200
|
+
`mcpinkscape_flags` overrides. It does not install the native Inkscape bridge;
|
|
201
|
+
that remains a separately built, per-user extension.
|
|
202
|
+
|
|
203
|
+
Remote mode adds `remote_server` and `api_keys` entries. Generate or rotate a
|
|
204
|
+
remote API key explicitly with:
|
|
205
|
+
|
|
206
|
+
```sh
|
|
207
|
+
mcpinkscape --config ./mcpinkscape.conf --genkey drawing-agent
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The plaintext key is printed once; it is not retained in normal status output.
|
|
211
|
+
|
|
212
|
+
## Running
|
|
213
|
+
|
|
214
|
+
Run stdio MCP mode:
|
|
215
|
+
|
|
216
|
+
```sh
|
|
217
|
+
mcpinkscape --config ./mcpinkscape.conf
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Run authenticated Streamable HTTP mode:
|
|
221
|
+
|
|
222
|
+
```sh
|
|
223
|
+
mcpinkscape --config ./mcpinkscape.conf --transport remotehttp
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
The remote wrapper accepts `Authorization: Bearer <key>`, `X-API-Key: <key>`,
|
|
227
|
+
`?mcp=<key>`, or `?api_key=<key>`. Its `/status` endpoint is intentionally
|
|
228
|
+
public for local health checks; `/mcp` requires a configured API key.
|
|
229
|
+
|
|
230
|
+
## Native Extension
|
|
231
|
+
|
|
232
|
+
The `native/` directory is an Inkscape-source-overlay target, not an independent
|
|
233
|
+
binary build. It needs the exact matching Inkscape source, build headers,
|
|
234
|
+
compiler, and `inkscape_base` ABI. It supplies Start, Stop, and Status entries
|
|
235
|
+
under Inkscape’s Extensions menu. Installation is intentionally a separate
|
|
236
|
+
explicit action and is not performed by the Python package.
|
|
237
|
+
|
|
238
|
+
The extension implements bridge lifecycle, structured JSON framing, same-user
|
|
239
|
+
transport checks, typed live drawing/style/transform/structure operations,
|
|
240
|
+
named undo transactions, revision-conflict protection, page/drawing PNG
|
|
241
|
+
snapshot staging, and pollable document/selection changes—including edits made
|
|
242
|
+
directly by a human in Inkscape. Tools are advertised only when a connected
|
|
243
|
+
bridge implements the matching protocol method.
|
|
244
|
+
|
|
245
|
+
## Repository Layout
|
|
246
|
+
|
|
247
|
+
- `src/mcpinkscape/`: Python MCP server, offline SVG backend, transports, and
|
|
248
|
+
native bridge client
|
|
249
|
+
- `native/`: C++ loaded-extension source, `.inx` descriptors, and overlay CMake
|
|
250
|
+
target
|
|
251
|
+
- `examples/`: configuration example
|
|
252
|
+
- `skill/`: OpenAI-compatible coding-agent skill
|
|
253
|
+
- `tests/`: Python protocol, service, transport, and real-Inkscape tests
|
|
254
|
+
- `USER_MANUAL.md`: operator and MCP-client usage guide
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
This project is distributed under the BSD-style terms in [LICENSE.md](LICENSE.md).
|