DocMake

MCP server

Your documents, generated by your AI assistant.

The official DocMake server for the Model Context Protocol. Ask Claude for an invoice in plain language; it picks the template, fills in the blanks (the data payload), and hands you the finished PDF.

It ships on npm as @docmake/mcp and runs locally through npx, so the only requirements are Node.js 18 or newer and a DocMake API key. It works on the free plan, and it gives an assistant six tools: list templates, inspect a template's fields, make a document (render_document), create a template, import a DOCX, and check usage. The source is on GitHub under the MIT license, and the same six tools are also hosted at app.docmake.io/mcp/v1 if you would rather install nothing.

A conversation, not an integration

MCP is the open standard that lets AI assistants use external tools. With the DocMake server installed, your assistant gains six document tools and uses them on its own: it finds the right template, asks you for any missing values, and saves the rendered file to your Downloads folder.

Renders are strict by default. If a blank (a variable in the API) has no value, the assistant gets the exact list of missing fields instead of a half-empty document, so it asks you rather than inventing numbers.

Templates stay in DocMake: design them once in the visual editor or start from the gallery, then render them from anywhere.

Claude
Generate the invoice for Acme Corp: 10 hours of consulting at 100 EUR, due in 14 days.
tool list_templates → Invoice (tmpl_ZjqIJk...)
tool get_template → client_name, items[], due_date...
tool render_document → invoice-acme.pdf
Done. Your invoice for Acme Corp (1,000.00 EUR, due August 23) is saved at ~/Downloads/DocMake/invoice-acme.pdf.

Setup

  1. 01 Create a free DocMake account and add a template: start from the gallery, import a DOCX, or design your own.
  2. 02 Create an API key in Settings → API Keys.
  3. 03 Add the server to your AI tool with the config on the right. Node.js 18+ is the only requirement.

Rendered files are saved to ~/Downloads/DocMake by default; set DOCMAKE_OUTPUT_DIR to change it.

{
  "mcpServers": {
    "docmake": {
      "command": "npx",
      "args": ["-y", "@docmake/mcp@latest"],
      "env": {
        "DOCMAKE_API_KEY": "dm_your_api_key"
      }
    }
  }
}

Settings > Developer > Edit Config, then restart Claude Desktop.

Remote, nothing to install

The same six tools, hosted

DocMake also runs the server for you at https://app.docmake.io/mcp/v1, spoken over streamable HTTP. A client that supports remote MCP needs no package and no Node.js: just the URL and one header, Authorization: Bearer dm_..., carrying the same API key the REST API uses.

Two things differ from the local package, because the server runs on our side rather than on your machine. render_document returns a short-lived download link instead of writing the file to disk, and import_docx takes the document as base64 rather than a path. Strict rendering, workspace scoping and the plan rate limits behave as they do over REST, where one MCP message counts as one request.

Claude.ai and ChatGPT add remote servers as custom connectors, and those are documented around an OAuth flow rather than a static key, so this setup does not reach them yet. For Claude Desktop, use the npx configuration above.

claude mcp add --transport http docmake \
  https://app.docmake.io/mcp/v1 \
  --header "Authorization: Bearer dm_your_api_key"

Adds the server to the current project. Pass --scope user to make it available everywhere.

Side by side

Same six tools, same workspace, same dm_ key. Pick on where you want the work to happen, not on what you get.

Local, @docmake/mcp Hosted, /mcp/v1
Transport stdio, run by your client through npx Streamable HTTP, one POST per message
Requirements Node.js 18 or newer Nothing installed
Auth DOCMAKE_API_KEY in the environment Authorization: Bearer dm_... header
Tools The same six The same six
A rendered file Written to DOCMAKE_OUTPUT_DIR, ~/Downloads/DocMake by default, never overwriting A signed download link that needs no key and expires
import_docx A path on your machine The file base64 encoded, up to 10 MB
Resources and prompts Advertised alongside the tools Tools only, both lists are empty
Version 0.1.1 on npm 0.1.0, reported in the handshake
Rate limit The workspace budget, one call is one request The same budget, one message is one request

Six tools, the full document loop

The same six on both servers, with the same names, the same arguments and the same answers. Everything an assistant needs to go from a request to a rendered file, including creating and importing templates without leaving the conversation.

list_templates

List templates

The templates in the connected workspace, newest edit first, with search and pagination. Start here when you need a template id.

search
string
Filter by name, substring match
page
integer
From 1
per_page
integer
Max 100, default 20

Returns data: id, name, created_at, updated_at, variables_count, render_count. meta: current_page, last_page, per_page, total.

Read only.

get_template

Get template fields

One template plus its field tree: every blank it expects, as dotted keys shaped like the data payload, with list fields carrying their per-item subfields. Call it before rendering.

template_id
string, required
From list_templates
include_schema
boolean
Also return the raw document schema. Default false, can be large

Returns id, name, created_at, updated_at, fields (recursive: key, name, label, type, required, default, example), unused.

Read only. A calculation is an output, so it is in neither list.

render_document

Render a document

Render a template to PDF or DOCX. Answers with a short-lived download link, not the file bytes, and refuses rather than filling a document with gaps.

template_id
string, required
data
object, required
Keys match the template fields
format
pdf or docx
Default pdf
filename
string
Without extension
locale
string
BCP 47, for example ro-RO. Defaults to the workspace setting
page_size
a4 or letter
Defaults to the workspace setting
strict
boolean
Default true

Returns document_id, filename, format, size_bytes, render_time_ms, warnings, download_url, download_expires_at.

Writes. Not idempotent: each call produces a document.

create_template

Create a template

Create a template from a document schema: a rich-text tree with typed blank nodes, rules and repeated sections. The quickest way to learn the format is get_template with include_schema true.

name
string, required
Max 255
schema
object, required
Root must be type "doc" with a content array

Returns id, name, variables, edit_url.

Writes. Counts against the template allowance.

import_docx

Import a DOCX as template

Turn a Word document into an editable template: headings, paragraphs, tables and styling are converted, then you add blanks in the editor or inspect the result with get_template.

file_base64
string, required
The .docx bytes, base64. Max 10 MB decoded
name
string
Defaults to "Imported document"

Returns id, name, import_warnings, edit_url.

Writes. The local package takes a file path instead.

get_usage

Get usage and limits

Plan, documents used against the monthly allowance, template count, AI credits and the per-minute rate limit. Check it when renders start failing on quota.

Returns plan, billing_period, renders, templates, credits, api_calls, rate_limit.

Read only. Takes no arguments.

Prefer raw HTTP? The same capabilities are available over the REST API, where the errors, the X-DocMake-Warnings header and strict mode are documented in full.

One run, end to end

This is what an assistant actually does, shown as raw JSON-RPC against the hosted server so you can follow it with nothing but curl. Every call and every answer below was run against https://app.docmake.io/mcp/v1 with a real key and pasted back unedited; the key and the signature are redacted.

0. Open a session

Streamable HTTP: one POST per message, with the key in the Authorization header. The server answers the handshake with a session id to send back on every later call.

Request
curl -sS -X POST https://app.docmake.io/mcp/v1 \
  -H "Authorization: Bearer dm_xxx" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2025-06-18","capabilities":{},
                 "clientInfo":{"name":"curl","version":"1.0"}}}'
Response
mcp-session-id: b988daa4-cb37-470d-92f5-fe6badbe3dc1

{"jsonrpc":"2.0","id":1,"result":{
  "protocolVersion":"2025-06-18",
  "capabilities":{"tools":{"listChanged":false},
                  "resources":{"listChanged":false},
                  "prompts":{"listChanged":false}},
  "serverInfo":{"name":"docmake","version":"0.1.0"}, ... }}

1. Find the template

tools/call list_templates
{"jsonrpc":"2.0","id":3,"method":"tools/call",
 "params":{"name":"list_templates","arguments":{"search":"formula"}}}
structuredContent
{
  "data": [
    {
      "id": "tmpl_xYucq408uKkJ",
      "name": "Docs formula example",
      "created_at": "2026-09-03T05:48:46+00:00",
      "updated_at": "2026-09-03T05:49:21+00:00",
      "variables_count": 5,
      "render_count": 2
    }
  ],
  "meta": { "current_page": 1, "last_page": 1, "per_page": 20, "total": 1 }
}

2. Ask what it needs

Keys are dotted and shaped like the payload, so an assistant can build the data object without guessing. A list field carries its per-item fields. Calculations are outputs and appear nowhere in this tree.

tools/call get_template
{"jsonrpc":"2.0","id":4,"method":"tools/call",
 "params":{"name":"get_template","arguments":{"template_id":"tmpl_xYucq408uKkJ"}}}
structuredContent, trimmed
{
  "id": "tmpl_xYucq408uKkJ",
  "name": "Docs formula example",
  "fields": [
    {
      "key": "client", "name": "client", "label": "Client",
      "type": "object", "required": false, "default": null, "example": null,
      "fields": [
        { "key": "client.name", "name": "name", "label": "Client name",
          "type": "string", "required": false, "default": null, "example": null }
      ]
    },
    {
      "key": "items", "name": "items", "label": "Items",
      "type": "array", "required": false, "default": null, "example": null,
      "fields": [
        { "key": "items.product", ... },
        { "key": "items.qty", ... },
        { "key": "items.unit_price", ... }
      ]
    }
  ],
  "unused": []
}

3. Render, and read the warnings

The answer carries a warnings array in the same shape as the REST API's X-DocMake-Warnings header: empty here, because nothing was missing. The link needs no API key and expires, so it can be handed straight to the person who asked.

tools/call render_document
{"jsonrpc":"2.0","id":5,"method":"tools/call",
 "params":{"name":"render_document","arguments":{
   "template_id":"tmpl_xYucq408uKkJ","format":"pdf","filename":"quote-northwind",
   "data":{"client":{"name":"Northwind Trading SRL"},"discount_percent":10,
     "items":[{"product":"Consulting","qty":1,"unit_price":2500},
              {"product":"Internal audit","qty":2,"unit_price":800},
              {"product":"Training","qty":3,"unit_price":350}]}}}}
structuredContent
{
  "document_id": "doc_M6fQVkMHLp04",
  "filename": "quote-northwind.pdf",
  "format": "pdf",
  "size_bytes": 21384,
  "render_time_ms": 1386,
  "warnings": [],
  "download_url": "https://app.docmake.io/mcp/documents/doc_M6fQVkMHLp04?expires=...&signature=...",
  "download_expires_at": "2026-09-03T06:50:22+00:00"
}

4. What happens when something is missing

The same call without a client name. Renders are strict by default here, so nothing is produced and the tool answers with the problem and the way out. The assistant asks you for the value rather than inventing one.

tools/call render_document, isError
{
  "content": [
    {
      "type": "text",
      "text": "Nothing was rendered: client.name has no value. Ask the user for the right values and call render_document again, or pass strict:false to render anyway with missing values left blank."
    }
  ],
  "isError": true
}

Source and listings

The local server is open source, published on npm, and listed in the official Model Context Protocol registry, so you can read the code before you run it.

Questions

What is the DocMake MCP server?
An open-source npm package (@docmake/mcp) that connects AI assistants to your DocMake account through the Model Context Protocol. Once installed, assistants like Claude can list your templates, check which fields they need, and render finished PDF or DOCX documents from a plain conversation.
Which AI tools work with it?
Any MCP client: Claude Desktop, Claude Code, Cursor, Zed, Windsurf, and others. Configuration is the same everywhere: run @docmake/mcp via npx with your API key in the environment. Claude Code, Cursor and VS Code can also point at the hosted server instead, with the API key sent as an Authorization header.
Is it open source?
Yes. The server is published at github.com/docmake-io/mcp under the MIT license, the package is @docmake/mcp on npm, and it is listed in the official Model Context Protocol registry as io.docmake/mcp.
Can I use it without installing anything?
Yes. DocMake hosts the same six tools at https://app.docmake.io/mcp/v1 over streamable HTTP. Point a client that supports remote MCP at that URL and send your API key as an Authorization: Bearer dm_... header. Three things differ from the local package: rendered documents come back as short-lived download links rather than local files, import_docx takes base64 instead of a file path, and the hosted server exposes tools only, where the package also advertises resources and a prompt.
Does it need a paid plan?
No. The free plan includes API access, so the MCP server works from the moment you sign up. Paid plans raise the monthly document volume and remove the footer branding.
Is my data safe?
The local server runs on your machine and talks only to the DocMake API over HTTPS with your API key. Rendered documents are saved to a folder you control. The hosted server runs inside DocMake and handles your data the same way the REST API does, under the same privacy policy. Nothing is sent to any third party either way.