Resource-only MCP server with docs and templates for the boxpdf TypeScript PDF layout library.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
A box-layout DSL over pdf-lib. Implemented in portable JavaScript, it runs in Node 20+, Cloudflare Workers, Deno, and browsers.
Live gallery: https://earonesty.github.io/boxpdf/
flowToPdf owns the document lifecycle and returns the saved bytes. standardFonts embeds the built-in Helvetica family (regular, bold, italic, bold-italic) in one call.
renderFlow(pdf, nodes, options) paginates into a document you own and returns { pages } β reach for it when you need multiple render passes, the page objects, or custom save() options. boxpdf re-exports PDFDocument and StandardFonts for this explicit lifecycle.
pdf-lib is a peer dependency.
The original boxpdf package remains supported and is published from the same build at the same
version. Existing imports and the boxpdf CLI continue to work unchanged:
New projects should use @boxpdf/writer. Both package names expose the same API, and both provide
the boxpdf command.
vstack, hstack, text, image, hline, vline, spacer, flex, keepTogether, link, svgPath, table.maxLines truncation, optional breakWords, and no-wrap control.cleanTheme, stripeTheme, editorialTheme, brutalistTheme.@pdf-lib/fontkit only when you call loadFont or embedInter.Files in templates/ cover receipts, boarding passes, resumes, order confirmations, and certificates. Each is a single file.
Scaffold one into your app with the CLI:
The CLI also ships a resource-only MCP server for agents:
Every theme factory accepts either a { font, bold, italic? } object β which is exactly what standardFonts(pdf) and embedInter(pdf) return β or the legacy positional fonts:
standardFonts(pdf, family) takes "helvetica" (default), "times", or "courier" and returns { font, bold, italic, boldItalic }. Every theme exposes the same shape: colors, spacing, radii, type, card, hr.
vstack(style, ...children). Vertical layout.hstack(style, ...children). Horizontal layout.keepTogether({ gap?, margin? }, ...children). Paginates atomically.Container style:
| Field | Type | Notes |
|---|---|---|
width / height | number | Fixed dimensions; otherwise size to content. |
padding / margin | number | { top, right, bottom, left } | Shorthand or per-side. |
background | RGB | Solid fill. |
backgroundImage | { image, width, height, offsetX?, offsetY?, repeat? } | Image painted behind children and clipped to the box. |
border | { color, width } | 1pt+ stroke around the box. |
borderSides | { top?, right?, bottom?, left? } | Per-side strokes using { color, width }. |
borderRadius | number | Corner radius. |
overflow | "visible" | "hidden" | Clips stack children and absolute descendants to the box rectangle. |
position | "relative" | "absolute" | CSS-like positioning for boxes. |
top / right / bottom / left | number | Absolute offsets in points. |
zIndex | number | Paint order for positioned boxes; higher values render later. |
rotate | number | Clockwise paint rotation in degrees around the box center; layout is unchanged. |
transform | BoxTransform[] | Ordered paint transforms: translate, scale, rotate, skew, and matrix. |
transformOrigin | { x, y } | Pivot using { length, percent } components; defaults to the box center. |
grow | number | Flex grow weight along the parent's main axis. |
shrink | number | Flex shrink weight. |
breakInside | "auto" | "avoid" | Fragmentation hint under renderFlow; avoid keeps the box atomic. |
gap | number | Spacing between children. |
justify | "start" | "center" | "end" | "between" | "around" | "evenly" | Main-axis distribution. |
align | "start" | "center" | "end" | "stretch" | "baseline" | Cross-axis alignment. baseline is intended for hstack rows. |
text(content, { size, font, color?, align?, width?, lineHeight?, maxLines?, underline?, strikethrough?, margin? }). Word-wraps when width is set. Truncates with ellipsis when maxLines is set. Default lineHeight uses the font's full height, including descenders.paragraph({ width?, align?, lineHeight?, margin?, paddingLeft?, textIndent?, wrap?, floats? }, ...runs). Mixed inline text runs and atomic inline nodes that wrap together as one paragraph. Use run(text, style), linkRun(text, style, href), and inlineNode(node, { verticalAlign?, href? }). Newlines in runs create hard breaks; wrap: false disables soft wrapping.image(pdfImage, { width, height, margin? }). Takes an already-embedded PDFImage.imageFit(pdfImage, { width, height, fit?, margin? }). Draws an image centered in a fixed rectangle, scaled to contain (default) or cover with clipping.spacer(size, { grow? }) / flex(weight = 1). Fixed or growing gap.hline({ color, thickness?, width?, margin? }).vline({ color, thickness?, height?, margin? }).link({ href }, child). Wraps a child and registers a PDF Link annotation over its rendered bounding box.table({ columns, rows, ... }). Fixed / auto / fractional columns with header/footer rows, dividers, styled cells, and row-level page fragmentation under renderFlow. Cells can be plain nodes or { content, colSpan?, padding?, background?, border?, borderSides?, borderRadius?, align?, valign? }.Form widgets are atomic layout nodes, so they work inside stacks, tables, pagination, and streamed documents without manual page coordinates.
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/boxpdf)<a href="https://allmcps.com/mcp/boxpdf"><img src="https://allmcps.com/api/badge/boxpdf?style=directory" alt="Boxpdf on AllMCPs" /></a>