mcp server
DocumentKit
Secure, high-throughput webpage-to-PDF and screenshot service with HTTP and MCP interfaces
Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- Node.js 20 or newer
{
"mcpServers": {
"documentkit": {
"command": "npx",
"args": [
"-y",
"@crossdo/documentkit"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 25, 2026DocumentKit
Secure, high-throughput webpage-to-PDF and screenshot service for Node.js. DocumentKit exposes the same rendering core through a REST API, MCP Streamable HTTP, and MCP stdio.
Status: early development (
0.x). APIs may change before1.0.
Features
- Render a URL or HTML string to PDF
- Capture PNG, JPEG, or WebP screenshots
- Memory-only output: generated documents are never persisted by DocumentKit
- Reused Chromium process with isolated browser contexts per request
- Bounded concurrency, queue backpressure, timeouts, and output limits
- SSRF protection for navigations, redirects, and subresources
- REST, MCP Streamable HTTP, and MCP stdio interfaces
- OpenAPI documentation and Docker support
- Reserved
ArtifactStoreinterface for future disk or object-storage adapters
Requirements
- Node.js 22 or newer
- macOS or Linux supported by Playwright
The npm package downloads a compatible Chromium automatically, so no separate browser installation is normally required.
Install Node.js and Playwright
-
Install Node.js 22 or newer from the Node.js download page or with a Node.js version manager, then verify the installation:
node --version npm --version -
Install the project dependencies from the repository root:
npm installThis installs
playwright-coreand downloads the compatible Chromium build through@playwright/browser-chromium. Do not install Playwright globally. -
On Linux, install Chromium's operating-system dependencies if they are not already available:
sudo npx playwright-core install-deps chromium
If browser downloading was disabled during npm install (for example, with PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1), download Chromium afterward with:
npx playwright-core install chromium
Quick start
npx --yes @crossdo/documentkit serve
The server listens on all interfaces (0.0.0.0:3000) by default. From the same machine, use:
- REST:
http://127.0.0.1:3000/v1 - MCP:
http://127.0.0.1:3000/mcp - OpenAPI UI:
http://127.0.0.1:3000/docs - Health:
http://127.0.0.1:3000/health/live
Deploy with PM2
Install DocumentKit locally, then use PM2 to keep it running:
mkdir -p ~/documentkit
cd ~/documentkit
npm init -y
npm install @crossdo/documentkit
npm install --global pm2
pm2 start ./node_modules/.bin/documentkit --name documentkit -- serve
Configure automatic startup after a server reboot. Run the command printed by pm2 startup, then save the current process list:
pm2 startup
pm2 save
Common operations:
pm2 status
pm2 logs documentkit
pm2 restart documentkit
pm2 stop documentkit
Update DocumentKit and restart it:
cd ~/documentkit
npm install @crossdo/documentkit@latest
pm2 restart documentkit
pm2 save
The service is network-accessible without authentication by default. Restrict port 3000 to trusted source addresses with a firewall or cloud security group. Configure DOCUMENTKIT_API_KEY when authentication is required.
Render HTML to PDF:
curl -sS http://127.0.0.1:3000/v1/pdf \
-H 'content-type: application/json' \
-d '{"html":"<!doctype html><h1>Hello from DocumentKit</h1>"}' \
--output document.pdf
Capture a webpage screenshot:
curl -sS http://127.0.0.1:3000/v1/screenshots \
-H 'content-type: application/json' \
-d '{"url":"https://example.com","screenshot":{"fullPage":true}}' \
--output screenshot.png
CLI
documentkit serve [--host 0.0.0.0] [--port 3000] [--api-key TOKEN]
documentkit mcp
documentkit doctor
For MCP stdio configuration:
{
"mcpServers": {
"documentkit": {
"command": "npx",
"args": ["--yes", "@crossdo/documentkit", "mcp"]
}
}
}
HTTP API
POST /v1/pdf
{
"url": "https://example.com",
"page": {
"waitUntil": "load",
"viewport": { "width": 1440, "height": 900, "deviceScaleFactor": 1 }
},
"pdf": {
"format": "A4",
"printBackground": true,
"landscape": false
}
}
POST /v1/screenshots
{
"html": "<!doctype html><h1>Hello</h1>",
"screenshot": {
"type": "png",
"fullPage": true,
"scale": "css"
}
}
Exactly one of url and html is required. Responses are raw binary data with Cache-Control: no-store. DocumentKit does not write generated output to disk.
See API documentation, MCP documentation, and configuration.
Security
DocumentKit listens on all interfaces without authentication by default. This is convenient for trusted private networks, but port 3000 must be restricted with a firewall or cloud security group. Set an API key to require bearer authentication:
DOCUMENTKIT_API_KEY='replace-with-at-least-16-random-characters' \
npx --yes @crossdo/documentkit serve
Private, local, reserved, and link-local rendering targets remain blocked. An application-level URL filter cannot replace an operating-system or container egress firewall. Production deployments should deny private network destinations at the network layer as well. Read SECURITY.md and the security model before exposing the service.
Performance model
DocumentKit starts one Chromium process and reuses it. Each render receives a fresh, isolated browser context which is closed after completion. A bounded queue prevents unbounded memory growth:
- concurrency: 4 jobs
- waiting queue: 32 jobs
- job timeout: 180 seconds
- output limit: 100 MiB
- MCP inline limit: 5 MiB
- declared network budget: 200 MiB per page
Chromium disk and media caches are minimized. Application output remains in memory and is released after the response. Tune concurrency based on available RAM; Chromium-heavy jobs commonly need substantially more memory than their final PDF size.
Development
npm install
npm run check
npm run dev
See CONTRIBUTING.md.