pandoc-mcp
Converts Jupyter notebooks (.ipynb) to and from other document formats; Mermaid code blocks remain unchanged in notebook output.
Supports LaTeX as an input/output format and PDF generation via XeLaTeX; Mermaid diagrams can become vector PDF figures in LaTeX and PDF outputs.
Converts Markdown documents to and from other Pandoc-supported formats, with options for standalone output, table of contents, metadata, and inline text results.
Automatically renders fenced Mermaid diagram code blocks into inline SVG, vector PDF figures, or embedded PNGs depending on the output format, with caption, sizing, and syntax-error warnings.
Converts documents to and from Typst, with Mermaid diagrams embedded as PNG images in Typst output.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pandoc-mcpconvert notes.md to a PDF and render the mermaid diagrams"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pandoc-mcp
An MCP server that converts documents between formats with Pandoc: markdown, HTML, DOCX, PDF (XeLaTeX), ODT, EPUB, PPTX, LaTeX, reStructuredText, Typst, AsciiDoc, Jupyter notebooks and everything else your pandoc reads or writes.
It is built on mcp-service-kit and runs over stdio (local) or HTTP with a bearer token (Docker). It is a reimplementation of mcp-pandoc with a few design changes: see Differences from mcp-pandoc.
For how it is built (layers, conversion flow, storage, security model), see docs/ARCHITECTURE.md.
Tools
Tool | What it does |
| Convert one input to |
| Fetch a stored document (the latest if no id) with its metadata and content. |
| List the server's named filters, defaults files, reference docs and templates, plus the pandoc version. |
| HTTP only. Return a short-lived, upload-only link for files the model can't pass inline, plus an |
| List the files uploaded through a link, as document ids for |
Each result is stored on the server and returned with an id and a download URL:
text output (markdown, HTML, LaTeX, ...) also comes back inline;
binary output (DOCX, PDF, ODT, EPUB, PPTX) comes back as an embedded base64 resource, up to
PANDOC_MCP_MAX_INLINE_BYTES;inline: falsereturns only the id and URL, which keeps large files out of the model's context.
The id can be passed as document to chain conversions, e.g. DOCX → markdown, edit, markdown → DOCX, without resending the bytes.
Uploads and images
To get a file the model can't pass inline, such as the user's own files or files on an agent's
shell, the model calls create_upload_link. The link:
works only for uploading, with no access to anything else;
expires after
PANDOC_MCP_UPLOAD_LINK_TTL_S(10 minutes);stops working once it has accepted
max_filesfiles.
The user opens it in a browser, or the agent runs the curl -F file=@... command it shows.
The model then calls check_upload(upload_id) to get the document ids. The uploader never
sees the ids, and nobody needs the server's token.
Images are embedded by passing their ids as resources and referring to them by file name:
{"contents": "# Report\n\n", "output_format": "docx", "resources": ["<id>"]}Only those files are readable; any other image path stays blocked by the sandbox.
Related MCP server: Pandoc Bridge
Mermaid diagrams
Mermaid diagrams written as fenced code blocks are rendered automatically, wherever
mermaid-cli (mmdc) is installed. The Docker
image includes it, with Debian's Chromium. The format depends on the output:
Output | Diagram becomes |
html, revealjs and other HTML slides | inline SVG |
pdf, latex, beamer | vector PDF figure |
docx, odt, pptx, epub, typst, ... | 2x PNG, embedded in the file |
markdown, gfm, commonmark, ipynb | unchanged code block (GitHub etc. render it) |
``` {.mermaid caption="Request flow" width="80%"}
flowchart LR
User --> API --> DB[(Database)]
```captionturns the diagram into a numbered figure, andwidthsizes it.A diagram with a syntax error stays as code, and mermaid's error appears in the result's
warnings, so the model can fix it and convert again.Pass
render_mermaid: falseto keep the code blocks.Without
mmdc, e.g. a local install without Node, diagrams stay as code, andlist_assetsreports mermaid as unavailable.
Running
Local (stdio)
You need pandoc, plus xelatex for PDF output (sudo apt install pandoc texlive-xetex texlive-latex-extra, or the pandoc release).
uv sync
uv run pandoc-mcp --mode stdio
# Claude Code
claude mcp add pandoc -- uv --directory /path/to/pandoc-mcp run pandoc-mcpIn stdio mode, input_path and output_path are accepted, so a conversion can read and write
files next to you directly.
Docker (HTTP)
The image includes pandoc and TeX Live (XeLaTeX).
cp .env.example .env # set PANDOC_MCP_TOKEN (openssl rand -hex 32)
docker compose up -d --build
claude mcp add --transport http pandoc http://localhost:8301/mcp \
--header "Authorization: Bearer $PANDOC_MCP_TOKEN"The server also provides these routes:
GET /documents/<id>/<filename>: download a stored document. The id is a random uuid4.GET /upload/<token>/POST /upload/<token>: the upload form and endpoint behind a link fromcreate_upload_link. The link is the credential; there is no other way to upload.
Assets
Filters, defaults files, reference documents and templates are installed by the administrator
in PANDOC_MCP_ASSETS_DIR. Tools refer to them by name:
assets/
defaults/ *.yaml pandoc defaults files e.g. academic-pdf.yaml, report-html.yaml
filters/ *.lua Lua filters (or executable JSON filters) e.g. pagebreak.lua
reference-docs/ *.docx|odt|pptx styling for Office output e.g. default.docx
templates/ pandoc templatesIf a text asset's first line is a comment (#, -- or %), that line becomes its description in list_assets.
A reference doc is a copy of pandoc's default (
pandoc -o custom.docx --print-default-data-file reference.docx) with the styles edited in Word or LibreOffice.JSON filters must already be executable. The server never runs chmod on them.
In Docker,
./assetsis mounted read-only, so you can add assets without rebuilding the image.
Configuration
Variable | Default | |
| stdio, 0.0.0.0, 3000 (8301 in Docker), true | from mcp-service-kit; CLI flags |
| Bearer token; required for HTTP unless | |
|
| Base of download URLs |
|
| Document store |
|
| Named assets |
|
| Pandoc executable |
|
|
|
|
| Pandoc is killed after this |
| 20 MB | Inline, base64-decoded or uploaded input |
| 50000 | Longest text returned inline |
| 5 MB | Largest binary returned as embedded base64 |
| 7 | Stored documents are purged after this |
|
| Render mermaid code blocks when |
|
| mermaid-cli executable |
|
|
|
| ( | Chromium settings for mmdc |
| 600 | Lifetime of an upload link |
| 10 | Most files one link may accept |
| 100 | Most links open at once |
| stdio only | Accept |
Security model
These protections apply over HTTP:
No client-supplied paths.
input_pathandoutput_pathare disabled.Assets are resolved by bare name inside the assets directory.
Upload filenames are reduced to a plain name.
The server token never leaves the MCP client. Uploads use links that are upload-only, short-lived and limited to a few files. Tokens are stored only as hashes, in memory, so a restart invalidates them. A link that ends up in a transcript stops working once it is used up or expires.
Pandoc runs with
--sandbox. Readers and writers cannot read local files. For example,→ DOCX would otherwise embed the file. Each conversion also runs in its own temporary directory. Images are embedded only when they are listed asresources.TeX is confined. It runs with
openin_any=p openout_any=p shell_escape=f, so raw LaTeX such as\input{/etc/passwd}is refused by xelatex.Arguments go straight to pandoc. It is run as a subprocess with an argument list, never a shell, and is killed after
PANDOC_MCP_TIMEOUT_S.Defaults files can't change the target.
--defaultsis always placed first, so a defaults file cannot override the requested formats or the output file.Mermaid renders in Chromium. Untrusted diagrams are rendered in headless Chromium, inside the container, with mermaid's default
strictsecurity level (no scripts or click handlers). Chromium's own sandbox is off, because it needs privileges the container does not have. SetPANDOC_MCP_MERMAID=falseif that is not acceptable.Filters are trusted code. They are whatever the administrator installed, so only install filters you trust.
Differences from mcp-pandoc
stdio protocol fixed. mcp-pandoc's
print()calls wrote to stdout, which corrupts the stdio protocol. Logging here goes to stderr.Non-blocking with a timeout. Pandoc runs as an async subprocess with a timeout instead of a blocking
pypandoccall inside the event loop.Formats come from pandoc itself. They are validated against
pandoc --list-input-formatsand--list-output-formats, not a fixed list of 10. That list offered PDF as an input and usedtxtwhere pandoc calls itplain.No server paths needed. Binary formats come back inline as base64 or by URL. mcp-pandoc required a path on the server's filesystem.
Base64 input. Binary input can be sent as base64, so a model can convert files it holds or produced.
Named assets. Filters and defaults files are named, admin-installed assets instead of arbitrary paths, and filters are never chmod'ed.
Code structure. The code uses mcp-service-kit's layout (
features/<tool>/tool.py, pydantic config, standard CLI), and tests run through a real MCP client.
Development
uv sync
uv run pytest # tests needing pandoc / xelatex are skipped when those are missing
uv run ruff checkTo run the whole suite, PDF included, inside the image:
docker build -t pandoc-mcp . && docker run --rm --user 0 -v $PWD/tests:/app/tests:ro \
pandoc-mcp sh -c 'uv sync --frozen -q && uv run --frozen pytest -q -p no:cacheprovider'This server cannot be deployed
Maintenance
Related MCP Connectors
Markdown in, any format out. PDFs merged, split, watermarked. Runs on our own doc engines.
Parse PDF/Word/PPT/HTML to Markdown; tables as JSON, image extraction, RAG chunking, page ranges.
Document-to-Markdown MCP server — convert PDF, Office and HTML into LLM-ready Markdown.
PDF/OCR/Office to Markdown, Office to PDF/PDF-A, PDF and image conversion, audio transcription.
1
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables document format conversion between various formats (Markdown, HTML, PDF, DOCX, LaTeX, EPUB, and more) using Pandoc, preserving formatting and structure while supporting both direct content transformation and file-based conversions.1MIT
- AlicenseNot gradedqualityNot gradedmaintenanceEnables document format conversion between 40+ formats including Markdown, HTML, LaTeX, DOCX, and PDF using Pandoc, with support for both text and file-based conversions.1MIT
- AlicenseBqualityDmaintenanceConverts Markdown files and content to styled PDFs with S3 integration, Mermaid diagrams, and ApexCharts support, supporting stdio, HTTP, and SSE transport modes.318 npm8MIT
- AlicenseAqualityCmaintenanceConverts documents between multiple formats (Markdown, HTML, DOCX, PDF, Text) enabling AI agents to easily transform documents.3103 PyPI12MIT