Thermal label MCP server: render, validate, debug and convert ZPL, EPL, TSPL and CPCL labels.
Model Context Protocol (MCP) Server: com.labelixa/zpl
The com.labelixa/zpl MCP server provides tools to render, validate, and convert Zebra ZPL label code produced by AI assistants. It supports generating a PNG preview, performing lint checks, and handling barcodes as part of the label workflow.
๐ ๏ธ Key Features
Render Zebra ZPL label code
Validate Zebra ZPL label code
Convert Zebra ZPL label code from AI assistants
Generate PNG preview
Lint Zebra ZPL
Barcodes support
Tool count: 8
๐ Use Cases
Preview Zebra ZPL output as PNG
Validate and lint ZPL before use
Convert AI-generated ZPL into usable label artifacts, including barcodes
โก Developer Benefits
Structured tooling for render/validate/convert
Immediate visual feedback via PNG preview
Automated linting for Zebra ZPL
โ ๏ธ Limitations
Limited to Zebra ZPL label code rendering, validation, conversion, preview, linting, and barcodes.
Render ZPL label code and return the label as a PNG image. Use this to SEE what ZPL output looks like โ LLMs can write ZPL but cannot otherwise verify the visual result. One call renders one label (use `index` to pick a label from a multi-label stream). The result also carries an 'Open this label in the Labelixa editor' link the user can click to edit, save or share the label.
Lint ZPL code and return structured diagnostics: unknown commands, missing ^FS, out-of-range parameters, fields outside the label boundary. Run this before zpl_preview when generating ZPL.
Parameters4
zpl
string
required
ZPL source
dpmm
integer
optional
Printer density (8 = 203 dpi). The boundary check measures against it โ pass the real value.
width_in
number
optional
Label width in inches. Fields outside it are reported, so a wrong size makes that finding wrong.
height_in
number
optional
Label height in inches. Same as width_in: the boundary check depends on it.
Raw schema
{
"type": "object",
"properties": {
"zpl": {
"type": "string",
"description": "ZPL source"
},
"dpmm": {
"type": "integer",
"default": 8,
"description": "Printer density (8 = 203 dpi). The boundary check measures against it โ pass the real value."
},
"width_in": {
"type": "number",
"default": 4,
"description": "Label width in inches. Fields outside it are reported, so a wrong size makes that finding wrong."
},
"height_in": {
"type": "number",
"default": 6,
"description": "Label height in inches. Same as width_in: the boundary check depends on it."
}
},
"required": [
"zpl"
]
}
zpl_command_help
Explain a single ZPL command: syntax, parameters with types/ranges/options, a fragment example and whether the Labelixa renderer draws it. Data comes from the same catalog that powers the public command reference pages.
Parameters2
command
string
required
ZPL command code, e.g. FO, ^BC, ~DG
locale
string
optional
Language for the human-readable fields (name and descriptions). Command codes, syntax strings, examples and parameter names never change.
Raw schema
{
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "ZPL command code, e.g. FO, ^BC, ~DG"
},
"locale": {
"type": "string",
"enum": [
"en",
"tr",
"de"
],
"default": "en",
"description": "Language for the human-readable fields (name and descriptions). Command codes, syntax strings, examples and parameter names never change."
}
},
"required": [
"command"
]
}
barcode_png
Generate a single barcode as a PNG image (Code 128, QR, DataMatrix, EAN-13, UPC-A, PDF417 and more). For a full label with text and layout, write ZPL and use zpl_preview instead.
Detect which printer language raw label code is written in (ZPL, EPL, TSPL or CPCL). Heuristic: returns the language plus a confidence TIER (high/medium/low) and signal codes โ not a probability.
Lint EPL/EPL2 label code and return positioned findings with severity as JSON. Checks the command set Labelixa implements from the EPL2 manual โ a clean result is not a guarantee that a specific printer accepts the job. Run this before epl_preview; if you are not sure which language the code is, call language_detect first.
Lint TSPL/TSPL2 label code and return positioned findings with severity as JSON. Checks the command set Labelixa implements from the TSPL2 manual โ a clean result is not a guarantee that a specific printer accepts the job. Run this before tspl_preview; if you are not sure which language the code is, call language_detect first.
Lint CPCL label code and return positioned findings with severity as JSON. Checks the command set Labelixa implements from the CPCL manual โ a clean result is not a guarantee that a specific printer accepts the job. Run this before cpcl_preview; if you are not sure which language the code is, call language_detect first.
Full health report for a ZPL label: sectioned findings (syntax, size/DPI, orientation, barcodes, fonts, graphics memory, job behaviour) with an honest score โ sections that cannot be assessed say so and are excluded from the score.
Parameters4
zpl
string
required
Raw ZPL code
dpmm
integer
optional
Printer density (8 = 203 dpi). The size/DPI section is scored against it โ pass the real value.
width_in
number
optional
Label width in inches; fields outside it are reported.
height_in
number
optional
Label height in inches; same role as width_in.
Raw schema
{
"type": "object",
"properties": {
"zpl": {
"type": "string",
"description": "Raw ZPL code"
},
"dpmm": {
"type": "integer",
"enum": [
6,
8,
12,
24
],
"default": 8,
"description": "Printer density (8 = 203 dpi). The size/DPI section is scored against it โ pass the real value."
},
"width_in": {
"type": "number",
"default": 4,
"description": "Label width in inches; fields outside it are reported."
},
"height_in": {
"type": "number",
"default": 6,
"description": "Label height in inches; same role as width_in."
}
},
"required": [
"zpl"
]
}
convert_zpl_dpi
Rescale ZPL between printer resolutions (203/300/600 DPI): coordinates, fonts, barcode module width and label size are scaled. Embedded ^GF/~DG image data is NOT scaled; the response says so instead of silently passing it through.
Parameters3
zpl
string
required
Raw ZPL code
source_dpi
integer
required
Resolution the ZPL was written for, in DPI (not dpmm: 203 DPI = 8 dpmm).
target_dpi
integer
required
Resolution to rescale to, in DPI. Equal to source_dpi means no scaling.
Raw schema
{
"type": "object",
"properties": {
"zpl": {
"type": "string",
"description": "Raw ZPL code"
},
"source_dpi": {
"type": "integer",
"enum": [
152,
203,
300,
600
],
"description": "Resolution the ZPL was written for, in DPI (not dpmm: 203 DPI = 8 dpmm)."
},
"target_dpi": {
"type": "integer",
"enum": [
152,
203,
300,
600
],
"description": "Resolution to rescale to, in DPI. Equal to source_dpi means no scaling."
}
},
"required": [
"zpl",
"source_dpi",
"target_dpi"
]
}
template_list
List Labelixa's first-party label template catalog: id, English name, category, size/density and tags. Read-only product content (no tenant data). Fetch one with template_get; render its ZPL with zpl_preview.
Fetch one catalog template: metadata, preview image URL and โ for non-premium templates โ the ZPL source, ready for zpl_preview. Premium templates return metadata for everyone; their ZPL source requires an API key whose plan includes the premium-template feature (same rule as the website).
Render EPL/EPL2 label code and return a PNG preview. The preview assumes 203 dpi and is an interpretation of the EPL2 manual covering a core command subset โ no physical printer validation. `labels` in the response is the TOTAL number of labels the stream prints (a stream may contain several, each ended by `P`); pass `index` to render a different one.
Render TSPL/TSPL2 label code and return a PNG preview. The preview assumes 203 dpi and is an interpretation of the TSPL manual covering a core command subset โ no physical printer validation. `labels` in the response is the TOTAL number of labels the stream prints (a stream may contain several, each ended by `PRINT`); pass `index` to render a different one.
Render CPCL label code and return a PNG preview. The preview assumes 203 dpi and is an interpretation of the CPCL manual covering a core command subset โ no physical printer validation. `labels` in the response is the TOTAL number of labels the stream prints (a stream may contain several, each ended by `PRINT`); pass `index` to render a different one.
Convert an image (PNG, JPEG, BMP or GIF, max 200 KB) to a ZPL ^GF graphic command. Returns the ZPL plus measured dimensions and the physical print size at the chosen density. PDF input is REST-only (/v1/graphics).
Parameters4
image_base64
string
required
Base64-encoded image bytes
dpmm
integer
optional
Target printer density
wrap
boolean
optional
Wrap the ^GF in a printable ^XA...^XZ label with ^PW/^LL
Decode barcodes from a photo or scan of a PRINTED label (PNG, JPEG, BMP or GIF) and report what a software decoder reads back. Honest by design: 'read' does not guarantee every handheld scanner will read it, and 'not read' does not condemn the label (photo angle/focus matter) โ the response says so.
Compatibility RISK analysis of ZPL code against a specific printer model, given as manufacturer/model (e.g. 'zebra/zd421'). NOT an emulator and never says 'it works': reports the model's language posture with evidence level and size-rule findings.
Parameters2
zpl
string
required
Raw ZPL code
model
string
required
Printer model slug, manufacturer/model, e.g. zebra/zd421
Submit a bulk label production job: one ZPL template with {{variable}} placeholders plus data rows (one object per label). Requires an API key whose plan includes bulk jobs. Quota is charged UPFRONT, one operation per row, and failed rows are not refunded; rows per job are capped by plan. Returns the job id โ check bulk_status (small jobs usually finish within seconds).
Status of one bulk job you own: state, attempt count and โ when finished โ the summary with produced count and per-row failures (row number + reason; failed rows never block the rest). Finished outputs stay downloadable for 7 days via the REST endpoint the response names.
Labelixa is an MCP (Model Context Protocol) server
and API platform for thermal label development. It gives AI assistants and
developer tools the ability to render, validate, debug, inspect and
convert thermal printer labels โ ZPL, EPL, TSPL and CPCL โ through MCP.
There are two ways to connect:
Remote server (recommended)
This npm package
Endpoint
https://api.labelixa.com/mcp
local process over stdio
Tool set
full set: rendering, validation, debugging, conversion, barcode analysis, printer compatibility, templates, bulk jobs
core subset (table below); each tool calls the Labelixa REST API
Install
nothing to install
npx -y labelixa-mcp or npm install -g labelixa-mcp
Transport: Streamable HTTP, stateless JSON-RPC over POST. Anonymous use
is free and rate-limited per IP; an API key uses the account's own quota.
Keys: labelixa.com.
Claude Code:
sh
claude mcp add --transport http labelixa https://api.labelixa.com/mcp
LABELIXA_API_KEY โ optional lbx_ API key. Without it the anonymous
quota applies.
LABELIXA_BASE_URL โ optional; defaults to https://api.labelixa.com.
Requests never follow redirects, so a server cannot forward your key to
another host. Numeric inputs are checked before a request is made: dpmm
is 6, 8, 12 or 24, label sides are finite, above 0 and at most 15 inches,
and DPI values are 152, 203, 300 or 600.
Tools in this package
Tool
What it does
zpl_preview
Renders ZPL to a PNG image for inspection. Server-side render โ not a guarantee of how a specific physical printer will output the label.
zpl_validate
Lints ZPL and returns the structured diagnostics report (unknown commands, parameter ranges, layout overflow) as JSON. Pass the real label size โ checks depend on it.
barcode_generate
Generates a standalone barcode (SVG or PNG): code128, code39, ean13, upca, upce, itf14, msi, qrcode, datamatrix, pdf417.
language_detect
Detects the printer language of raw label code (ZPL/EPL/TSPL/CPCL). Heuristic โ returns a confidence tier, not a probability.
epl_validate
Lints EPL/EPL2 code; positioned findings with severity, as JSON.
tspl_validate
Lints TSPL/TSPL2 code; positioned findings with severity, as JSON.
cpcl_validate
Lints CPCL code; positioned findings with severity, as JSON.
zpl_compatibility
Compatibility RISK analysis of ZPL against a printer model. Not an emulator โ reports language posture with evidence level; never says "it works".
zpl_command_help
Looks up one ZPL command in the maintained catalog: name, syntax, parameters and whether the preview engine actually renders it โ printer-side commands are marked as not rendered. Optional locale (en default, tr, de) translates the name and descriptions only; command codes, syntax strings, examples and parameter names are protocol and never change.
convert_zpl_dpi
Rescales ZPL coordinates between printer resolutions (203/300/600 dpi). Embedded ^GF/~DG bitmaps are NOT rescaled โ a warnings block precedes the output when present.
explain_zpl
Full sectioned health report (syntax, size/DPI, orientation, barcodes, fonts, memory) with an honest score โ sections it cannot assess say "not assessed" instead of counting.
EPL, TSPL and CPCL previews, label templates, bulk generation,
image-to-ZPL conversion and barcode reading from photos are on the remote
server only.
Directory listings
Official MCP Registry:
com.labelixa/zpl (remote server + this npm package).
Smithery: labelixa/zpl.
Smithery routes calls through its own gateway; the canonical endpoint
is https://api.labelixa.com/mcp.