Skip to content

Generate your first PDF with NextPDF Connect

This recipe gives you the shortest path from an empty session to a rendered PDF with NextPDF Connect. You create a single-page A4 document, add a heading and a subtitle, then return the file as base64. Three Core tools do the work: create_pdf, add_text, and output_pdf. You do not need fonts, images, or a licensed tier.

A Connect transport sends each tool call as a request and returns the tool’s result as a response. The transport layer is independent of the result reported by the tool (PSR-18 §p2).

Install NextPDF Server and bind a transport:

Terminal window
composer require nextpdf/server

Run the server with the transport your host expects: Model Context Protocol over stdio, REST, or gRPC. See Transport availability below. The tools in this recipe are Core tools. They ship with the server, so you do not need a Pro or Enterprise package.

A Connect session is a server-side document store keyed by a document_id. create_pdf opens a session and returns the id. Each later tool call uses that id. The document starts with one blank page. The page tree is the structure a reader uses to reach each page (ISO 32000-2 §7.7.3). output_pdf renders the session to a PDF. By default, it then destroys the session to free memory.

When you call add_text without an explicit x or y, the text flows into place. It starts at the current cursor, and the cursor advances after each call.

The tool registry resolves these tools when the server starts. The names shown here are the registry’s protocol names. The catalog of record is the merged tool catalog. Available tools depend on the installed tier, but these three are always present in Core.

ToolRoleRisk tier
create_pdfOpen a document sessionSafe
add_textWrite text into the documentCaution
output_pdfRender and return the PDFApproval Required (file mode) / Review (base64)

The host makes three tool calls. In order:

  1. Call create_pdf with page_size: "A4", orientation: "portrait", and the document title and author. The server returns a document_id.
  2. Call add_text with that document_id, the heading text, a large font_size, width: 0 (the full content width), and alignment: "center".
  3. Call output_pdf with the document_id. With no file_path, the server returns the PDF as base64 and destroys the session.

Here is a minimal create_pdf argument object:

{
"page_size": "A4",
"orientation": "portrait",
"title": "Hello World",
"author": "NextPDF Cookbook"
}

The response includes the document_id, the page count, and the page geometry. Treat the id as an opaque value, and do not infer meaning from it.

A production caller checks each response before making the next call. It never reuses a document_id after output_pdf has destroyed the session.

  1. create_pdf — confirm the response contains a document_id. If the server returns the session-limit error, release unused sessions and try again.
  2. add_text (heading) — confirm the response returns a position.
  3. add_text (subtitle) — use a smaller font_size; the cursor continues below the heading.
  4. output_pdf — read the base64 field and decode it to bytes. The destroyed flag confirms the session is gone.

The file comes back inline (base64 mode), so there is no filesystem side effect and no human approval gate. See HITL risk tier.

  • Destroyed session. After output_pdf runs with the default destroy: true, the document_id is no longer valid. Any later call that uses it returns an unknown-document error. Create a new session instead.
  • Unknown page size. The server rejects a page_size it does not recognise, and returns a clear error. Use a documented size (A3, A4, A5, A6, Letter, Legal, Tabloid).
  • Empty text. An empty text produces a zero-width entry, not an error. Check your input before the call.
  • Session limit. The in-memory store caps how many sessions run at once. Release sessions promptly with output_pdf.

A text-only single page renders well within the page budget, and the output is usually 1–3 KB. This recipe uses the double-render reproducibility profile structural. The PDF carries a trailer /ID and timestamps that change from run to run, so a structural (normalised) comparison is the accurate one.

The base64 path has no filesystem side effect. The file-output path does have one, and it is gated. See the HITL section. Treat the returned base64 as document content, not as a trusted channel. It is exactly the bytes the tools produced.

StatementSpecClausereference_id
A transport sends a request and receives a response independent of the result.PSR-18§p2
Pages are reached through the document page tree.ISO 32000-2§7.7.3

This recipe describes how the server produces output. It does not assert profile conformance.

Not applicable — all three tools are Core.

TransportAvailableNotes
MCP (stdio)YesTool calls map to MCP tools/call.
RESTYesEach tool is a REST operation; the result is the response body.
gRPCYesEach tool is a unary call.

The tool result is the same across transports; only the framing differs. A non-success result is still a normal response, not a transport failure (PSR-18 §p2).

The server places each tool call on a human-in-the-loop (HITL) risk ladder: Safe (0) → Caution (1) → Review (2) → Approval Required (3). create_pdf is Safe, and add_text is Caution. output_pdf is Approval Required, but in base64 mode (no file_path) it drops to Review and runs without a human confirmation. Writing to a file keeps it at Approval Required. See output-approval and the HITL risk tiers reference.

This recipe stays in base64 mode, so the confirmation gate returns the allow envelope:

{ "allowed": true }

The challenge envelope (allowed: false, with a challenge string and a single-use token) is documented in output-approval.