NiimBlue Labels MCP
OfficialSummary: This server designs NIIMBOT thermal-printer labels with NiimBlue's renderer and gives you a preview plus a link to print — it never prints or touches a printer itself.
Render labels (
render_label): build labels from 1–100 objects (Textbox, Icon/Material Icons, Rect, Circle, Polyline, QRCode, CODE128B/EAN13 Barcode) in printer-dot coordinates, with font, weight, rotation, alignment species.Preview exactly what prints: returns the 1-bit PNG the printhead burns, each object's rendered bounding box, and the label geometry (dpi, print direction, printhead width, size in dots).
Print via link: returns a niim.blue
#load=link that opens the label in NiimBlue (after a confirm that replaces the open label — save it first).Get warnings with fixes: overflow, off-label/near-edge, small or thin text, thin strokes, wrapped text, glyph fallback, missing/carried-by-name fonts, unfilled fields, QR/barcode errors, module size and quiet zones.
Fill in data:
{key}fields populate fromrows(1 row in the link, more rows as a NiimBlue CSV for one label per row);{dt}/{dt|format}print dates at print time.Cable-flag layouts: split the label (
split,split_parts), mirror/copy or flip into the other part, and add a tail (tail_pos,tail_length_mm).Save and reuse templates:
save_aswrites<name>.args.jsonplus an importable.niimblue.json;list_templateslists them;templatebases a render on a saved one.Inspect and convert:
list_fontsshows built-in, default and font-folder families (with smallest legible size, skipped files);get_templatereturns editable render args from a saved template or a NiimBlue.jsonexport (withprinter), noting anything dropped.Export:
include_jsonreturns the NiimBlue.jsonexport on the final call.Works offline: no API keys or network; rendering uses bundled NiimBlue code/fonts in headless Chrome/Chromium/Edge, with configurable env vars for Chrome path, app URL, templates dir, fonts dir and log level.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@NiimBlue Labels MCP make a 40x30mm label for my D110 that says 'Cable A' with a QR code"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
NiimBlue Labels MCP
MCP server that designs labels for NIIMBOT thermal printers (D11, D110, B1, B21 and others) and hands them to NiimBlue to print.
It renders each label with NiimBlue's own code in headless Chrome or Edge and returns the exact 1-bit image the printhead burns, plus warnings for anything that will print badly. It also returns a link that opens the label in NiimBlue. The server never prints and never talks to a printer: you open the link, check the label, and print from NiimBlue. It can also save a label as a fill-in template and reprint it with new values.
Requirements
Node.js 20+.
Google Chrome, Chromium or Microsoft Edge. NiimBlue needs one of them to print over Bluetooth anyway. The server finds it in the usual install folders; set
NIIMBLUE_CHROMEif yours is elsewhere.
No API keys and no network access: the render runs offline from the bundled NiimBlue code and fonts, plus any font files you put in your font folder.
Related MCP server: niimbot-mcp
Install
Claude Code (server plus the niimblue skill):
/plugin marketplace add Nightious-Tools/niimblue-mcp
/plugin install niimblue-mcp@niimblue-mcpCodex:
codex plugin marketplace add Nightious-Tools/niimblue-mcpThen run /plugins, install NiimBlue Labels, and start a new session.
Claude Desktop: download niimblue-mcp.mcpb from Releases and open it. It asks for an optional Chrome path, the NiimBlue URL, the templates folder and the font folder.
OpenCode: clone the repo and add this to your opencode.json. OpenCode reads the skill from .claude/skills/.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"niimblue": {
"type": "local",
"command": ["node", "/path/to/niimblue-mcp/dist/index.mjs"]
}
}
}Other MCP clients:
{
"mcpServers": {
"niimblue": {
"command": "npx",
"args": ["-y", "github:Nightious-Tools/niimblue-mcp"]
}
}
}On Windows, some clients need "command": "cmd", "args": ["/c", "npx", "-y", "github:Nightious-Tools/niimblue-mcp"].
Server only:
claude mcp add niimblue -s user -- npx -y github:Nightious-Tools/niimblue-mcp
codex mcp add niimblue -- npx -y github:Nightious-Tools/niimblue-mcpTools
Tool | Purpose |
| Render a label and return the print preview and the NiimBlue link. Writes files only when |
| List saved templates: name, title, printer, size in mm, the |
| List the |
| Return |
render_label
Param | Purpose |
| Printer model, such as |
| Label size as set in NiimBlue, 4–300 mm. |
| Optional label name in NiimBlue's saved labels. |
| Optional cable-flag layout: split into parts, then copy or flip the design into the other part. |
| Optional cable-flag tail. |
| 1–100 objects in paint order: |
| Optional on |
| Optional values for the |
| Optional saved template name. Its args are the base; args given here override them, and |
| Save these args as a template: |
| Also return the NiimBlue |
It returns the 1-bit PNG, then JSON with label (dpi, print direction, printhead width and size in dots), zoom, link, link_chars, boxes (each object's rendered bounding box), warnings, and saved (args_path, niimblue_path) after a save_as.
Opening the link replaces the label open in NiimBlue, after a confirm. Save it first.
Each warning has a code, the object index when it has one, and a message that ends with the fix:
HEAD_OVERFLOW, OFF_LABEL, NEAR_EDGE, TEXT_SMALL, TEXT_THIN, STROKE_THIN, TEXT_WRAPPED, GLYPH_FALLBACK, FONT_MISSING, FONT_NOT_IN_LINK, UNFILLED_FIELD, QR_ERR, QR_MODULE_SMALL, QR_QUIET_ZONE, BARCODE_ERR, BARCODE_MODULE_SMALL, BARCODE_QUIET_ZONE.
TEXT_WRAPPED means a Textbox wrapped where its text has no \n; widen it or break the line yourself. UNFILLED_FIELD means a {key} has no value in rows, so it prints literally. FONT_MISSING means a fontFamily is neither built in nor in your font folder, or its file isn't a valid font; the preview used a fallback. FONT_NOT_IN_LINK names the font file to add in NiimBlue before you open the link (see Fonts).
get_template
Pass name for a saved template's args, or path and printer to convert a NiimBlue .json export (Saved labels → Export, or a .niimblue.json, up to 2 MB). The conversion keeps Textbox, Material Icons text, Rect, Circle, Polyline, QRCode and Barcode, and turns the export's CSV into rows. An export with images, ArUco markers, paths or groups is refused with BAD_INPUT; notes lists anything else it dropped.
Errors return ok: false with error.code: BAD_INPUT, CHROME_NOT_FOUND, RENDER_FAILED, RENDER_TIMEOUT or INTERNAL.
The first time NiimBlue opens a link it may lay out text before its font has loaded. If the text in the app looks wrapped differently from the preview, reopen the link.
Fonts
Every NiimBlue has Noto Sans Variable (Latin and Cyrillic) and Material Icons. The link carries only a font's name, so any other fontFamily needs its file added in NiimBlue once: open the Fonts menu (the gear by the font picker) and upload it. Characters a font lacks, such as ł or →, fall back to a system font and print differently on each machine (GLYPH_FALLBACK).
The server bundles five Latin-only fonts. Upload these files from fonts/ once:
| Style | File |
| Monospace, 700 |
|
| Condensed grotesk, 700 |
|
| Heavy wide display, 400 |
|
| Heavy grotesk, 800 |
|
| Slab serif, 700 |
|
Each file holds one weight, so leave fontWeight unset: any family but Noto defaults to 400, which draws the file as is, and a higher weight prints a faked bold.
niim.blue currently drops an uploaded font whose name has a space, so the label prints in the fallback font. That covers all five built-ins. A fix has been submitted to NiimBlue; until it is live, set NIIMBLUE_APP_URL to a NiimBlue build that has it.
For your own fonts, put .woff2, .ttf or .otf files (up to 2 MB) in the font folder (NIIMBLUE_FONTS_DIR). The family is the file name up to the first dot, as in NiimBlue's Fonts menu: Inter Bold.ttf is Inter Bold. A folder file overrides a built-in font of the same name. NiimBlue takes only .ttf and .woff2, so rename an .otf to .ttf before you upload it. list_fonts shows what the server found and why it skipped a file. Put only fonts you trust there: the preview's Chrome parses them without its sandbox.
Environment variables
All optional. See .env.example.
Variable | Default |
| Auto-detected. Linux: |
|
|
|
|
|
|
|
|
Development
Needs Node.js 22.12+ and npm 11+ to develop (vitest 5 and the lockfile's overrides need them); the shipped bundle runs on Node 20.
git clone https://github.com/Nightious-Tools/niimblue-mcp && cd niimblue-mcp
npx -y npm@11 ci
npm test # render tests need Chrome or Edge
npm run build # writes dist/index.mjs, which is committed
npm run inspect # MCP Inspector
npm run pack # build, then niimblue-mcp.mcpbLicense
Source-available, not open source. You may install and run it; you may not redistribute or modify it. See LICENSE. The bundle includes NiimBlue (MIT), fabric, Noto Sans, JetBrains Mono, Barlow Condensed, Archivo, Archivo Black, Bitter (OFL-1.1), Material Icons (Apache-2.0) and other third-party code under their own licenses: see THIRD_PARTY_NOTICES.md. Not affiliated with NIIMBOT or NiimBlue.
Available Tools
4 toolsget_templateGet label template argsARead-onlyIdempotent
Return render_label args to edit: a saved template by name, or a NiimBlue .json label export (path + printer) converted to objects and rows. Images, ArUco markers, paths and groups can't be converted (BAD_INPUT); notes lists what else was dropped.
Inputs: name, path, printer. Returns: ok, args, tool, notes
list_fontsList label fontsARead-onlyIdempotent
List the fontFamily values render_label can draw: the default (Noto Sans Variable), the built-in fonts with notes and the smallest legible size, and the font files in the user's font folder (NIIMBLUE_FONTS_DIR; .woff2, .ttf or .otf, family = the name before the first dot). The link carries only the family name: the user adds each non-default font's file (path) in NiimBlue → Fonts once.
Inputs: no named parameters. Returns: ok, tool, folder, builtin, +1 more
list_templatesList saved label templatesARead-onlyIdempotent
List the templates render_label save_as stored: name (pass it as render_label template or get_template name), title, printer, size in mm, the {key} fields rows must fill, row count, last modified.
Inputs: no named parameters. Returns: ok, dir, tool, templates
render_labelRender NiimBlue labelAIdempotent
Design a NIIMBOT label for NiimBlue and see exactly what the printhead burns. Returns the 1-bit PNG NiimBlue prints (threshold 140; each dot drawn zoom×zoom px), each object's rendered box, warnings that end with their fix, and a niim.blue #load= link that opens the label in NiimBlue for printing. Units are printer dots: 8 per mm at 203 dpi, 11.81 at 300 dpi; origin top-left; objects paint in array order and use NiimBlue/fabric property names. Floors at 203 dpi (×dpmm/8 at 300 dpi): text ≥16 px, or the font's min_px from list_fonts; weight ≥500 under 24 px; strokes ≥2 px; QR modules ≥3 px with 4 clear modules; Code 128 scaleFactor ≥2 with 10 clear modules; text and codes ≥1 mm from the edges. Colours: black, white, transparent. Fonts: Noto Sans Variable (Latin, Cyrillic) by default; any other fontFamily (list_fonts) travels by name only, so the user adds its file in NiimBlue (FONT_NOT_IN_LINK). Fix every warning and render again. Final call: include_json, for the .json export. The link replaces the label open in NiimBlue after a confirm: tell the user to save it first. {key} fields fill from rows (preview: row 1; more than 1 row travels as NiimBlue's CSV, one label per row). save_as writes the args and an importable .niimblue.json to the templates folder; template starts from saved args.
Inputs: rows, split, title, mirror, +11 more. Returns: ok, link, tool, zoom, +5 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
render_label (design/render) and list_fonts (font enumeration) are clearly distinct, and list_templates vs get_template separate list-all from fetch-one. The only soft spot is get_template, which is named like a template getter but also converts arbitrary NiimBlue .json exports, a dual role that could momentarily confuse selection.
All four names follow a clean verb_noun pattern (get_template, list_templates, render_label, list_fonts) in consistent snake_case. The naming scheme is predictable and easy to extend.
Four tools is on the lean side for a label-design server, but each one is a heavyweight operation (rendering, template import, listing, font discovery) so nothing feels padded. A dedicated save/delete template tool would round it out.
The lifecycle is mostly covered: list_templates and get_template provide read/update paths, and render_label with save_as creates or overwrites templates. There is no delete/rename template operation, and saving is an implicit argument rather than its own tool, which are minor but real gaps.
Maintenance
Related MCP Connectors
Thermal label MCP server: render, validate, debug and convert ZPL, EPL, TSPL and CPCL labels.
Fill an HTML template with JSON and get a hosted PDF or image link. Free previews, no key.
Generate branded images at scale: design templates and render them to PNGs by prompt.
Design mockups, device frames and launch graphics live in your open Brayer studio tab.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables printing PNG labels to a nearby thermal label printer over local serial or Bluetooth, with tools for rendering previews, checking printer status, and printing with confirmation.51MIT
- FlicenseNot gradedqualityCmaintenanceEnables printing text, QR codes, and images directly to NIIMBOT B1 BLE label printers without vendor apps or cloud, with orientation control, fit validation, and local preview tools.-

keyline-mcpofficial
FlicenseNot gradedqualityBmaintenanceEnables AI agents to author designs as structured JSON scenes and render them to PNG, JPEG, WebP, vector PDF, animated PNG, GIF, MP4 or WebM at every target size, using one native binary with no browser or headless Chrome.6-- AlicenseNot gradedqualityBmaintenanceEnables AI clients to prepare and preview labels, then safely submit physical print jobs to an Xprinter XP-330B through local stdio or authenticated remote access, with status, cancellation, and retry receipts.MIT