Model Context Protocol

Markdown to Word MCP server

An MCP server that lets Claude Desktop, Claude Code, Cursor or any other MCP client write a real .docx or PDF instead of another code block — and read an existing .docx back as Markdown. Four tools, one workspace directory, no Pandoc.

Not on npm yet. The server is finished and its 97 tests pass, including a spawned stdio round-trip against a real client, but it has not been published: it depends on the shared conversion engine, whose licence has to be settled before a public package can depend on it. The configuration blocks below are the ones that will be correct on the day it ships — today the npx -y markdown-to-word-mcp command inside them cannot resolve, and there is no public repository to install from instead. We are saying that here rather than letting you debug a missing package. Until then, the same engine converts documents in your browser on the Markdown to Word converter.

The four tools

ToolArgumentsResult
markdown_to_wordmarkdown or input_path, output_path, formatting optionsWrites a .docx and returns its path plus word, heading and image counts and any warnings.
markdown_to_pdfthe same argumentsWrites a .pdf. Reports honestly when no headless Chromium is installed instead of writing a broken file.
word_to_markdowninput_path, optional output_pathMarkdown. With no output_path the Markdown comes back inside the response instead of as a file.
convert_fileinput_path, optional output_path and toDirection inferred from the extensions: report.md → report.docx, contract.docx → contract.md.

Headings become Word's built-in Heading 1–6 styles, so the navigation pane and an automatic table of contents work in the produced file. Tables stay editable tables, lists use native numbering definitions, and $…$ equations become native Word equation objects rather than images. Nothing is flattened into styled paragraphs, which is the usual failure mode when an agent "writes a Word file" by renaming HTML.

Formatting arguments

Accepted by markdown_to_word, markdown_to_pdf and convert_file, in snake_case: font (default Calibri), font_size (11), paper (A4, Letter or Legal), toc, number_headings, page_numbers, math, mermaid, signature (keep or drop the "Converted with MDtoDOCX" footer), reference_docx_path and css_path. Every argument is validated with a zod schema before a handler runs, and the MCP SDK publishes the JSON Schema derived from those same definitions, so the tool descriptions the model sees and the validation the server performs cannot drift apart. Invalid calls come back as protocol-level validation errors; everything else — a missing file, a refused path, a failed conversion — comes back as a tool result with isError: true. The server never throws its way out of a session, which matters when a model is going to try again.

Path sandbox: one workspace root

An MCP server runs with your user's file permissions, so the interesting question is not what it can do but what it refuses to do. This one reads and writes inside exactly one directory, resolved in this order: the --workspace <dir> flag (short form -w), then the MD2WORD_WORKSPACE environment variable, then the process working directory, which for most clients is the project they launched the server in.

Anything outside that root is refused: .. traversal, absolute paths pointing elsewhere, and symlinks whose target leaves the root. The check applies to every path the server touches, not just the obvious ones — reference_docx_path, css_path and local images referenced from inside the Markdown are all resolved and checked the same way, because an image path is just as good an exfiltration route as an input path. When a call is refused, the message names the root and tells the caller how to widen it, so the model can explain the problem to you instead of silently retrying. Two more switches narrow things further: --no-remote-images (or MD2WORD_NO_REMOTE_IMAGES=1) refuses to download http(s) images at all, and --max-input-bytes <n> caps the input document, defaulting to 25 MB.

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, or %APPDATA%\Claude\claude_desktop_config.json on Windows:

{
  "mcpServers": {
    "markdown-to-word": {
      "command": "npx",
      "args": ["-y", "markdown-to-word-mcp", "--workspace", "/Users/you/Documents/md2word"]
    }
  }
}

Claude Desktop launches servers without a useful working directory, so set --workspace explicitly to the folder you want documents to land in. Restart the app after editing the file.

Claude Code

claude mcp add markdown-to-word -- npx -y markdown-to-word-mcp --workspace "$PWD"

Or commit an .mcp.json at the project root so everyone on the team gets it:

{
  "mcpServers": {
    "markdown-to-word": {
      "command": "npx",
      "args": ["-y", "markdown-to-word-mcp"]
    }
  }
}

The working directory is already the project here, so --workspace can be left out and the sandbox becomes the repository.

Cursor

Global config in ~/.cursor/mcp.json, or per project in .cursor/mcp.json:

{
  "mcpServers": {
    "markdown-to-word": {
      "command": "npx",
      "args": ["-y", "markdown-to-word-mcp", "--workspace", "/absolute/path/to/project"]
    }
  }
}

If you would rather install it globally than let npx resolve it each time, replace "command": "npx" with "command": "markdown-to-word-mcp" and drop the package name from args.

PDF, Mermaid and honest failure

markdown_to_pdf prints the styled HTML with a headless Chromium, which is not bundled; install playwright (plus npx playwright install chromium) or puppeteer in the directory the server runs from. Without one, the tool returns an error saying exactly that and suggesting .docx or HTML instead. mermaid: true shells out to mmdc from @mermaid-js/mermaid-cli; without it, diagrams stay as code blocks and the result carries a note. Both behaviours exist so a model cannot report success for a file that was never written.

The server shares its Node-side hooks and its conversion step with the Markdown to Word CLI, so the two cannot drift. If you want Claude to reach for it without being told to, pair it with the Markdown to Word skill. Tier rules on the pricing page describe the hosted service; a locally run server has no entitlement check.

Markdown to Word MCP: frequently asked questions

Can I add this MCP server to Claude today?
No. It is finished and tested but not yet published to npm, so the npx -y markdown-to-word-mcp command in the config will not resolve. There is no public repository to point a client at either. The browser converter works in the meantime.
What will the package be called?
markdown-to-word-mcp, unscoped, so the command in every config block above will work unchanged once it is published. It will also be submitted to the MCP registry.
Which MCP clients does it support?
Any client that speaks MCP over stdio. Claude Desktop, Claude Code and Cursor are documented above because their config file locations differ; the server itself makes no assumption about the client.
Can the server read files outside my project?
No. Every path is resolved against one workspace root and refused if it leaves it, including .. traversal, absolute paths, symlink targets, reference templates, CSS files and images referenced from the Markdown.
Where does the .docx actually get written?
To the output_path you or the model supplies, resolved inside the workspace root. The tool result returns the final path, so the assistant can tell you where to look rather than guessing.
Why does markdown_to_pdf fail while markdown_to_word works?
PDF needs a headless Chromium and the server does not bundle one. Install playwright or puppeteer where the server runs, or ask for .docx. The tool errors rather than writing an empty PDF.
Does it send my documents anywhere?
No. Conversion happens in the server process on your machine. The only network access is downloading remote images referenced by the Markdown, which --no-remote-images switches off entirely.
How is this different from just asking the model for Markdown?
A model can write Markdown but cannot produce a .docx. These tools do, with real Word styles, editable tables and native equations, so the file opens correctly in Word, LibreOffice and Google Docs.