Skip to content

About

MCP Server for Ink/Stitch

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Ink/Stitch MCP Bridge

An MCP server that gives AI assistants full headless access to Ink/Stitch machine-embroidery tooling — no Inkscape installation required.

SVG designs go in; stitch-ready machine files (DST, PES, JEF, EXP, VP3, and ~17 more), PNG previews, validation reports, and digitized lettering come out.

"Hello" digitized in the Amitaclo satin font by this bridge — 1,882 stitches, 69×28mm

The image above is the bridge's own output: generate_lettering("Hello", "Amitaclo") → machine-ready DST → render_png_preview.

MCP client (Claude Code / Claude Desktop)
        │  stdio (JSON-RPC)
        ▼
inkstitch-mcp server  (FastMCP, this package)
        ├── native tools ──────────► pystitch + lxml  (stats, PNG render, format
        │                            conversion, param editing, font/format lists)
        └── subprocess tools ──────► .venv-inkstitch python
                                     vendor/inkstitch/inkstitch.py --extension=…
                                     (export, import, lettering, validation,
                                      stitch-plan previews, transforms)

Tools (21)

Tool What it does
health_check Verify toolchain; optional end-to-end smoke export
list_formats Machine formats Ink/Stitch reads (~50) and writes (~22)
list_fonts 140 bundled digitized lettering fonts
list_known_params All legal per-element stitch parameters (~136)
list_elements Inventory an SVG: ids, labels, stitch type (fill/stroke/satin), params
get_element_params / set_element_params Read/write inkstitch:* stitch settings on elements
export_embroidery SVG → machine file (format from output extension) + stitch stats
import_embroidery Machine file → editable stitch-plan SVG
export_zip One SVG → many formats in a ZIP, optional panelization
design_stats Stitch/jump/trim/color counts, threads, size (mm) of a machine file
convert_machine_format Machine file → machine file (e.g. DST → PES)
render_png_preview PNG image of the stitches (from machine file or SVG)
thread_list Plain-text thread/color report
troubleshoot Structured validation: errors/warnings with positions & fixes
density_map Stitch-density heat-map layer (thread-break risk)
preview_stitch_plan Render the actual stitch plan into an SVG layer
cleanup_document Remove problem-causing tiny objects (dry-run by default)
transform_elements stroke_to_satin, auto_satin, auto_run, fill_to_stroke, jump_to_stroke, break_apart, outline
remove_embroidery_settings Strip embroidery params/commands from an SVG
generate_lettering Text → embroidered lettering in any bundled font

Setup

Requires Python 3.11 (Ink/Stitch's pinned dependencies do not support newer interpreters) and git. Developed and tested on Windows 11; the code paths are OS-aware but only Windows has been exercised.

# --recursive pulls the Ink/Stitch submodule AND its fonts submodule (140 fonts)
git clone --recursive https://github.com/GreerBK/InkStitchMCP
cd InkStitchMCP

py -3.11 -m venv .venv-inkstitch
# inkex's repo has a test file exceeding Windows path limits; scope the fix to this install:
set GIT_CONFIG_COUNT=1&& set GIT_CONFIG_KEY_0=core.longpaths&& set GIT_CONFIG_VALUE_0=true
.venv-inkstitch\Scripts\python -m pip install -r requirements-inkstitch.txt
.venv-inkstitch\Scripts\python -m pip install -e .

If you cloned without --recursive: git submodule update --init --recursive.

Verify everything with the health_check tool (or run the test suites below).

Paths are overridable via INKSTITCH_MCP_ROOT / INKSTITCH_MCP_REPO / INKSTITCH_MCP_PYTHON / INKSTITCH_MCP_OUTPUT (see src/inkstitch_mcp/config.py), plus INKSTITCH_MCP_TIMEOUT / INKSTITCH_MCP_SLOW_TIMEOUT (seconds) and INKSTITCH_MCP_TRACE=1 for stderr tracing of subprocess calls.

Registering with a client

Claude Code — either copy .mcp.json.example to .mcp.json (auto-loads for this project) and fill in your path, or register globally:

claude mcp add inkstitch -- <path-to-InkStitchMCP>\.venv-inkstitch\Scripts\python.exe -m inkstitch_mcp

Claude Desktop — add to %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "inkstitch": {
      "command": "<path-to-InkStitchMCP>\\.venv-inkstitch\\Scripts\\python.exe",
      "args": ["-m", "inkstitch_mcp"]
    }
  }
}

Tests

.venv-inkstitch\Scripts\python tests\e2e.py            # 34 checks, every tool, real designs
.venv-inkstitch\Scripts\python tests\protocol_smoke.py # real MCP stdio round-trip

Design notes (hard-won)

These are the traps this bridge encodes; they matter if you modify runner.py:

  • Exit codes lie. Ink/Stitch exits 0 for parse errors, "no embroiderable elements", and domain errors — with the explanation on stderr and an empty payload. Success is judged per-tool from payload presence, never from the return code.
  • stdout is binary. Embroidery/ZIP payloads come over stdout (the Inkscape convention); the output extension switches stdout to O_BINARY on Windows. Always capture bytes; stderr is UTF-8, flushed once at process exit.
  • stdin=DEVNULL is load-bearing. Under an MCP client, the server's stdin is the live JSON-RPC pipe; letting a child inherit it deadlocks the child interpreter at startup on Windows (diagnosed via py-spy: zero CPU, no Python frames).
  • Legacy SVGs summon an invisible dialog. Every extension's load() runs the version migrator with a blocking wx prompt for unversioned files containing Ink/Stitch attributes — including --extension=update_svg itself. The preflight in runner.py detects the condition (same XPath as lib/update.py) and migrates via _migrate_helper.py, which calls the migrator directly with the prompt disabled.
  • Never expose raster preview modes. png_realistic, png_simple, realistic-DPI stitch plans, and the ZIP --format-png-realistic/simple flags all shell out to an inkscape binary. PNG previews here use pystitch's native renderer instead.
  • The output extension's parser is hand-rolled. Options must be single --name=value tokens, --format is mandatory, values containing = crash it, and --output is swallowed (hence stdout capture there, --output=<tmpfile> elsewhere).
  • Arg spelling is per-extension. Some use hyphens, some underscores, some both (batch_lettering mixes them in one parser). Flags are hardcoded per tool from the vendored argparsers — don't "normalize" them.
  • --del_params must always be passed to remove_embroidery_settings: its argparse default is the Python bool True with type=str, which crashes when omitted.
  • batch_lettering dumps the input SVG on validation failure with exit 0 — the ZIP magic (PK) check is what actually detects failure.
  • Documents parameterized by this bridge are version-stamped. set_element_params writes the current inkstitch_svg_version metadata; without it, the next tool call would run the v0→v4 legacy migration on freshly written modern params and silently change their meaning (e.g. solid strokes forced to zigzag_stitch).
  • Slow tools run off the event loop. Subprocess-backed tools are registered via blocking_tool (async + anyio.to_thread); registering them as plain sync tools freezes all MCP traffic for the duration of an export.
  • custom_file_name is a path fragment inside the zip extension — it is validated against a strict character allowlist to prevent writing outside the target directory.

License

This bridge code: MIT (see LICENSE). Ink/Stitch is referenced as a git submodule — not distributed in this repository — and is GPL-3.0-or-later; pystitch and other dependencies carry their own licenses. If you distribute a bundle that includes the vendor/inkstitch checkout, GPL terms apply to that component.

About

MCP Server for Ink/Stitch

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages