Does the printed content leave my machine?
No. The MCP server, client, PDF rendering and print queue all run locally; only the initial npx package download needs the network. Nothing is uploaded and there is no cloud relay.
Once the Web Print Expert client is installed, add one stdio MCP server to your AI host and the model can print HTML, web pages, PDFs and images straight to a local printer. It changes neither the client nor the web-print-pdf browser library — it just attaches another client to the local port the client already exposes.
Three hops, all on your own machine, with no cloud relay:
npx -y mcp-web-print-pdf over stdio.AI host (Claude / Cursor / dsh)
| stdio: npx -y mcp-web-print-pdf
v
mcp-web-print-pdf
| ws://127.0.0.1:16794/websocket/standard
v
Web Print Expert client --> printerdry_run: true when you only want to check the layout.An unlicensed real print returns Not allowed to use, please purchase authorization; make sure the client is signed in and licensed first.
16794). Not yet? Download the client.npx, so no global install is needed; the package is on npm.Open the client and confirm it is running and the port is free. Once the host is connected, the first tool to call is getConnectStatus.
Every host runs the same stdio command; only the config file location and top-level key differ:
{
"mcpServers": {
"webprint": {
"command": "npx",
"args": ["-y", "mcp-web-print-pdf"],
"env": { "WEBPRINT_PORT": "16794" }
}
}
}dsh uses a YAML insert instead — different shape, same fields:
- insert:
- id: mcp-webprint
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: webprint
transport: stdio
command: npx
args:
- '-y'
- 'mcp-web-print-pdf'
toolCallTimeoutMs: 180000Restart the host and check its MCP panel reports the server as connected. Tool names are namespaced on the model side, e.g. mcp__webprint__printHtml. Call getConnectStatus first, then printHtml with dry_run: true to see whether a preview is generated.
The client port defaults to 16794 and can be overridden with WEBPRINT_PORT; the WebSocket request timeout defaults to 120 s and can be overridden with WEBPRINT_TIMEOUT (milliseconds).
Config formats follow each host current docs; the table below is for locating the file quickly.
| Host | Config location | Top-level key |
|---|---|---|
| Claude Desktop | %APPDATA%\Claude\claude_desktop_config.json | mcpServers |
| Cursor | ~/.cursor/mcp.json or project .cursor/mcp.json | mcpServers |
| dsh | ~/.dsh/profiles/<profile>/cordis.patch.yml | insert (YAML) |
| Claude Code | claude mcp add --scope user webprint -- npx -y mcp-web-print-pdf | written by the CLI |
| VS Code + Copilot | .vscode/mcp.json | servers |
| OpenAI Codex CLI | ~/.codex/config.toml | mcp_servers (TOML) |
| Cline / Roo / Kilo | cline_mcp_settings.json | mcpServers |
| Cherry Studio / Trae | Add a STDIO server in the settings panel | GUI |
Tool names map one-to-one onto web-print-pdf@2.x methods (the utils. prefix cannot appear in a tool name, so it is dropped).
| Tool | What it does | Notes |
|---|---|---|
getConnectStatus | Check whether the client is online | Probe first, before printing |
getPrinterList | List local printers (name + driver) | Use it to get an exact printer_name |
getPrinterPapers | List paper sizes a printer accepts | Fills paper_format / print_options.bin |
printHtml | Print an HTML string | Most used; fragments and full pages both work |
printHtmlByUrl | Fetch a page, then print it | Accepts cookies / httpHeaders |
printHtmlByBase64 | Print Base64-encoded HTML | Subject to the 10 MB message cap |
printPdfByUrl | Print a PDF URL | The client downloads it first |
printPdfByBase64 | Print a Base64-encoded PDF | Roughly under 5 MB |
printImageByUrl | Print an image URL | — |
printImageByBase64 | Print a Base64-encoded image | Bare base64 gets the data-URI prefix added |
printFile | Print a local .pdf / .html / image by path | Extra tool in this repo; bypasses the stdio message cap |
batchPrint | Submit several mixed jobs at once | Every task action must match |
| Tool | What it does | Notes |
|---|---|---|
setTitle | Set the client window title | reset: true restores defaults |
setThemeColor | Set the client theme color | |
switchTabsVisibility | Show or hide client tabs | |
setContactUsTabInnerHtml | Set the content of the Contact Us tab |
The three option objects map onto the upstream arguments: pdf_options and print_options go through the client whitelist (unknown field names fail loudly), while extra_options accepts any custom keys and echoes them back.
Merge rule: fields you set explicitly win, convenience arguments only fill gaps.
| MCP argument | Upstream | Notes |
|---|---|---|
| content field | first argument | html / url / base64 / path / tasks |
pdf_options | pdfOptions | PDF layout: paper, margins, header/footer, watermark, page numbers, background |
print_options | printOptions | Printer delivery: printer name, copies, duplex, scaling, bin, thermal sharpening |
extra_options | extraOptions | action, requestTimeout, cookies, httpHeaders, localStorages |
dry_run | — | Convenience flag: true renders a preview only; omit it to print |
paper_format / printer_name / copies | — | Convenience arguments, equivalent to the same print_options fields |
printFile or a URL.toolCallTimeoutMs).pdf_options.paperFormat. It only accepts a fixed enum (A0–A6 / Letter / Legal / Tabloid / Ledger); for 80 mm receipts or 100×150 labels use width + height.{ type, data, pdfOptions?, printOptions?, extraOptions? } — content goes in data, not content / url / base64.printFile casually. It reads any local path the model names, so only enable it in trusted environments.print_html, list_printers); since 0.2.0 the names match the upstream camelCase methods and the old ones no longer exist.getConnectStatus — continue only when the client is online.getPrinterList — confirm the target printer names the model sees are the ones you expect.printHtml with dry_run: true — a preview or PDF URL in the response means the render path works.Get-PrintJob on Windows) instead of trusting the tool response alone.No. The MCP server, client, PDF rendering and print queue all run locally; only the initial npx package download needs the network. Nothing is uploaded and there is no cloud relay.
No. Those only accept remote HTTP MCP servers, while this project ships a local stdio server. Using them would require your own HTTP bridge in between.
One-to-one mapping: public APIs such as printHtml, batchPrint and utils.getPrinterList all have same-named tools, with arguments reshaped as MCP JSON. printFile is the one addition (print by local path).
Check the printer for paused, offline or empty-paper states, which leave the job stuck in the OS queue. Then confirm licensing: an unlicensed real print returns NOTALLOWUSE.
The MCP server itself is an MIT-licensed open-source package with no extra fee; actual printing still depends on your Web Print Expert client licence. To verify the wiring first, pass dry_run: true to render a preview.
The same web-print-pdf front-end runs on Windows, macOS, and Linux/domestic OS—install the matching client on each desktop.