cf-rendercv is an HTTP API + MCP server for generating resume PDFs from RenderCV-style YAML or JSON. PDFs are produced inside Cloudflare Workers (workerd): templates use Jinja2-compatible rendering via WASM, and layout is compiled to PDF with Typst WASM modules—no subprocesses and no Docker.
WebAssembly npm packages used in this repo (optimized for workerd):
@jchoi2x/minijinja(^0.0.13) — Jinja2-style templating@jchoi2x/typst.ts(0.7.4)@jchoi2x/typst-ts-renderer(0.7.5)@jchoi2x/typst-ts-web-compiler(^0.7.11)
The apps are:
./apps/http- Cloudflare Worker (Hono)
- MCPAgent (MCP tool/agent wiring)
- hosts an MCP server that registers the
rendercvtool, prompts, and JSON schema resources (see./apps/http/src/durable/mcp/rendercv/) - renders PDFs in the Durable Object using Minijinja + Typst WASM (same pipeline as HTTP)
- Cloudflare Worker (
./apps/http)- Proxies HTTP and MCP traffic to a Durable Object (
RendercvDo) that hosts the Hono app, MCP server, and rendering pipeline. - Rendering: validate RenderCV JSON/YAML → build Typst source (Jinja via Minijinja WASM) → compile PDF with Typst WASM.
- Exposes
POST /api/v3/rendercv/render(PDF) andPOST /api/v3/rendercv/typst(Typst source). Request bodies accept RenderCV as JSON or YAML (see OpenAPI/Swagger).
- Proxies HTTP and MCP traffic to a Durable Object (
This Worker supports using RenderCV in two ways:
- HTTP API:
POST /api/v3/rendercv/renderreturns a generated PDF (application/pdf).POST /api/v3/rendercv/typstreturns Typst source (application/text). Bodies may be RenderCV JSON or YAML. - MCP tool: the Worker registers an MCP tool named
rendercvthat accepts{ content, format }and returns a generated PDF URL (or base64 whenformat: "base64").
The Worker also registers:
- a prompt named
rendercv - a resource at
rendercv://schema-and-promptcontaining the RenderCV JSON schema
The application is deployed at https://rendercv-http.xvzf.workers.dev/ (HTTP API, OpenAPI/Swagger UI, and MCP).
Run the Model Context Protocol Inspector and connect to the deployed MCP server:
npx @modelcontextprotocol/inspector@latestAt a high level, you will:
- node >= 20
- bun >= 1.1.0
The HTTP/MCP server uses Google OAuth for authentication.
To run locally, you must set up a Google OAuth client application in the Google Cloud console: https://console.cloud.google.com/auth/clients/create
After creating the app, configure the resulting GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET for the worker.
-
Install dependencies at the repo root:
bun install
-
Start the cloudflare worker locally from the repo root:
bun run dev:http
-
Send a
POSTrequest tohttp://localhost:<port>/api/v3/rendercv/renderwith your RenderCV JSON or YAML body and save theapplication/pdfresponse. UsePOST /api/v3/rendercv/typstfor Typst source output.
For document structure and field semantics, see the official RenderCV user guide: RenderCV — User guide.
To develop or deploy the Cloudflare Worker in ./apps/http, refer to that app’s own configuration and scripts (e.g., wrangler.jsonc, package.json) for the precise commands.
- Unit tests live next to source under
apps/**/src/**/__tests__/(see.cursor/rules/unit-testing.mdc). From the repo root runbun run test,bun run test:http, orbun run test:unitas documented inpackage.json.
End-to-end checks that exercise the full Typst compilation path (for example a successful POST /api/v3/rendercv/render with a complete RenderCV document) require bun run dev:http or a deployed Worker.
Use the @modelcontextprotocol/inspector tool to debug the MCP server.
npx @modelcontextprotocol/inspector@latestSequence Diagram (HTTP)
Rendering a resume via HTTP request
sequenceDiagram
participant C as HTTP Client
participant W as Worker (edge)
box Blue Durable Object
participant D as RendercvDo (Hono + MCP)
participant J as Minijinja WASM (templates)
participant Y as Typst WASM (compile)
end
C->>W: POST /api/v3/rendercv/render (JSON or YAML)
W->>D: stub.fetch(request)
D->>D: parse + validate RenderCV document
D->>J: build Typst source from templates
J-->>D: Typst document text
D->>Y: compile PDF
Y-->>D: PDF bytes
D-->>W: application/pdf
W-->>C: application/pdf
Sequence Diagram (MCP)
MCP is the Model Context Protocol, a protocol for building agents that can interact with other agents and tools.
sequenceDiagram
participant M as MCP Client (agent)
participant D as RendercvDo (MCPAgent)
participant T as MCP tool: rendercv
participant Y as Typst WASM
participant S as Object storage (S3-compatible)
M->>D: MCP request (/mcp)
D->>T: invoke rendercv (content, format)
T->>D: renderCvTypstPdf (same pipeline as HTTP)
D->>Y: compile PDF
Y-->>D: PDF bytes
rect rgba(33, 66, 99, 0.12)
D->>S: upload PDF for public URL (when format is url)
S-->>D: URL + path
end
T-->>D: tool result (PDF URL or base64)
D-->>M: MCP response
Sequence Diagram (MCP Discovery)
Discovery is the process of the MCP client (agent) discovering the tools, resources, and prompts available on the MCP server.
sequenceDiagram
participant M as MCP Client (agent)
participant D as RendercvDo (MCPAgent durable object)
participant G as GitHub: rendercv/schema.json
M->>D: MCP initialize
M->>D: tools/list
D-->>M: tools include rendercv (input schema: RenderCV JSON)
M->>D: resources/list
D-->>M: resources include rendercv://schema-and-prompt
M->>D: resources/read(rendercv://schema-and-prompt)
D->>G: fetch schema.json
G-->>D: schema.json (raw JSON)
D->>D: parse JSON + JSON.stringify(schema, 2)
D-->>M: resource text (application/json) containing the RenderCV schema
M->>D: prompts/list
D-->>M: prompts include rendercv
M->>D: prompts/get('rendercv')
D-->>M: prompt text with examples/instructions to build content (see rendercv://schema-and-prompt for the full schema)
Note over M,D: Using the tool list + prompt examples + the schema resource, <br/>the LLM knows how to build a valid `content` payload, then calls the MCP tool when the user asks to generate a resume.
M->>D: tool call rendercv { content, format: "url" }

