label-printer-mcp
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., "@label-printer-mcpprint the 4x6 label in return.pdf on my thermal printer"
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.
label-printer-mcp
Print a 4x6 shipping label from a PDF — as a CLI, a Python library, or an MCP server.
A return label turns up as a 4x6 page, or as a US Letter sheet with the label in one corner and a packing slip below it, or sideways. This finds the label, crops to it losslessly, checks it really is 4x6, and prints it at exactly 100% on a 4x6 thermal printer.
Why it crops instead of scaling
A carrier's barcode encodes the tracking number in the width of its bars. Scale the label — or rasterise and resample it — and you can get a parcel whose barcode a scanner won't read, with nothing wrong on screen to warn you. It gets rejected at the counter.
So the crop here is a CropBox change: the page keeps every object it had and simply shows a smaller window onto
them. Vector artwork stays vector and prints at whatever resolution the printer has. Nothing is resampled, ever, and
printing passes print-scaling=none so CUPS doesn't helpfully fit the label to the media.
A test pins this: it counts the barcode's vector drawings after the crop. A rasterising crop would leave one image and zero drawings, and would pass a size check while producing a label a scanner may refuse.
Related MCP server: proof-print-dialog
Why it refuses
Finding the label on a letter sheet is a heuristic. Candidates are scored on aspect ratio alone — "biggest block" and "most ink" both pick the packing slip on a busy sheet, while a 4x6 label is the only thing on it with a 1.5 ratio and a short side over three inches.
When nothing scores well it refuses and says what it saw, with measurements, rather than cropping to the wrong thing:
no region looks like a 4x6 label. Closest: 3.41x8.01in (aspect 2.35), 8.5x11.0in (aspect 1.29).
A 4x6 has aspect 1.50 and a short side of 4.0in; refusing rather than cropping to the wrong thing.that region is 3.2x4.8in, not 4.0x6.0in (aspect is right, size is not). Scaling it would corrupt the
barcode, so nothing was written. Print it as-is only if you mean to.Paper is cheap; a mislabelled return is not.
Install
python3 -m venv .venv
.venv/bin/pip install -e . # or: pip install pymupdf mcpCLI
python -m labelprint inspect label.pdf # what it is, and where the label looks to be
python -m labelprint normalise label.pdf out.4x6.pdf # crop to the label; --page N for a later page
python -m labelprint preview label.pdf out.png # look before you print
python -m labelprint queues # the print queues this machine has
python -m labelprint print out.4x6.pdf MyPrinter # DRY RUN: prints the command, sends nothing
python -m labelprint print out.4x6.pdf MyPrinter 1 --liveprint is a dry run unless you pass --live. Everything returns JSON.
MCP server
{
"mcpServers": {
"label": {
"command": "/path/to/label-printer-mcp/.venv/bin/python",
"args": ["/path/to/label-printer-mcp/server.py"]
}
}
}Tools: inspect, prepare, preview, printers, send. send is a dry run unless called with live=True, so an
assistant has to say explicitly that it means to move paper — and should show you the preview first.
Library
from pathlib import Path
import labelprint
r = labelprint.normalise(Path("return.pdf"), Path("out.4x6.pdf"))
if r.ok:
print(r.size_in) # [4.0, 6.0]
labelprint.print_label(Path(r.out), "MyPrinter", dry_run=False)
else:
print(r.reason) # why it refused, with measurementsPrinter setup
Add the printer in System Settings → Printers & Scanners, then:
lpstat -p # the queue name
lpoptions -p <queue> -l # what options it actually supportsThat second command matters. A CUPS queue silently ignores options it doesn't advertise, which looks exactly like
them working — so check that your printer really takes media=Custom.4x6in and print-scaling before trusting a
label that came out looking fine.
Tests
.venv/bin/python test_labelprint.py15 tests on synthetic fixtures shaped like the real thing: a 4x6 page, a label on a letter sheet, a label above a packing slip (the case the finder exists for), a landscape label, an undersized label, a packing slip alone, a blank page. The fixtures are synthetic on purpose — a real return label carries somebody's address and tracking number.
Requirements
macOS or Linux with CUPS (lp, lpstat), Python 3.10+, and PyMuPDF.
The MCP server additionally needs the MCP SDK (v2+).
Licence
MIT.
This server cannot be deployed
Maintenance
Related MCP Connectors
Thermal label MCP server: render, validate, debug and convert ZPL, EPL, TSPL and CPCL labels.
Print & mail PDF/HTML/Markdown/text/DOCX/images to US addresses; pay per call in x402 USDC on Base.
AI tools for MyPost A4 labels, 4x6 thermal printers and LabelChop resources.
Prepare USPS Certified Mail letters from any AI assistant; a person reviews, pays and authorizes.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to print documents, manage print queues, and control printers on macOS/Linux systems via the CUPS printing system. Supports printing PDFs, text files, and other formats with options like duplex printing, landscape orientation, and multiple copies.68 npm12MIT
- FlicenseNot gradedqualityBmaintenanceEnables programmatic document proofing for print, with real ink coverage measurement and waste page detection, letting agents decide what to print before any sheet is produced.-
- 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
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to submit PDFs or JSON-rendered templates to local printers, check printer status, and manage print jobs through MCP tools.214 npmMIT