print-blocks
Enables printing structured documents to ESC/POS thermal printers via a CUPS queue, with tools for printer info, print jobs, and template management.
README
print-blocks
print-blocks is a small TypeScript service that prints structured documents to ESC/POS thermal printers.
It has an API endpoint /print that accepts a JSON payload describing a document as an array of blocks, renders them to ESC/POS bytes with react-thermal-printer, and submits the resulting bytes to a CUPS printer with lp.
The service has no UI. It exposes:
POST /printfor authenticated print jobs.GET /healthzfor unauthenticated liveness checks.GET /openapi.jsonfor generated OpenAPI JSON.GET /docsfor an interactive Scalar API reference whenEXPOSE_DOCS=true.GET /llms.txtfor LLM-friendly Markdown API documentation whenEXPOSE_LLMS_TXT=true.ALL /mcpfor authenticated MCP clients whenEXPOSE_MCP=true.
Requirements
- Node.js 24 and pnpm 10 for local development.
- CUPS configured on the host.
- A CUPS printer queue that accepts raw/native ESC/POS data.
- The CUPS client command
lpavailable wherever the app runs.
The production container installs cups-client, so lp is available inside the image.
Configuration
Copy the example environment file and edit it:
cp .env.example .env
Note:
- Documentation endpoints are disabled by default. Set
EXPOSE_DOCS=trueto enable/docsandEXPOSE_LLMS_TXT=trueto enable/llms.txt. - The MCP endpoint is disabled by default. Set
EXPOSE_MCP=trueand provide a separateMCP_TOKENwith at least 32 characters to enable/mcp. PRINTER_WIDTHconfigures the printer text width in characters and defaults to48.PRINTER_DOT_WIDTHconfigures the raster width used for image-like blocks and defaults to576dots. Set it explicitly when your printer mode uses a different raster width, such as384dots.- Image blocks accept base64-encoded data through the
dataproperty. Supported image formats are JPEG, PNG, WebP, and SVG. Remote image URLs are disabled by default. SetALLOW_REMOTE_IMAGE_URLS=trueto allow image blocks to use an HTTPSurlinstead. Remote image fetching is intentionally strict: only HTTPS URLs with public domain hostnames are accepted, direct IP addresses and credentials are rejected, redirects are not followed, downloaded bytes are limited byMAX_REMOTE_IMAGE_BYTES, fetches time out afterREMOTE_IMAGE_TIMEOUT_MS, and decoded image input is limited byMAX_IMAGE_INPUT_PIXELS. These restrictions are in place to prevent abuse and security issues, but enabling remote image URLs is only recommended in trusted environments.
Development
Install dependencies:
pnpm install
Run the dev server:
pnpm dev
SVG-backed block previews are available in development at:
http://localhost:3000/preview
Run checks:
pnpm typecheck
pnpm lint
pnpm format:check
pnpm test
pnpm build
API
POST /print
Headers:
Content-Type: application/json
Authorization: Bearer <API_TOKEN>
Body:
{
"blocks": [
{
"type": "text",
"content": "Hello from print-blocks",
"align": "center",
"bold": true
}
]
}
Success response:
{
"ok": true
}
GET /healthz
Returns:
{
"ok": true
}
GET /openapi.json
Returns the OpenAPI specification for the API.
GET /docs
Returns an interactive API reference backed by Scalar and /openapi.json. This endpoint is only registered when EXPOSE_DOCS=true.
GET /llms.txt
Returns Markdown API documentation generated from the OpenAPI specification. This endpoint is only registered when EXPOSE_LLMS_TXT=true.
ALL /mcp
Serves a stateless MCP server over streamable HTTP. This endpoint is only registered when EXPOSE_MCP=true and requires Authorization: Bearer <MCP_TOKEN>.
Available tools:
get_inforeturns printer settings, service limits, supported blocks, and templates.printrenders print instructions and submits them to the configured printer.list_templateslists examplary print templates that can be used as starting points or inspiration for print requests.get_templatereturns Markdown instructions and the template's JSON structure for a given template id.
Manual smoke test
After the app is running:
curl -X POST "http://localhost:3000/print" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_TOKEN" \
--data '{"blocks":[{"type":"text","content":"Hello from print-blocks","align":"center"}]}'
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
E2B
Using MCP to run code via e2b.