DocuGenerate MCP Server
by hasankhadra
README.md
# DocuGenerate MCP Server
A local [Model Context Protocol](https://modelcontextprotocol.io) server that wraps the
[DocuGenerate](https://docugenerate.com) document-generation API, so **Claude Desktop can
generate documents (invoices, contracts, letters) from your templates** — just by asking.
This is a **local demo build**: TypeScript, the official MCP SDK, and **STDIO** transport.
You register it in Claude Desktop and it runs on your machine.
> The productionised “official” version would instead be a **remote HTTP MCP server with
> OAuth** — this local stdio build is deliberately the demo shape.
## Tools
| Tool | Args | Returns |
| --- | --- | --- |
| `list_templates` | *(optional)* `name_contains` | Each template's `id`, `name`, and `merge_fields` (the tags to supply). |
| `get_template_fields` | `template_id` | Merge fields for one template (fallback / double-check). |
| `generate_document` | `template_id`, `data` (object of field→value), `format?` = `pdf` \| `docx` (default `pdf`) | A **hosted URL** to the generated document (a link, not binary). |
## How it maps to the DocuGenerate API
Confirmed against the [API Quick Start](https://docugenerate.com/developers/quickstart) and
live probes of `api.docugenerate.com`:
- **Base URL:** `https://api.docugenerate.com/v1`
- **Auth header:** `Authorization: <API Key>` — the **raw key**, no `Bearer ` prefix.
- `GET /template` → list templates (each has `id`, `name`, `tags.valid` = merge fields)
- `GET /template/{id}` → one template
- `POST /document` with `{ template_id, data: [ {...} ], output_format: ".pdf" }` → responds
with `document_uri` (the hosted document link).
## Setup
Requires **Node 20+**.
```bash
npm install
npm run build # compiles to dist/ via tsc
```
Get your API key from the DocuGenerate **Settings** page (<https://app.docugenerate.com>).
> **Before the demo:** create at least one template in the DocuGenerate dashboard —
> for the prompts below, make an **“Invoice”** template with merge tags such as
> `Company Name`, `Invoice Number`, `Date`, `Due Date`, `Line Items`, and `Total`.
> `list_templates` will report each template's exact merge fields.
### Register in Claude Desktop
Edit `claude_desktop_config.json`:
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
Add this server (use the **absolute** path to the built `dist/index.js`):
```json
{
"mcpServers": {
"docugenerate": {
"command": "node",
"args": ["/absolute/path/to/DocuGenerate-mcp/dist/index.js"],
"env": {
"DOCUGENERATE_API_KEY": "your_api_key_here"
}
}
}
}
```
Then **fully quit and reopen Claude Desktop**. The `docugenerate` tools appear under the
🔌 / tools menu.
## Demo prompts
Once registered, try these in Claude Desktop:
1. **“List my DocuGenerate templates.”**
2. **“Generate an invoice from the Invoice template for Acme Corp — 3 line items:
Design $1200, Development $3400, Hosting $200 — due in 30 days.”**
3. **“Now generate the same as a DOCX.”**
Claude will call `list_templates` to discover the Invoice template and its fields, then
`generate_document` (PDF, then DOCX) and hand you back the document URLs.
## Local testing (without Claude Desktop)
You can drive the server over stdio directly. Set the key and run the smoke test:
```bash
export DOCUGENERATE_API_KEY=your_api_key_here
npm run build
node dist/index.js # server waits for MCP JSON-RPC on stdin; Ctrl-C to exit
```
A quick end-to-end `generate_document` smoke test (replace `TEMPLATE_ID` with a real id from
`list_templates`):
```bash
export DOCUGENERATE_API_KEY=your_api_key_here
TEMPLATE_ID=your_template_id node --input-type=module -e '
import { spawn } from "node:child_process";
const srv = spawn("node", ["dist/index.js"], { env: process.env });
let buf = "";
srv.stdout.on("data", d => { buf += d.toString();
for (const line of buf.split("\n")) { if (!line.trim()) continue;
try { const m = JSON.parse(line);
if (m.id === 2) { console.log(m.result.content[0].text); srv.kill(); process.exit(0); }
} catch {} }
});
srv.stderr.on("data", d => process.stderr.write("[srv] " + d));
const send = o => srv.stdin.write(JSON.stringify(o) + "\n");
send({ jsonrpc:"2.0", id:1, method:"initialize", params:{ protocolVersion:"2024-11-05", capabilities:{}, clientInfo:{ name:"cli", version:"0" } } });
send({ jsonrpc:"2.0", method:"notifications/initialized" });
send({ jsonrpc:"2.0", id:2, method:"tools/call", params:{ name:"generate_document",
arguments:{ template_id: process.env.TEMPLATE_ID,
data: { "Company Name": "Acme Corp", "Total": "$4,800" }, format: "pdf" } } });
setTimeout(() => { srv.kill(); process.exit(1); }, 15000);
'
```
## Error handling
Every tool returns a readable error instead of crashing. Failures surface the HTTP status
and the DocuGenerate error body, with a hint for the common cases:
- **401 / 403** → “check that `DOCUGENERATE_API_KEY` is set to a valid key…”
- **404** → “the `template_id` may be wrong or deleted. Use `list_templates`…”
- **429** → “rate limit hit; wait a moment and try again.”
- Network/DNS/TLS failures and non-JSON responses are also caught and reported.
## Troubleshooting
- **`generate_document` returns a 500 “Cannot read properties of undefined (reading 'length')”.**
This is a DocuGenerate-side error that means the *template* file is malformed — a
hand-assembled `.docx` missing the standard Office parts (`styles.xml`, `settings.xml`,
etc.) will upload fine but fail at render time. Fix: author the template in **Microsoft
Word / Google Docs** (or upload it through the DocuGenerate dashboard) so it's a complete
`.docx`, then re-upload. A normal Word-authored invoice template works.
## Configuration
| Env var | Required | Default |
| --- | --- | --- |
| `DOCUGENERATE_API_KEY` | ✅ | — |
| `DOCUGENERATE_BASE_URL` | — | `https://api.docugenerate.com/v1` |
## License
MIT
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues