{
  "markdown": "# polydoc-mcp\n\nAn [MCP](https://modelcontextprotocol.io) server for [PolyDoc](https://polydoc.tech), a REST API that converts HTML or URLs to **PDF**, captures **screenshots**, and generates EU-compliant **e-invoices** (Factur-X / ZUGFeRD hybrid PDF/A-3). It lets MCP clients (Claude Desktop, Claude Code, Cursor, and others) drive PolyDoc directly.\n\nPDF output can target **PDF/A** (archival) and **PDF/UA-1** (accessible, ISO 14289-1). Both are best-effort by default; set `verify` on either to validate the result with veraPDF and fail the request instead of returning a non-conforming file.\n\n## Tools\n\n- **`polydoc_html_to_pdf`** - HTML, URL, or saved template to PDF (layout, margins, page format, page ranges, bookmarks, tagged PDFs, PDF/A and PDF/UA conformance).\n- **`polydoc_screenshot`** - HTML, URL, or template to PNG / JPEG / WebP, with viewport and device-pixel-ratio control. Returns an inline image preview when small enough.\n- **`polydoc_generate_einvoice`** - Factur-X or ZUGFeRD hybrid PDF/A-3 from structured invoice data, profiles from `minimum` to `extended`.\n- **`polydoc_test_credentials`** - verify the configured API key with a minimal sandbox render (never draws production quota).\n\nContent can come from a **URL**, an inline **HTML** string, or a saved **template** (with Liquid `templateData`). Downloads are written to a local directory and the file path is returned; you can also deliver to your **cloud storage** (presigned URL) or a **webhook**.\n\n## Installation\n\nRequires Node.js >= 20.15. Published to npm, so clients can run it with `npx`:\n\n```\nnpx -y polydoc-mcp\n```\n\nThe server is configured entirely through environment variables (see below).\n\n## Configuration\n\n| Variable | Required | Default | Description |\n|---|---|---|---|\n| `POLYDOC_API_KEY` | yes | - | API key from [dashboard.polydoc.tech](https://dashboard.polydoc.tech). |\n| `POLYDOC_SANDBOX` | no | `false` | Default sandbox mode (watermarked, rate-limited). A tool call can override per request. |\n| `POLYDOC_BASE_URL` | no | `https://api.polydoc.tech` | Override for self-hosted or staging. |\n| `POLYDOC_OUTPUT_DIR` | no | OS temp dir + `/polydoc` | Where downloads are written. Output never escapes this folder. |\n\n## Client setup\n\n### Claude Desktop\n\nAdd to `claude_desktop_config.json` (Settings > Developer > Edit Config):\n\n```json\n{\n  \"mcpServers\": {\n    \"polydoc\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"polydoc-mcp\"],\n      \"env\": {\n        \"POLYDOC_API_KEY\": \"your-key\",\n        \"POLYDOC_OUTPUT_DIR\": \"/Users/you/Documents/polydoc\"\n      }\n    }\n  }\n}\n```\n\n### Claude Code\n\n```\nclaude mcp add polydoc -e POLYDOC_API_KEY=your-key -- npx -y polydoc-mcp\n```\n\n### Cursor\n\nAdd to `~/.cursor/mcp.json` (or a project `.cursor/mcp.json`) using the same `mcpServers` block shown for Claude Desktop.\n\n## Output and delivery\n\n- **Download** (default): the file is written under `POLYDOC_OUTPUT_DIR` and the absolute path is returned with metadata (size, conversion id, credits). Screenshots also return an inline image block. Pass `returnBase64: true` to also receive the bytes as base64 (heavy; for clients without a filesystem).\n- **Cloud storage**: set `delivery: \"cloudStorage\"` and `presignedUrl`. The upload URL is returned.\n- **Webhook**: set `delivery: \"webhook\"` and a `webhook` object (`{ url, async?, method?, headers? }`).\n\n## PDF/A and PDF/UA\n\n`polydoc_html_to_pdf` takes two conformance targets inside `pdfOptions`:\n\n```json\n{\n  \"pdfOptions\": {\n    \"pdfa\": { \"level\": \"3b\", \"verify\": true },\n    \"pdfua\": { \"verify\": true }\n  }\n}\n```\n\n`pdfa.level` is `1b`, `2b`, or `3b`. Setting `pdfua` forces a tagged render, so you do not need `tagged` as well.\n\nWithout `verify`, output is best-effort: it targets the standard but the request still succeeds if the toolchain cannot satisfy every machine-checkable rule. With `verify: true`, veraPDF validates the result and a non-conforming file fails with **422** instead of being returned. Use it when a downstream system will reject a bad file anyway.\n\n## Anything not in a tool's schema?\n\nEvery conversion tool has an `advanced` object that is deep-merged into the request body, so any API capability not surfaced as a typed field (for example `pdf.watermark`, `pdf.encryption`, `render`, `request`) is still reachable. See the field reference at [docs.polydoc.tech](https://docs.polydoc.tech).\n\n## Examples\n\nWorked tool inputs for each angle live in [`examples/`](./examples): a branded PDF from a template, a URL screenshot, and a ZUGFeRD / EN 16931 e-invoice.\n\n## Development\n\n- `yarn install`\n- `yarn build` - compile to `dist/`\n- `yarn lint`\n- `yarn test` - unit tests (request builder, output jail, tool handlers) and an in-memory MCP round-trip\n- `POLYDOC_API_KEY=your-key yarn test:integration` - live smoke tests against the sandbox\n- `yarn scrub:check` - check for em-dashes in source and docs\n\nRun the built server directly for a quick check:\n\n```\nPOLYDOC_API_KEY=your-key node dist/index.js\n```\n\n## License\n\n[MIT](./LICENSE)\n",
  "bytes": 5001,
  "sha": "e2aa969ac5e39f38de8d51cdbebb639d56201507f6b90b77d806efc9e953de63",
  "repo_slug": "polydoc-tech/polydoc-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_tech_polydoc_polydoc_mcp_ee72e567/readme"
}