
boxpdf
io.github.earonesty由 GitHub 账号 earonesty 发布v1.0.3更新于 Oct 24, 2026
Resource-only MCP server with docs and templates for the boxpdf TypeScript PDF layout library.
发布方自己的服务:captcha.cc Human Verification
概览
一个仅提供资源的 MCP 服务器,为助手提供 boxpdf TypeScript PDF 排版库的文档和模板。
- 可以做什么
- 提供 boxpdf PDF 排版库的参考资料:布局原语、主题、AcroForm 表单字段、渲染与流式 API、字体和加密选项,以及限制和运行时支持说明。提供收据、登机牌、简历、订单确认和证书的起始模板。它仅提供资源,不包含用于生成或编辑 PDF 的工具。
- 适用场景
- 适合在助手协助编写或调试使用 boxpdf 生成 PDF 的 TypeScript 代码时,随时查阅该库的 API、模板和主题细节。如果只是想让助手直接产出 PDF 文件,则不需要它。
- 运行要求
- 作为本地进程通过 stdio 运行,使用 npx 从 boxpdf npm 包启动,需要 Node.js。未声明任何身份验证、环境变量或请求头。
安装
在 SourceWeft 中
- 打开 控制台中的 boxpdf,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
@boxpdf/writer
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/
Related repos: boxpdf-html (HTML → BoxPDF) and streaming-pdf-reader (PDF → document model, HTML, and structured data).
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.
Prefer to manage the document yourself? The explicit path still works.
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.
Install
pdf-lib is a peer dependency.
Legacy package name
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.
What it does
- Declarative layout primitives:
vstack,hstack,text,image,hline,vline,spacer,flex,keepTogether,link,svgPath,table. - Layout-aware AcroForm fields: text, checkbox, radio, dropdown, option-list, and push-button widgets.
- Padding, margin, background, background images, borders, borderRadius, overflow clipping, flex-grow, flex-shrink, justify, align.
- Rich paragraphs with mixed inline runs, inline replaced nodes, hard breaks, hanging indents, and optional paragraph floats.
- Word wrapping with
maxLinestruncation, optionalbreakWords, and no-wrap control. - Themes:
cleanTheme,stripeTheme,editorialTheme,brutalistTheme. - Multi-page flow with per-page headers and footers, stack fragmentation, and table row fragmentation.
- Streaming generation for memory-bounded output.
- PDF link annotations, text decorations, document metadata.
- ~7 KB minified core. Custom fonts pull in
@pdf-lib/fontkitonly when you callloadFontorembedInter.
Templates
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:
Themes
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.
API
Containers
vstack(style, ...children). Vertical layout.hstack(style, ...children). Horizontal layout.keepTogether({ gap?, margin? }, ...children). Paginates atomically.
Container style:
Leaves
text(content, { size, font, color?, align?, width?, lineHeight?, maxLines?, underline?, strikethrough?, margin? }). Word-wraps whenwidthis set. Truncates with ellipsis whenmaxLinesis set. DefaultlineHeightuses 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. Userun(text, style),linkRun(text, style, href), andinlineNode(node, { verticalAlign?, href? }). Newlines in runs create hard breaks;wrap: falsedisables soft wrapping.image(pdfImage, { width, height, margin? }). Takes an already-embeddedPDFImage.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 underrenderFlow. Cells can be plain nodes or{ content, colSpan?, padding?, background?, border?, borderSides?, borderRadius?, align?, valign? }.
AcroForm fields
Form widgets are atomic layout nodes, so they work inside stacks, tables, pagination, and streamed documents without manual page coordinates.
textField({ name, width, height, ... }). Supports an initialvalue,multiline,password,maxLength,combed, alignment, and shared field flags and appearance options. Password text fields are non-exportable by default unlessexported: trueis explicitly set.checkbox({ name, width, height, checked? }).radioOption({ name, option, width, height, selected? }). Nodes with the same name form one radio group.dropdown({ name, options, width, height, selected?, editable?, sorted? }). Kept single-select for consistent viewer behavior.optionList({ name, options, width, height, selected?, multiselect?, sorted? }).button({ name, label, width, height, ... }). Creates a portable push-button widget and appearance; BoxPDF does not attach PDF JavaScript or submit actions. Standard SubmitForm actions are reader-dependent and browser viewers may block submissions from local PDFs by origin policy.
All fields accept margin, alignSelf, readOnly, required, exported, hidden, backgroundColor, borderColor, and borderWidth. Text-bearing fields also accept font, fontSize, and textColor. Field names are document-global. Reusing a name adds another widget for the same logical field; reusing it for a different field type throws. Password text fields default to exported: false, so mark exported: true to permit submission/export intentionally. Forms work with ordinary, streamed, and encrypted output; use the encryption fillForms permission to control whether conforming readers allow changes.
For shared logical fields, text, dropdown, and option-list initialization state (value, options, and initial selected) is fixed by the first node. Radio-group flags (offToggleable, mutuallyExclusive) are also first-node-only. selected: true on a radioOption marks that option, while selected: false does not clear any existing selection.
Use getFormValues(pdf), setFormValues(pdf, values), and flattenForm(pdf) when working with a caller-owned PDFDocument. When updating non-WinAnsi text, pass the embedded font as { font } to setFormValues or flattenForm so pdf-lib regenerates the appearances with that font.
AcroForm widgets are PDF annotations rather than page drawing operations. They therefore cannot be placed inside transformed BoxPDF ancestors; BoxPDF throws instead of emitting a misplaced widget. XFA, signature fields, PDF JavaScript, and cryptographic signing are outside the core form layer.
Rendering
flowToPdf(build, options?). The shortest path to bytes. Creates aPDFDocument, hands it to yourbuild(pdf)callback (embed fonts/images there and return the top-level nodes), paginates withrenderFlow, and returns the savedUint8Array. SameoptionsasrenderFlow.renderFlow(pdf, nodes[], options). Paginates a sequence of top-level children. Top-levelvstacknodes may fragment between children;table()fragments between rows and repeats headers on continuation pages. UsekeepTogether()orbreakInside: "avoid"for atomic blocks. Options:size,margin,header?,footer?,reserveBottom?,title?,author?,subject?,keywords?,creator?,producer?,debug?,warnings?,profile?. Headers and footers receive{ pageNumber, totalPages }. Defaults to LETTER (612×792). Pass{ size: PageSizes.A4 }for A4. When a top-level child's measured width exceeds the page content area, boxpdf emits aconsole.warn. Suppress withwarnings: false.savePdf(pdf, options?). Save a caller-owned document, optionally with password encryption. Callingpdf.save()directly always remains pdf-lib's unencrypted behavior.streamFlow(pdf, writable, asyncIterable, options). Incremental page-by-page rendering. Memory stays bounded regardless of page count. Writes PDF bytes to aWritableStream<Uint8Array>as each page closes. See the Streaming section below for the contract.renderToPdf(node, options). One-page convenience.pageInner(size, margin)/pageContent(size, margin). Compute the inner content width or rectangle of a page.render(node, page, x, yTop, parentWidth). Draws a subtree at a known position on an existingPDFPage.measure(node, parentWidth). Computes intrinsic size independently of rendering.
Pass { debug: true } to outline content boxes in red and margin boxes in orange.
Helpers
standardFonts(pdf, family?). Embed a built-in pdf-lib family ("helvetica"default,"times","courier") and get{ font, bold, italic, boldItalic }back — ready to drop into any theme. These use compact PDF standard-font references.loadFont(pdf, source, options?). Embed a TTF from URL, bytes, base64, or data URL.loadImage(pdf, source). Embed a PNG or JPEG (auto-detected).aspectRatio(ratio, { width })/aspectRatio(ratio, { height }). Derive the missing dimension for fixed-ratio boxes or images.formatCurrency(n, { currency, locale }).Intl.NumberFormatwrapper.defineStyles({ ... }). Typed identity for reusable style bundles.hex("#1f8a4d")/rgb255(31, 138, 77). Color builders.
Loading fonts
Three options.
Bundled bytes via the CLI. Recommended for production.
Generates src/fonts/acme.ts with export const base64 strings. Then:
Bytes ship inside your bundle for immediate local loading.
The built-in Inter weights.
boxpdf/inter re-exports the same Inter subset as raw base64 strings (inter, interBold, interItalic) and as embedInter(pdf, { italic?, tabularFigures? }).
Importing boxpdf/inter loads ~325 KB of font bytes plus @pdf-lib/fontkit. Core-only imports stay on the smaller core bundle.
Pass { tabularFigures: true } to also get tabular-numeral variants for money columns:
Fetch from a URL.
The full TTF gets fetched and subsetted at embed time. On Cloudflare Workers with a warm cache this is fast (~5-15 ms). On a cold cache or in Node you pay the full fetch each time.
loadFont accepts the same { subset?: boolean; features?: { tnum: true } } options regardless of the source. Use features: { tnum: true } to enable tabular numerals.
Password encryption
BoxPDF can write PDF 2.0 password-encrypted output using the Standard Security Handler revision 6 and AES-256. Encryption uses the runtime's Web Crypto implementation and adds no crypto dependency to browser bundles. The implementation is loaded as a separate chunk only when encryption is requested.
For a caller-owned document, save through savePdf:
password is required and cannot prepare to an empty value. ownerPassword is
optional; when omitted, BoxPDF generates and discards a random internal owner
credential. Passwords use SASLprep and may contain Unicode, with a maximum of
127 UTF-8 bytes after preparation. Available permissions are printing,
modify, copying, annotate, fillForms, and assemble.
PDF permissions are advisory viewer settings, not DRM. Send the password by a different channel from the PDF. Encryption cannot be combined with PDF/A, and BoxPDF does not decrypt input PDFs or preserve existing signatures. Saving the same document again creates fresh keys, salts, file identifiers, and IVs.
Streaming output
For long-running document generation, use streamFlow instead of renderFlow. It emits PDF bytes to a WritableStream<Uint8Array> as each page closes. Peak heap is bounded at O(shared resources + one page in flight) regardless of total page count.
For Node, adapt a stream.Writable:
If one logical stack or table is too large to construct at once, emit bounded
pieces with flowContinuation. Adjacent pieces with the same id are paginated
as though they were one node, including stack gaps, decoration, table headers,
and row dividers:
Continuation fragments must be consecutive and the last one must set
final: true; streamFlow rejects interrupted or unfinished sequences instead
of silently producing an incomplete layout.
Contract
- All
embedFont/embedJpg/embedPngcalls must complete beforestreamFlow. Embedding mid-stream throws. - The iterable is consumed one node at a time. Pass a generator.
streamFlowtakes exclusive ownership of the writable, closing it on success and aborting it on failure.- Streaming headers and footers receive
ctx.pageNumber. UserenderFlowfor headers or footers that display "Page X of Y"; accessingctx.totalPagesduring streaming throws. - Output is 0-5% larger than
renderFlow's defaultsave().
Memory bench
Peak heap during render. Each measurement runs in its own subprocess. 50 lines of text per page. @react-pdf/renderer included for shape comparison.
streamFlow holds peak heap roughly flat (12 → 25 MB across a 100× workload increase). renderFlow scales roughly linearly with page count. @react-pdf/renderer adds ~2.3 MB per page in this workload and peaks at 2.3 GB by 1000 pages. See docs/design/streaming.md for the design and the chart.
The continuation path has its own heap-capped subprocess check. Unlike the older comparison above, it constructs every fragment lazily and forces a GC after output to distinguish V8's allocation high-water mark from the retained live set:
Both runs complete with --max-old-space-size=128. Across the 10× workload,
the retained heap grows by about 10 MB, primarily from the final page tree and xref
index; rendered page content and continuation input are released incrementally.
Reproduce it with pnpm memory:check:continuation.
Cloudflare Workers
Both the core and the boxpdf/inter subpath run on Workers without nodejs_compat.
Examples
Runnable scripts in examples/:
receipt.ts. Single-page receipt with totals.itinerary.ts. Two-band travel itinerary.invoice.ts. Multi-page invoice with running header and footer pluskeepTogether.debug.ts. Layout with{ debug: true }.themes-showcase.ts. The same receipt rendered in all four themes.inter-showcase.ts. Clean theme rendered with Inter.flex-shrink.ts. Three URL-overflow behaviors side by side.hanging-indent.ts. ParagraphpaddingLeftplus negativetextIndentfor list markers.overflow-clipping.ts. Clipped cards with absolute overlays and background images.
Flex-shrink
Opt-in via shrink: number on any child of an hstack or vstack. When the sum of children's intrinsic main-axis sizes exceeds the parent's available space, items with shrink > 0 give up shares proportional to shrink × baseSize. Items with shrink = 0 (the default) are frozen.
Behavior:
- A text child's minimum width equals its widest whitespace-separated word. Wrapping occurs at whitespace boundaries.
- A single-token string (URL, hash, slug) preserves its intrinsic width and visibly overflows its slot. Two opt-ins lower the floor:
maxLines: N. The engine ellipsizes overflow. The text shrinks to its slot and trims with….breakWords: true. CSSoverflow-wrap: break-word. Hard-breaks at character boundaries.
- When shrunk text rewraps to more lines, the container's intrinsic height grows accordingly.
- When one item hits its min-word floor, its remaining shrink weight redistributes to siblings.
- Works on
vstacktoo when the parent has a fixedheightsmaller than the sum of children. linkforwards its child's shrink weight, so linked text shrinks and re-wraps like bare text.
See examples/flex-shrink.ts.
Absolute positioning
Boxes can use a small CSS-like positioning model:
Behavior:
- Any positioned box establishes the containing block for absolute descendant boxes.
position: "absolute"removes avstackorhstackfrom normal stack flow.- Absolute boxes render after normal children, so they can be used for stamps, badges, overlays, and watermarks.
top,right,bottom, andleftare point offsets from the nearest positioned ancestor, falling back to the currentrender()root.- If both
leftandrightare set andwidthis omitted, the box stretches to the remaining width.topplusbottomdoes the same for height. - Absolute siblings render by
zIndexfrom low to high. Boxes with the samezIndexkeep document order. - Parent measurement, gaps, flex grow/shrink, and pagination ignore absolute boxes. Give the containing box a fixed
widthandheightwhen you need stable placement.
Limitations
- Positioning supports relative containing boxes, out-of-flow absolute boxes, point offsets,
zIndex, and stretch from paired edges. - Font shaping follows pdf-lib and fontkit support. Complex Indic, Arabic, and Thai scripts require a HarfBuzz-based stack; available HarfBuzz stacks currently target runtimes beyond Cloudflare Workers.
streamFlowsupports incremental generation. PDF linearization (reordering the byte stream so byte 1 is page 1) remains a separate post-process.
License
MIT © Erik Aronesty
来源:README.md,提交 25ebd3b
工具
0版本历史
1- v1.0.3最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分
其他 Captcha 集成

captcha.cc Human Verification
cc.captcha官方发布者
面向 captcha.cc 的远程 MCP 服务器,帮助助手生成 CAPTCHA 集成代码片段,并创建实时挑战用于测试。

CaptchaNo
由 GitHub 账号 DishantSinghDev2 发布
CaptchaNo MCP 服务器让 AI 助手通过付费打码服务解决 reCAPTCHA v2/v3/Enterprise、Turnstile、DataDome 和图片验证码。

rea-captcha
由 GitHub 账号 masakaai 发布
一个本地 stdio MCP 服务器,在代理已有的浏览器会话中检测 CAPTCHA 验证挑战,并协调授权完成或人工接管,然后恢复原任务。

Capmonster Mcp Patchright Captcha Solver
由 GitHub 账号 CapMonsterCloud 发布
隐身浏览器自动化 MCP 服务器,提供 66 个工具,用于页面导航、内容提取以及会话、Cookie 和配置文件管理。

Capmonster Mcp Captcha Solver
由 GitHub 账号 CapMonsterCloud 发布
让 AI 助手向 CapMonster Cloud 提交验证码求解任务并轮询结果,覆盖 reCAPTCHA、Turnstile 等反机器人挑战。