NextPDF Connect quickstart
At a glance
Section titled “At a glance”This page runs the smallest useful exchange against both transports: Model Context Protocol (MCP) and Representational State Transfer (REST). Each request uses the exact wire format the server implements. You do not need a software development kit (SDK).
Install
Section titled “Install”composer require nextpdf/serverConceptual overview
Section titled “Conceptual overview”The MCP transport uses JSON-RPC 2.0 over standard input and output. You
must send the sequence in order. First send initialize. Then send the
notifications/initialized acknowledgement. Then send tools/list and
tools/call. The server reads one JSON message per line. Each line must
end with a newline. The server writes one response per line.
The REST transport exposes the same engine capabilities as Hypertext
Transfer Protocol (HTTP) operations. A single stateless render is one
POST /api/v1/render with an ordered operations array. The response body
is the Portable Document Format (PDF) file.
Code sample — Quick start (MCP over stdio)
Section titled “Code sample — Quick start (MCP over stdio)”Start the server, and pipe the handshake into it. These three requests use the verified method names that the protocol handler routes:
./vendor/bin/nextpdf-mcp <<'EOF'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"quickstart","version":"1.0.0"}}}{"jsonrpc":"2.0","method":"notifications/initialized"}{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}EOFThe initialize response reports the protocol version 2025-06-18, the
server name NextPDF Connect, and a capabilities.nextpdf block. That
block includes the live tier counts, the runtime tool_count, the risk
model version, and hitl_enabled: true. The tools/list response lists
the exact tools registered for this installation. The notification line
intentionally produces no response.
Now call a safe tool. The diagnostic.doctor tool runs a read-only
environment check. It does not need a document or confirmation:
./vendor/bin/nextpdf-mcp <<'EOF'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"quickstart","version":"1.0.0"}}}{"jsonrpc":"2.0","method":"notifications/initialized"}{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"diagnostic.doctor","arguments":{}}}EOFCode sample — Quick start (REST)
Section titled “Code sample — Quick start (REST)”Start the REST server, then render a one-line PDF. The server requires an application programming interface (API) key on every non-health endpoint, so define one first:
export NEXTPDF_API_KEYS='npk_live_k8a3b2c1_0123456789abcdef0123456789abcdef:demo:core:default'./vendor/bin/rr serve -c .rr.yamlIn a second shell, post a render request. The body is a RenderRequest.
That request contains an ordered operations array of typed operations.
curl -sS -X POST http://localhost:8080/api/v1/render \ -H 'Authorization: Bearer npk_live_k8a3b2c1_0123456789abcdef0123456789abcdef' \ -H 'Content-Type: application/json' \ -d '{ "page_size": "A4", "orientation": "portrait", "operations": [ { "type": "add_text", "text": "Hello from NextPDF Connect" } ] }' \ --output hello.pdfA 200 response body is the PDF (Content-Type: application/pdf) written
to hello.pdf. Health probes do not need a key:
curl -sS http://localhost:8080/healthzEdge cases and gotchas
Section titled “Edge cases and gotchas”-
The handshake order matters. The protocol handler treats a message with no
idas a notification and returns nothing. Sendinitializewith anid, then theinitializednotification, then your requests that include anid. -
A repeated request
idis de-duplicated. The handler caches recent responses in a 64-entry circular buffer. For a duplicateid, it returns the cached response without running the tool again. Use fresh ids. -
A high-risk tool answers with a challenge, not a result. Calling
output_pdfwith afile_pathreturns a confirmation challenge instead of running. Re-invoke the tool with the issued_confirmation_token. The base64 output mode, withoutfile_path, does not require confirmation. See /connect/hitl-risk-tiers/. -
An unauthorized REST request gets
401. A missing or malformedAuthorization: Bearerheader returns a problem-details body with aWWW-Authenticate: Bearerheader. The/healthzand/readyzprobes are the only anonymous endpoints.
Performance
Section titled “Performance”Both quickstart paths use a single request. The REST path also pays the
RoadRunner worker pool’s cold-start cost on the first request after
rr serve. Later requests reuse warm workers.
Security notes
Section titled “Security notes”The npk_live_ key above is a throwaway demo value. Generate real keys
with sufficient entropy, store them outside source control, and prefer the
file-based key store for rotation. The MCP stdio transport has no API key
because it is a local subprocess trusted by its launching client under the
MCP transport model. See /connect/security-and-operations/.
Conformance
Section titled “Conformance”The wire formats shown match the implemented MCP revision 2025-06-18 and
the OpenAPI 3.1 REST contract. Normative protocol and authentication
citations are pinned on /transports/mcp/, /transports/rest/, and
/connect/security-and-operations/.
See also
Section titled “See also”- /transports/mcp/ — the full MCP transport reference
- /transports/rest/ — the full REST transport reference and OpenAPI rendering
- /connect/tool-catalog/ — which tools
tools/listreturns and why - /connect/hitl-risk-tiers/ — what a confirmation challenge looks like
- /connect/configuration/ — restricting the catalog and tuning the server