Summary
Swap the current render_html implementation — which renders an HTML snippet to PNG via headless Chromium — for a subprocess calling WeasyPrint.
Motivation
Headless Chromium is heavy for what the harness actually needs:
- ~300MB+ Chromium binary bundled/installed on the VPS.
- High cold-start cost and memory footprint per render.
- Overkill when the rendered content is static (tables, charts, diagrams).
WeasyPrint is a pure-Python HTML/CSS rendering engine (backed by Pango/cairo). Running it in a subprocess keeps the render isolated from the main process and avoids the browser entirely — much lighter, faster startup, lower memory. A good fit for a small VPS.
Proposed change
- Replace the Chromium render path with a subprocess that invokes WeasyPrint on the HTML snippet and writes a PNG to
data/renders/.
- Subprocess isolation: a bad render can't take down the harness; enforce a timeout.
- Keep the
render_html MCP tool signature unchanged (html, width, height, title) so nothing upstream breaks.
Trade-off to confirm before implementing
WeasyPrint does not execute JavaScript. The current setup can run inline JS libs (Chart.js, D3). After this change:
- Pure HTML/CSS + inline SVG renders → fine. The
render-style skill is already CSS/SVG-only, and recent charts were hand-built SVG — these keep working.
- Any render relying on a JS charting lib → would break and must be rebuilt as static SVG/CSS.
If dropping JS rendering is acceptable (it looks like it is, given current usage), WeasyPrint is a clean win. Flagging it so the decision is explicit.
Notes
- WeasyPrint needs system libs (Pango, cairo, gdk-pixbuf) — a deployment/Dockerfile change.
- Confirm WeasyPrint's PNG output path; it's PDF-first, PNG is supported but worth verifying the quality/DPI is acceptable for Telegram photos.
Requested by the owner.
Summary
Swap the current
render_htmlimplementation — which renders an HTML snippet to PNG via headless Chromium — for a subprocess calling WeasyPrint.Motivation
Headless Chromium is heavy for what the harness actually needs:
WeasyPrint is a pure-Python HTML/CSS rendering engine (backed by Pango/cairo). Running it in a subprocess keeps the render isolated from the main process and avoids the browser entirely — much lighter, faster startup, lower memory. A good fit for a small VPS.
Proposed change
data/renders/.render_htmlMCP tool signature unchanged (html, width, height, title) so nothing upstream breaks.Trade-off to confirm before implementing
WeasyPrint does not execute JavaScript. The current setup can run inline JS libs (Chart.js, D3). After this change:
render-styleskill is already CSS/SVG-only, and recent charts were hand-built SVG — these keep working.If dropping JS rendering is acceptable (it looks like it is, given current usage), WeasyPrint is a clean win. Flagging it so the decision is explicit.
Notes
Requested by the owner.