Give your AI agent a printer.
shortorder is a tiny Go binary that turns a USB thermal printer into an HTTP + MCP service. Agents discover it, scripts hit it — and it cooks up text, receipts, QR codes, barcodes and SVG. No drivers. No cloud. No spooler.
The printer your agent can actually use.
One tiny binary. An HTTP API and an MCP server over a USB thermal printer — so anything that speaks HTTP, and any MCP-aware LLM, can print a receipt on demand.
Agents discover it. Then they print.
shortorder ships an MCP server, an OpenAPI spec, and mDNS advertising — so an LLM can find your thermal printer on the LAN and use it as a tool, no integration code required.
Three ways an agent finds the printer.
This is the part that makes it AI-enabled. Point an agent at the box and it discovers the print tools on its own — no integration to write.
MCP server
Exposes the printer as Model Context Protocol tools. MCP-aware agents get the schemas automatically — over stdio (subprocess) or HTTP streamable transport.
OpenAPI 3.1
A descriptor at /openapi.json (and /.well-known/) for function-calling agents and tool loaders that import an OpenAPI spec.
mDNS discovery
Advertises _shortorder._tcp on the LAN with TXT records, so an agent can find the box without ever being told its IP.
// claude_desktop_config.json — or any MCP client { "mcpServers": { "shortorder": { "command": "shortorder", "args": ["mcp"] } } }
# HTTP streamable transport — live whenever the service runs POST http://localhost/mcp # tools advertised to the agent: list_printers print_text print_document print_qr print_barcode print_svg print_image cut
# OpenAPI 3.1 descriptor for function-calling agents GET http://localhost/openapi.json GET http://localhost/.well-known/openapi.json
# the service advertises itself on the local network $ dns-sd -B _shortorder._tcp $ avahi-browse _shortorder._tcp # TXT records: version · path · api · mcp · openapi
Reach for print_document to lay out a whole receipt — header, itemized table, totals, a code, footer — in one job using the printer's crisp native text. print_svg is the escape hatch for anything the character grid can't express.
Or just POST it. Any language, any shell.
Once it's running, print from anything that speaks HTTP. Copy a line, point it at your box, watch it cut.
# Plain text, centered and bold, then cut curl -X POST http://localhost/api/print/text \ -H 'Content-Type: application/json' \ -d '{"text":"ORDER #42","align":"center","bold":true,"cut":true}'
# A whole receipt in one job: header, table, total, cut curl -X POST http://localhost/api/print/document \ -H 'Content-Type: application/json' \ -d '{ "elements": [ {"type":"text","text":"SHORT ORDER","align":"center","bold":true}, {"type":"rule"}, {"type":"table", "columns":[{"width":3},{"width":0},{"width":8,"align":"right"}], "rows":[["2","Coffee","$6.00"],["1","Muffin","$3.25"]]}, {"type":"rule","char":"="}, {"type":"row","left":"TOTAL","right":"$9.25","bold":true} ], "cut": true }'
# A QR code with a caption curl -X POST http://localhost/api/print/qr \ -H 'Content-Type: application/json' \ -d '{"data":"https://example.com","caption":"scan me"}'
# A CODE128 barcode with the value printed beneath curl -X POST http://localhost/api/print/barcode \ -H 'Content-Type: application/json' \ -d '{"data":"SHORTORDER42","format":"code128","caption":"SHORTORDER42"}'
# Arbitrary layout via SVG — logos, shapes, free positioning curl -X POST http://localhost/api/print/svg \ -H 'Content-Type: application/json' \ -d '{"svg":"<svg xmlns=... width=384 height=80>...</svg>"}'
# Built-in samples — no body required curl -X POST http://localhost/api/print/sample/receipt curl -X POST http://localhost/api/print/sample/svg # Any PNG/JPEG/GIF, scaled to fit and dithered curl -X POST 'http://localhost/api/print/image?align=center' \ --data-binary @logo.png -H 'Content-Type: application/octet-stream'
Straight to the USB endpoint. No driver to install.
Receipt printers speak ESC/POS — a byte stream of text plus control sequences. shortorder renders each request to ESC/POS and writes it directly to the printer's USB device. No spooler, no print queue, no driver.
Request
An HTTP / MCP call arrives — text, document, QR, barcode, image or SVG.
Render
Composed to the printer's native font grid, or rasterized to a 1-bit bitmap.
ESC/POS
Emitted as a single byte stream with formatting, raster and cutter commands.
Written straight to the USB device node — then the receipt is cut.
Native text grid crisp · small
- Text and full layouts via
/api/print/document— rows, tables and rules over a fixed character grid. - Composed in code from the printer's native font, so it prints sharp and tiny.
1-bit raster universal
- QR, barcodes, images and
/api/print/svgrendered to a 1-bit raster (Floyd–Steinberg dithered). - SVG drawn by a pure-Go engine with fonts bundled in the binary — identical on every host, no system fonts needed.
Windows
Finds the printer via the USB printer device interface (GUID_DEVINTERFACE_USBPRINT) and writes with CreateFile / WriteFile.
Linux & Raspberry Pi
Finds the printer in sysfs, matches USB VID/PID against the allowlist, and writes to its usblp node (/dev/usb/lp0).
Most cheap USB receipt printers just work.
It's a REST and MCP interface to an ESC/POS USB printer. If yours is Epson-compatible, you're already most of the way there.
| Printer | Interface | Status |
|---|---|---|
| Volcora v-WRP2-A1W | USB · ESC/POS | Supported |
| Epson TM-series & compatible clones | USB · ESC/POS | Works · same USB identity |
Most inexpensive 80mm and 58mm USB receipt printers are ESC/POS and Epson-compatible. Adding one is a one-line allowlist change — put a Model (USB vendor/product ID and/or a name substring) in internal/printer/printer.go. The print path is already shared across models.
One binary. No dependencies. Pick your platform.
Prebuilt binaries and packages ship for every release. The commands below use the GitHub CLI (gh) to resolve the latest version for you.
# Debian, Ubuntu, Raspberry Pi OS — installs a boot service gh release download -R aphexddb/shortorder -p '*_linux_arm64.deb' sudo dpkg -i shortorder_*_linux_arm64.deb # serves the UI + API on port 80, reachable at shortorder.local
gh release download -R aphexddb/shortorder -p '*_linux_amd64.tar.gz' tar -xzf shortorder_*_linux_amd64.tar.gz ./shortorder # on macOS, use the darwin_arm64 (Apple Silicon) or darwin_amd64 build
Download shortorder_<version>_windows_amd64.zip from Releases, unzip it, then run:
shortorder.exe # listens on http://localhost:8080/
# requires Go 1.26 or newer make build # single static binary into ./bin ./bin/shortorder -list # see what's detected ./bin/shortorder # run the service
Then open the web UI — it lists connected devices, runs test prints, and documents the full API. localhost on Linux/macOS, localhost:8080 on Windows.
Contributions & new printer models welcome.
shortorder is Apache-2.0 and built in the open. Adding support for your printer is usually a one-line allowlist change — and the print path is already shared. Bring a model, a bug, or an idea.