NiimBlue Labels MCP
OfficialClick 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 MCPmake 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.
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 and the templates 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 |
| 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 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, 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.
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.
Only Noto Sans Variable (Latin and Cyrillic) and Material Icons travel with the link. Other characters, such as ł or →, fall back to a system font and print differently on each machine (GLYPH_FALLBACK).
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.
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 (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
3 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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Saved template name (list_templates) | |
| path | No | Or: a NiimBlue .json label export to convert (Saved labels → Export, or a saved .niimblue.json) | |
| printer | No | With path: the printer to convert for (dots per mm); the export doesn't name one |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| args | Yes | render_label args: edit them and render |
| tool | Yes | |
| notes | Yes | What the conversion dropped or changed |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond annotations by disclosing conversion limitations: images, ArUco markers, paths, and groups cannot be converted and produce BAD_INPUT. It also explains that notes reports additional dropped items, which is useful lossy-conversion behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly written sentences, front-loaded with the return purpose and followed by the key conversion caveats. No padding or redundant restatement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for this tool: annotations cover the safety profile, an output schema exists, and the description supplies the source alternatives, conversion restrictions, and notes behavior needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the path+printer pairing and conversion behavior, but the schema already documents the individual parameters and their constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: return render_label arguments for editing, not render them. It clearly identifies the two sources (saved template by name or NiimBlue .json export converted to objects and rows), which distinguishes it from render_label.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the use case clear: obtain editable render_label args from either a saved template or an exported label file. It does not explicitly state when to avoid render_label or list_templates, but the edit-oriented framing provides clear context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| dir | Yes | |
| tool | Yes | |
| templates | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description adds value by explaining what each returned field means and how the template name relates to sibling calls, though most of the returned-field detail overlaps with the existing output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with a colon-delimited field list; no filler, and the most important token (the template name usable elsewhere) is highlighted first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters, rich annotations, and an output schema present, the description only needs to frame the listing and its downstream use — which it does completely. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the baseline there is nothing for the description to disambiguate. It sensibly uses the space to describe outputs instead, adding modest value over the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (templates) scoped to those saved by render_label's save_as, then enumerates the exact fields returned. Naming the sibling tools render_label and get_template makes the distinction unambiguous without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent what to do with the result: 'pass it as render_label template or get_template name', which chains this tool correctly into the workflow. It stops short of stating when-not to call it or any precondition, so it is not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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; 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. Only Noto Sans Variable (Latin, Cyrillic) + Material Icons survive the 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.
| Name | Required | Description | Default |
|---|---|---|---|
| rows | No | Values for {key} fields, one object per label. The preview shows row 1. 1 row: the link carries the filled text. More: the link carries them as NiimBlue's CSV (it replaces the user's open CSV) and prints one label per row | |
| split | No | Split the label into parts (cable flags) | |
| title | No | Label name in NiimBlue's saved labels; travels only in the .json export (include_json, save_as), so after opening the link the user types it when saving | |
| mirror | No | Repeat the design into the other split part, optionally rotated | |
| objects | No | Objects in paint order: the first is the bottom layer | |
| printer | No | Printer model, e.g. D110, B1, D11_H: sets dpi, print direction and printable width | |
| save_as | No | Save these args as a template under this name: writes <name>.args.json and an importable <name>.niimblue.json | |
| tail_pos | No | Side of the cable-flag tail | |
| template | No | Saved template name (list_templates): its args are the base, the args given here override them, objects and rows replace wholesale | |
| width_mm | No | Label width as set in NiimBlue. B-series (top): runs across the head | |
| height_mm | No | Label height as set in NiimBlue. D-series (left): the tape width across the head | |
| overwrite | No | Replace an existing save_as template (default false: refuse) | |
| split_parts | No | Number of split parts | |
| include_json | No | Also return the NiimBlue .json export; set it on the final call | |
| tail_length_mm | No | Tail length in mm |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | Yes | |
| link | Yes | Opens the label in NiimBlue (after a confirm that replaces the open label) |
| tool | Yes | |
| zoom | Yes | Each printer dot is zoom×zoom PNG pixels |
| boxes | Yes | Rendered bounding boxes in dots, after auto-size |
| label | Yes | |
| saved | No | save_as: the template files written |
| warnings | Yes | |
| link_chars | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the safety profile (readOnly=false, idempotent, non-destructive); the description adds substantial context beyond that: the returned artifact is a 1-bit PNG thresholded at 140, per-object rendered boxes, warnings with fixes, and a #load= link. It also discloses a side effect the annotations miss — the link replaces the user's currently open label after a confirm — and that save_as writes two files into the templates folder. This is exactly what annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Effectively sized for a 15-parameter rendering tool with many hard constraints, and it front-loads purpose and returns before the rule list. It reads as a dense wall of text rather than grouped bullets, and the dpi floors duplicate enum/schema notes, so it is slightly more repetitive than needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the printer-model enum, nested object union, and an existing output schema, the description still covers the pieces an agent needs to succeed: units and dpi, interpolation and row/CSV semantics, template and save_as lifecycle, and the iterate-until-warning-free loop. Nothing material is left for the agent to guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 and the schema already documents all 15 parameters thoroughly. The description still adds meaning beyond it: dpi-to-dot conversion (8/mm at 203 dpi, 11.81 at 300), top-left origin, paint order as array order, NiimBlue/fabric property naming, and the {key}/rows interpolation contract. That said, it partly repeats schema-stated floors (e.g. font ≥16 px).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Design a NIIMBOT label for NiimBlue') and immediately scopes the output ('see exactly what the printhead burns'). The render step is clearly distinguished from the sibling list_templates/get_template tools, which only manage saved args. An agent can tell what this does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete operational flow: fix every warning then re-render, and 'final call: include_json' for the .json export, plus the ordering caution that the link replaces the label currently open in NiimBlue and the user must save first. It does not explicitly say when to prefer this tool over list_templates/get_template, but the workflow guidance is otherwise clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v1.1.0- First observed
get_template - First observed
list_templates - First observed
render_label
TDQS
Scored across 3 tools
The three tools have clearly distinct purposes: render_label handles design/rendering, list_templates enumerates saved templates, and get_template retrieves template args for editing. There is no meaningful overlap in their intended actions, so an agent can easily select the right tool.
All names use a consistent snake_case verb_noun convention: render_label, list_templates, get_template. The pattern is predictable and readable across the set.
Three tools are well scoped for a focused label-rendering and template-management server. Each operation (render, list, get) earns its place without redundancy or obvious over-fragmentation.
The surface covers rendering, saving, listing, and retrieving templates, which supports the main label workflow. However, template lifecycle operations such as delete or rename are absent, leaving minor gaps an agent must work around.
Maintenance
Related MCP Connectors
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.
- BrayerOAuthcom.usebrayer
Design mockups, device frames and launch graphics live in your open Brayer studio tab.
Deterministic image rendering for agents: JSON template in, on-brand PNG out.
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.5MIT
- 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.-
- AlicenseNot gradedqualityCmaintenanceEnables an assistant to locate a 4x6 shipping label within a PDF, crop to it losslessly without resampling, verify its true size, preview it, list print queues, and send it to a thermal printer at exactly 100%. All printing stays a dry run unless explicitly confirmed live, and the server refuses to crop or scale when the region doesn't measure up to 4x6.1MIT

keyline-mcpofficial
FlicenseNot gradedqualityAmaintenanceEnables 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.4-