zplCore.comzplCore.com

28MCP server for coding agents

zplcore-mcp is a Model Context Protocol server: coding agents such as Claude Code, Claude Desktop, VS Code/GitHub Copilot or Cursor use it to render, check and fix ZPL labels offline in a loop – write ZPL, look at the PNG, read the diagnostics, improve. 26 tools: render, lint, format, diff, fill_template, convert_epl, comply, verify, import_label, extract, redact, gs1_link_build/_parse, gs1_migrate, rfid_encode/_decode/_check, printer_profiles, printer_check, print_estimate, cut_plan, lift_svg, list_symbologies, describe_symbology, explain_command, get_limits.

dotnet pack tools/ZplCore.Mcp -c Release -o nupkg
dotnet tool install -g ZplCore.Mcp --add-source nupkg     # command "zplcore-mcp", needs the .NET 10 runtime

claude mcp add zplcore -- zplcore-mcp                     # Claude Code (current project; --scope user for all)

Claude Code (.mcp.json in the repository)

{ "mcpServers": { "zplcore": { "type": "stdio", "command": "zplcore-mcp", "args": [] } } }

Claude Desktop (claude_desktop_config.json)

{ "mcpServers": { "zplcore": { "command": "/Users/you/.dotnet/tools/zplcore-mcp", "args": [] } } }

GUI apps often do not have ~/.dotnet/tools in their PATH – use the absolute path.

VS Code / GitHub Copilot (.vscode/mcp.json)

{ "servers": { "zplcore": { "type": "stdio", "command": "zplcore-mcp", "args": [] } } }

Cursor (.cursor/mcp.json)

{ "mcpServers": { "zplcore": { "command": "zplcore-mcp", "args": [] } } }

Example run (shortened)

Prompt: “Create a 100 × 150 mm GS1 shipping label for this shipment and check it against the GS1 logistics rules.”

  1. lint – 0 diagnostics
  2. comply gs1-logistic – 2 errors: ZPL3104 SSCC X-dimension 0.375 mm < 0.495 mm, ZPL3105 bar height 13 mm < 31.75 mm
  3. Agent: SSCC barcode set to ^BY4 and 270 dots high, text 3 mm and up, layout adjusted
  4. comply gs1-logistic – 0 errors · verify – 3 of 3 barcodes read, grade A · render – PNG, 100 × 150 mm, 203 dpi

Label, findings and grades are real engine results; a pre-check, not a certification.

Security model

Isolated

  • stdio only: no HTTP/SSE, no listening socket; logs go to stderr only and never contain tool input
  • Tools take label text and return results – no access to files, the network, printers, processes or environment variables; printer storage commands work on a store that lives for one call
  • Every call runs in its own worker process with an empty environment (no client tokens), time and memory limits; on macOS also under sandbox-exec (no network, no writes outside its scratch folder, home directory unreadable)
  • No PDF: lift_svg takes SVG text only, PDFium is not shipped with the server

Bounded

  • Strict schemas: unknown arguments, wrong types, out-of-range values and duplicate keys are rejected
  • Every call inside a ZplLimits scope (see below): 10 labels, 12 M dots, 4 MiB graphics, 16 MiB printer storage, 64 Ki characters of field data
  • 20 s and 1536 MB per call (configurable: --timeout-seconds, --memory-mb, --workers)
  • SVG: 2 Mi characters, no DOCTYPE/entities, no external references, ≤ 256 levels, ≤ 200,000 elements
  • Strings from the label are marked as untrusted data in the result