
Connects Claude to Carbone's document generation and conversion API. Exposes tools to convert between 100+ formats (PDF, DOCX, XLSX, HTML, Markdown, images), render documents from templates using JSON data injection, and manage a template library with versioning and categories. Includes batch generation, PDF watermarking, form filling, and localization support. Works via stdio (Claude Desktop, Cursor, VS Code) or streamable HTTP at mcp.carbone.io. Requires a Carbone API key for the cloud service, or point it at your own on-premise instance. Useful when you need Claude to produce finished documents, invoices, or reports rather than just draft text.
claude mcp add --transport http carbone-mcp https://mcp.carbone.ioRun in your terminal. Add --scope user to make it available in every project.
Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.
Verified live against the running server on Jun 10, 2026.
list_templatesList stored Carbone templates with filtering, search, and pagination. Filter by Template ID, Version ID, category, or upload origin. Use includeVersions to see the full version history of each template. Supports cursor-based pagination for large collections. Note: filtering by...8 paramsList stored Carbone templates with filtering, search, and pagination. Filter by Template ID, Version ID, category, or upload origin. Use includeVersions to see the full version history of each template. Supports cursor-based pagination for large collections. Note: filtering by...
categorystringcursorstringidstringincludeVersionsbooleanlimitintegeroriginintegersearchstringversionIdstringconvert_documentConvert any document to another format without storing a template. Supports 100+ input/output format combinations: Office documents, PDFs, images, web pages, spreadsheets, and more. The source file can be a local path, a URL, or a base64 string. Use render_document instead whe...3 paramsConvert any document to another format without storing a template. Supports 100+ input/output format combinations: Office documents, PDFs, images, web pages, spreadsheets, and more. The source file can be a local path, a URL, or a base64 string. Use render_document instead whe...
convertTo*valueconverterstringL · C · Ofile*stringrender_documentGenerate a document by merging a Carbone template with JSON data. Two modes: (1) pass templateId to use a previously uploaded template; (2) pass template (file path, URL, or base64) to upload and render in a single request without storing a template. Supports output format con...21 paramsGenerate a document by merging a Carbone template with JSON data. Two modes: (1) pass templateId to use a previously uploaded template; (2) pass template (file path, URL, or base64) to upload and render in a single request without storing a template. Supports output format con...
batchOutputstringbatchReportNamestringbatchSplitBystringcomplementobjectconvertTovalueconverterstringL · C · OcurrencyRatesobjectcurrencySourcestringcurrencyTargetstringdata*objectenumobjecthardRefreshbooleanlangstringreportNamestringtemplatestringtemplateIdstringtimezonestringtranslationsobjectvariableStrstringwebhookHeadersobject+1 more parameters. See the server's own documentation for the full schema.
list_categoriesList all template categories currently in use in your Carbone account. Categories act like folders for organising templates (e.g. "invoices", "legal", "hr"). Use the returned names as the category filter in list_templates or upload_template.List all template categories currently in use in your Carbone account. Categories act like folders for organising templates (e.g. "invoices", "legal", "hr"). Use the returned names as the category filter in list_templates or upload_template.
No parameters — call it with no arguments.
list_tagsList all tags currently used across templates in your Carbone account. Tags are free-form labels attached to templates (e.g. "sales", "billing", "v2"). Note: the Carbone API does not support filtering list_templates by tag — use this tool to discover available tags, then call...List all tags currently used across templates in your Carbone account. Tags are free-form labels attached to templates (e.g. "sales", "billing", "v2"). Note: the Carbone API does not support filtering list_templates by tag — use this tool to discover available tags, then call...
No parameters — call it with no arguments.
upload_templateUpload and store a reusable Carbone template. Once uploaded, use render_document with the returned Template ID to generate documents from it. Supports versioning: multiple versions can live under a single stable Template ID, with deployedAt controlling which version is active....10 paramsUpload and store a reusable Carbone template. Once uploaded, use render_document with the returned Template ID to generate documents from it. Supports versioning: multiple versions can live under a single stable Template ID, with deployedAt controlling which version is active....
categorystringcommentstringdeployedAtintegerexpireAtintegeridstringname*stringsamplearraytagsarraytemplate*stringversioningbooleanupdate_template_metadataUpdate the metadata of a stored template: name, comment, category, tags, deployment timestamp, or expiration. Use deployedAt to activate a specific version for rendering. Use expireAt to schedule or trigger immediate deletion.7 paramsUpdate the metadata of a stored template: name, comment, category, tags, deployment timestamp, or expiration. Use deployedAt to activate a specific version for rendering. Use expireAt to schedule or trigger immediate deletion.
categorystringcommentstringdeployedAtintegerexpireAtintegernamestringtagsarraytemplateId*stringdelete_templateDelete a stored Carbone template. This is a soft delete: the template is marked for garbage collection and removed after a delay (default 24 hours). You can delete by Template ID (removes all versions) or by Version ID (removes only that specific version). For immediate or sch...1 paramsDelete a stored Carbone template. This is a soft delete: the template is marked for garbage collection and removed after a delay (default 24 hours). You can delete by Template ID (removes all versions) or by Version ID (removes only that specific version). For immediate or sch...
templateId*stringdownload_templateDownload the original source file of a stored Carbone template (e.g. the DOCX, XLSX, PPTX, or HTML file that was uploaded). Use this to inspect, edit, or back up a template. Pass a Template ID to download the currently deployed version, or a Version ID to download a specific v...1 paramsDownload the original source file of a stored Carbone template (e.g. the DOCX, XLSX, PPTX, or HTML file that was uploaded). Use this to inspect, edit, or back up a template. Pass a Template ID to download the currently deployed version, or a Version ID to download a specific v...
templateId*stringget_api_statusCheck Carbone API health and version. Returns the current API version and a status message. Useful for verifying connectivity and confirming which Carbone version is active.Check Carbone API health and version. Returns the current API version and a status message. Useful for verifying connectivity and confirming which Carbone version is active.
No parameters — call it with no arguments.
get_capabilitiesReturns a summary of all Carbone capabilities: supported formats, features, tool usage examples, and links to full documentation. Call this first if you are unsure what Carbone can do.Returns a summary of all Carbone capabilities: supported formats, features, tool usage examples, and links to full documentation. Call this first if you are unsure what Carbone can do.
No parameters — call it with no arguments.
Automate production-ready PDF, Word, Excel and PowerPoint documents from templates and JSON data, and convert files between 36 formats, from Claude, Cursor, VS Code or any MCP client. The official server for the Carbone document generation API.
{d.field} tags, or fill an existing PDF form.These work on any Carbone account, even without a plan (you then get watermarked PDFs):
inspect_template lists its tags and drafts a sample JSON)More in Example prompts, including with Salesforce, HubSpot, Notion and Stripe.
Upgrading from 1.x? Read the upgrade notes — HTTP deployments should upgrade now (security fixes).
npx carbone-mcp). Check with node --version. The Docker image needs Docker only.| Setup | Runs | Clients | Local files |
|---|---|---|---|
| Hosted server (HTTP) | https://mcp.carbone.io, nothing to install | claude.ai, Claude Desktop, Claude Code, VS Code, Cursor, …: sign in with your Carbone account | ❌ URLs and base64 only |
| Local package (stdio) | npx carbone-mcp on your machine | Claude Desktop, Claude Code, VS Code, Cursor, and any client that starts local servers | ✅ reads local paths, saves documents to disk |
| Docker (HTTP) | Your own server | Clients that can send an Authorization header: Claude Code, VS Code, Cursor, … | ❌ URLs and base64 only |
claude.ai and Claude Desktop: add the hosted server as a connector. In Claude Desktop, use the local package instead to read and save files on your computer.
Most clients use this config:
{
"mcpServers": {
"carbone": {
"command": "npx",
"args": ["-y", "carbone-mcp"],
"env": {
"CARBONE_API_KEY": "your_api_key_here"
}
}
}
}
| Client | Where to put it |
|---|---|
| Claude Desktop | Settings → Developer → Edit Config opens claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\). Quit and restart Claude Desktop afterwards. |
| Cursor | ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project) |
Claude Code:
claude mcp add --env CARBONE_API_KEY=your_api_key_here --transport stdio carbone -- npx -y carbone-mcp
VS Code: .vscode/mcp.json uses servers, not mcpServers. With an input variable, VS Code asks for the key once and stores it securely:
{
"inputs": [
{ "type": "promptString", "id": "carbone-api-key", "description": "Carbone API key", "password": true }
],
"servers": {
"carbone": {
"type": "stdio",
"command": "npx",
"args": ["-y", "carbone-mcp"],
"env": { "CARBONE_API_KEY": "${input:carbone-api-key}" }
}
}
}
Then try: "What can Carbone do?"
Client docs: Claude Desktop · Claude Code · VS Code · Cursor
Nothing to install: connect to https://mcp.carbone.io over Streamable HTTP, and sign in with your Carbone account when your client opens account.carbone.io in your browser. Over HTTP, file inputs must be URLs or base64 (File inputs).
Claude Code: add the server, then run /mcp, select carbone and choose Authenticate.
claude mcp add --transport http carbone https://mcp.carbone.io
VS Code (.vscode/mcp.json), which asks you to sign in when it starts the server:
{
"servers": {
"carbone": { "type": "http", "url": "https://mcp.carbone.io" }
}
}
Cursor (~/.cursor/mcp.json or .cursor/mcp.json), then sign in from Cursor's MCP settings:
{
"mcpServers": {
"carbone": { "url": "https://mcp.carbone.io" }
}
}
https://mcp.carbone.io. Leave the OAuth client ID and secret empty.In an organization, each member connects with their own Carbone account, and their documents count against it. Claude Desktop uses the same connectors; to read and save files on your computer, use the local package instead.
file (convert_document) and template (render_document, inspect_template, upload_template) accept:
| Form | Example | stdio | HTTP |
|---|---|---|---|
| Absolute local path | /Users/me/invoice.docx, ~/invoice.docx, C:\Users\me\invoice.docx | ✅ | ❌ refused |
| URL | https://example.com/invoice.docx | ✅ | ✅ |
| Base64 | the file content, base64-encoded | ✅ | ✅ |
Any other string, such as a bare invoice.docx, is read as base64 and fails. Relative paths (./…, ../…) resolve against the server's working directory, which your client chooses: prefer absolute paths. The JSON parameters (data, complement, …) also accept a path, URL or base64 string pointing to a JSON file (details).
| Output | stdio (local clients) | HTTP (remote / self-hosted) |
|---|---|---|
| Text: HTML, TXT, CSV, MD, XML, JSON (template samples) | inline text | inline text |
| Images: PNG, JPG, GIF, WEBP | inline image | inline image |
| Everything else: PDF, Office, SVG, TIFF… | saved to a temp file, path returned | returned as a download attachment |
You can instead save to a path you choose (outputPath, stdio only), get an attachment for any format (asAttachment), or get a one-time download link (returnLink): see Output and file delivery.
Claude Desktop cannot display inline binary attachments (it mishandles them as images). For PDF and Office files, keep the default temp-file path, or ask for
returnLinkto get a download URL.
| Tool | What it does |
|---|---|
convert_document | Converts a file to another format; Carbone tags stay as written |
render_document | Fills a template with JSON data, and can convert the result (to PDF, for example) |
inspect_template | Lists a template's tags and returns a matching sample dataset. Runs one render on your account (counts as one document generation) |
list_templates | Lists stored templates, filtered by category, name or ID |
list_categories | Lists the template categories in your account |
list_tags | Lists the tags used across your templates |
upload_template | Stores a reusable template, with versions, category and tags |
update_template_metadata | Renames, categorizes, tags, deploys or schedules the deletion of a template version |
delete_template | Deletes a template or one of its versions, immediately |
download_template | Downloads a template's original file, or the sample data stored with it |
get_api_status | Checks the Carbone API's health and version |
get_capabilities | Summarizes the formats, features and usage examples |
Every parameter, with examples: docs/API.md.
With your other tools. Carbone turns data that another MCP server fetches into a finished document. These assume that server (Salesforce, HubSpot, Notion, Stripe, …) is connected in the same client.
Templates and data
Convert
Batch and localization
PDF options and template library
| Symptom | Cause and fix |
|---|---|
Tool error Authentication failed: … (no key, or a key the Carbone API rejects with 401) | stdio: set CARBONE_API_KEY in the client config's env and restart the client (without it, the server stops at startup with CARBONE_API_KEY environment variable is required). Self-hosted HTTP: send Authorization: Bearer <key>; a server with CARBONE_REQUIRE_CLIENT_AUTH_HEADER=true requires it on every request. Check the key at account.carbone.io. |
| mcp.carbone.io asks you to sign in again, or sign-in fails | Reconnect: in Claude, Disconnect then Connect the connector; in Claude Code, /mcp → Clear authentication, then Authenticate. |
HTTP 403 Invalid Origin: <host> | A browser-based client served from a host other than localhost. Add its hostname to MCP_ALLOWED_ORIGINS. |
HTTP 405 Method not allowed when you open the endpoint in a browser | Expected: the endpoint only answers MCP POST requests. Connect with an MCP client; check the server with GET /health. |
HTTP 413 Request body too large, or the stdio connection closes | One MCP message is over MCP_MAX_BODY_BYTES (60 MB by default; it applies to stdio messages too). Pass large files by URL (or a local path in stdio) instead of inline base64, or raise the limit. |
Rate limit exceeded. Please wait N second(s) | The Carbone API answered 429. Wait the time given and try again. |
Tags such as {d.name} still visible in the output | convert_document is a pure conversion and keeps tags. Use render_document with your data. |
| Watermark on every PDF, or only PDF works | You use the test key: it produces watermarked PDFs only. On mcp.carbone.io, start a plan at account.carbone.io (the Free plan is enough): the server switches to your production key by itself. Locally, use the production key. |
A file given by name (invoice.docx) fails | A bare name is read as base64. Pass an absolute path (stdio), a URL, or base64 (File inputs). |
| Rendering by Template ID still uses the old version after an upload | Renders by Template ID use the deployed version (most recent deployedAt). Deploy the new version with update_template_metadata (templateId = its Version ID, deployedAt = 42000000000), or render by Version ID. |
| Password, watermark or PDF/A missing from a PDF | PDF/A, page ranges and accessibility use the default converter L (LibreOffice); O, C and I apply passwords, permissions and watermarks. For PDF → PDF the server sets hardRefresh for you: don't pass hardRefresh: false. |
| Claude Desktop shows no Carbone tools, or the server disconnects | Read mcp-server-carbone.log (the server's stderr) in ~/Library/Logs/Claude/ (macOS) or %APPDATA%\Claude\logs\ (Windows). A good start logs Carbone MCP Server v<version> started (stdio). |
| You want to test the server without an AI client | Run the MCP Inspector (Node.js 22.19+): npx @modelcontextprotocol/inspector -e CARBONE_API_KEY=your_api_key_here npx carbone-mcp. It lists the tools and shows each request and response. |
The image serves Streamable HTTP on port 3000. This quick start sets no server key: each client sends its own key in Authorization: Bearer <key> (signing in with a Carbone account is for mcp.carbone.io only), and the port is reachable from your machine only.
docker run -d --name carbone-mcp -p 127.0.0.1:3000:3000 carbone/carbone-mcp
curl http://localhost:3000/health
Connect your client with your key in the Authorization header:
claude mcp add --transport http carbone http://localhost:3000 --header "Authorization: Bearer your_api_key_here"
In VS Code and Cursor, take the hosted server config with the URL http://localhost:3000 and add "headers": { "Authorization": "Bearer your_api_key_here" } next to "url". VS Code can prompt for the key with an inputs entry of type promptString ("Bearer ${input:carbone-api-key}"), and Cursor can read it from your environment ("Bearer ${env:CARBONE_API_KEY}"). To serve other machines, publish the port behind a TLS reverse proxy, keep the server without CARBONE_API_KEY (or set CARBONE_REQUIRE_CLIENT_AUTH_HEADER=true), and list the hostnames of browser-based clients in MCP_ALLOWED_ORIGINS.
Shared-key variant, for one user on one machine. A server-level key lets clients connect without sending one:
docker run -d --name carbone-mcp -p 127.0.0.1:3000:3000 -e CARBONE_API_KEY=your_api_key_here carbone/carbone-mcp
Read the shared-key warning before you use it.
Docker Compose: compose.yml builds the image from this repository, binds 127.0.0.1 only, sets no server key, and passes through every variable of .env.example. Start it with docker compose up -d. Compose also reads CARBONE_API_KEY from your shell or a .env file: if it is set there, you get the shared-key variant.
To run the image as a stdio server for Claude Desktop, see the Docker Hub page.
If you run Carbone on-premise, point the server at your instance with CARBONE_BASE_URL; no API key is needed. For example CARBONE_BASE_URL=https://your-carbone-server.com npx carbone-mcp, or add -e CARBONE_BASE_URL=https://your-carbone-server.com to docker run.
| Variable | Default | Purpose |
|---|---|---|
CARBONE_API_KEY | none | Your Carbone API key: required in stdio for Carbone Cloud, optional over HTTP (Security) |
CARBONE_BASE_URL | https://api.carbone.io | Carbone API URL; set it to an on-premise instance (no key needed) |
CARBONE_TIMEOUT | 60000 | Carbone API request timeout in ms; Carbone Cloud's own limit is 60 s |
CARBONE_MAX_FILE_BYTES | 104857600 (100 MB) | Largest input file read from a path, URL or base64 |
MCP_TRANSPORT | stdio (http in Docker) | stdio or http |
MCP_PORT | 3000 | HTTP port |
MCP_PATH | / | HTTP endpoint path; cannot be /health |
MCP_MAX_BODY_BYTES | 62914560 (60 MB) | Largest MCP message: an HTTP body (413 above it) or a stdio message |
MCP_ALLOWED_ORIGINS | none (localhost is always allowed) | HTTP: browser Origin hostnames to allow, comma-separated |
CARBONE_REQUIRE_CLIENT_AUTH_HEADER | false | HTTP: true refuses requests that bring no Bearer key of their own |
CARBONE_ALLOW_PRIVATE_NETWORK | false | true lets URL inputs reach private and internal addresses |
Full descriptions: Configuration in docs/API.md.
localhost, RFC 1918, cloud metadata) are refused unless CARBONE_ALLOW_PRIVATE_NETWORK=true (details). Local paths are read in stdio only, where the server runs as you; over HTTP they are refused.CARBONE_API_KEY set on an HTTP server and CARBONE_REQUIRE_CLIENT_AUTH_HEADER=false (the default), every request without a Bearer key spends that key: anyone who can reach the port uses that Carbone account. The server prints a warning at startup. Never publish such a port on a network you don't fully trust, or set CARBONE_REQUIRE_CLIENT_AUTH_HEADER=true so each client must bring its own key. This doesn't apply when no server key is set (for example on-premise Carbone without authentication).Origin header is present but not allowed gets 403, so a malicious web page cannot reach a locally running server (DNS rebinding) and spend its key. localhost, 127.0.0.1 and [::1] are allowed; list the browser-based clients you trust in MCP_ALLOWED_ORIGINS. Requests without an Origin (desktop, CLI and server-side clients) are unaffected.returnLink or a webhook until they are downloaded. See the privacy policy, or run Carbone on-premise for full control.Design a template in Word, Excel, PowerPoint, LibreOffice, HTML or Markdown, and put tags where the data goes:
Dear {d.customer.name},
Your invoice total is {d.total:formatC()}.
Items:
{d.items[i].description} {d.items[i].quantity}x {d.items[i].price:formatC()}
{d.items[i+1]}
{d.items[i]} … {d.items[i+1]} repeats a line for each item. Start with the basics, or give your AI assistant the Carbone Skill, a template syntax reference for AI tools (download .skill · GitHub).
Bug reports, fixes and documentation improvements are welcome. CONTRIBUTING.md covers the development setup, tests, debugging and the pull request process.
Apache 2.0, see LICENSE.
CARBONE_API_KEY*secretYour Carbone API key from https://account.carbone.io. Required when using the Carbone cloud API. If CARBONE_BASE_URL points to an on-premise server, authentication is not required and this can be left empty.
CARBONE_BASE_URLdefault: https://api.carbone.ioCustom Carbone API base URL for on-premise deployments. Defaults to https://api.carbone.io. When set to a custom URL, CARBONE_API_KEY is not required.