Skip to main content
Glama
xt765

mcp-document-converter

by xt765

Features

  • Multi-format Support: Supports 5 mainstream document formats: Markdown, HTML, DOCX, PDF, and Text

  • Bidirectional Conversion: Any format can be converted to any other format (5ร—5=25 conversion combinations)

  • MCP Protocol: Compliant with MCP standards, can be used as a tool for AI assistants like Trae IDE

  • Plugin Architecture: Easy to extend with new parsers and renderers

  • Syntax Highlighting: HTML and PDF outputs support code syntax highlighting

  • Style Customization: Support for custom CSS styles

  • Metadata Preservation: Preserves document title, author, creation time, and other metadata during conversion


Related MCP server: Pandoc MCP Server

๐Ÿ“š Documentation

User Guide ยท API Reference ยท Contributing ยท Changelog ยท License


Architecture

flowchart TB
    subgraph Parsers["Parsers"]
        MD[Markdown]
        DOCX1[DOCX]
        HTML1[HTML]
        PDF1[PDF]
        TXT1[Text]
    end

    subgraph IR["Intermediate Representation (IR)"]
        DT[Document Tree]
        META[Metadata]
        ASSETS[Assets]
    end

    subgraph Renderers["Renderers"]
        HTML2[HTML]
        PDF2[PDF]
        MD2[Markdown]
        DOCX2[DOCX]
        TXT2[Text]
    end

    MD --> IR
    DOCX1 --> IR
    HTML1 --> IR
    PDF1 --> IR
    TXT1 --> IR
    
    IR --> HTML2
    IR --> PDF2
    IR --> MD2
    IR --> DOCX2
    IR --> TXT2

Core Components

  1. DocumentIR (Intermediate Representation): Unified abstraction for all documents, containing document tree, metadata, assets, etc.

  2. BaseParser (Parser Base Class): Defines the parser interface, parses various formats into DocumentIR

  3. BaseRenderer (Renderer Base Class): Defines the renderer interface, renders DocumentIR into various formats

  4. ConverterRegistry (Registry): Manages all parsers and renderers, provides format lookup and auto-matching

  5. DocumentConverter (Conversion Engine): Coordinates parsers and renderers to complete document conversion

Supported Formats

Input Formats (Parsers)

Format

Extensions

MIME Type

Features

Markdown

.md, .markdown, .mdown, .mkd

text/markdown

YAML Front Matter, GFM extensions

HTML

.html, .htm

text/html

Semantic tag parsing

DOCX

.docx

application/vnd.openxmlformats-officedocument.wordprocessingml.document

Styles, tables, images

PDF

.pdf

application/pdf

Text extraction and structure recognition

Text

.txt, .text

text/plain

Auto encoding detection and structure recognition

Output Formats (Renderers)

Format

Extension

MIME Type

Features

HTML

.html

text/html

Beautiful styling, code highlighting, responsive design

Markdown

.md

text/markdown

Standard Markdown format, YAML Front Matter

DOCX

.docx

application/vnd.openxmlformats-officedocument.wordprocessingml.document

Word document format, style preservation

PDF

.pdf

application/pdf

Generated with WeasyPrint, pagination support

Text

.txt

text/plain

Plain text, basic formatting preserved

Conversion Matrix

flowchart LR
    subgraph Sources["Source Formats"]
        MD_S[Markdown]
        HTML_S[HTML]
        DOCX_S[DOCX]
        PDF_S[PDF]
        TXT_S[Text]
    end

    subgraph Targets["Target Formats"]
        MD_T[Markdown]
        HTML_T[HTML]
        DOCX_T[DOCX]
        PDF_T[PDF]
        TXT_T[Text]
    end

    MD_S --> Targets
    HTML_S --> Targets
    DOCX_S --> Targets
    PDF_S --> Targets
    TXT_S --> Targets

Installation

pip install mcp-document-converter

From Source

git clone https://github.com/xt765/mcp-document-converter.git
cd mcp-document-converter
pip install -e .

MCP Tools

This server provides the following tools:

convert_document

Convert a document from one format to another.

Arguments:

  • source_path (string, required): Path to the source document.

  • target_format (string, required): Target format (html, pdf, markdown, docx, text).

  • output_path (string, optional): Path for the output file.

  • source_format (string, optional): Format of the source file (auto-detected if not provided).

  • options (object, optional): Additional options like template, css, and preserve_metadata.

Configuration

Using in Trae IDE / Claude Desktop

Add the following to your MCP configuration file:

Option 1: Using PyPI (Recommended)

{
  "mcpServers": {
    "mcp-document-converter": {
      "command": "uvx",
      "args": [
        "mcp-document-converter"
      ]
    }
  }
}

Option 2: Using GitHub repository

{
  "mcpServers": {
    "mcp-document-converter": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/xt765/mcp-document-converter",
        "mcp-document-converter"
      ]
    }
  }
}

Option 3: Using Gitee repository (Faster access in China)

{
  "mcpServers": {
    "mcp-document-converter": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://gitee.com/xt765/mcp-document-converter",
        "mcp-document-converter"
      ]
    }
  }
}

Option 4: Using pip (Manual installation)

First install the package:

pip install mcp-document-converter

Then add to configuration:

{
  "mcpServers": {
    "mcp-document-converter": {
      "command": "mcp-document-converter",
      "args": []
    }
  }
}

Using in Cherry Studio

Cherry Studio is a powerful open-source desktop AI client assistant that supports integrating various tools through the MCP protocol

Configuration Example:

Cherry Studio Configuration

Usage Example:

Cherry Studio Usage

Usage

As an MCP Tool

After configuration, AI assistants can directly call the following tools:

Use a unified interface to convert any supported document type.

# Markdown to HTML
convert_document(
    source_path="document.md",
    target_format="html"
)

# HTML to PDF
convert_document(
    source_path="document.html",
    target_format="pdf"
)

# DOCX to Markdown
convert_document(
    source_path="document.docx",
    target_format="markdown"
)

# Conversion with options
convert_document(
    source_path="document.md",
    target_format="html",
    output_path="output.html",
    options={
        "css": "custom.css",
        "preserve_metadata": True
    }
)

2. list_supported_formats

List all supported document formats.

list_supported_formats()

3. get_conversion_matrix

Get the complete format conversion matrix.

get_conversion_matrix()

4. can_convert

Check if conversion from source format to target format is supported.

can_convert(source_format="markdown", target_format="pdf")

5. get_format_info

Get detailed information about a specific format.

get_format_info(format="markdown")

As a Python Library

from mcp_document_converter import DocumentConverter
from mcp_document_converter.registry import get_registry
from mcp_document_converter.parsers import MarkdownParser, HTMLParser
from mcp_document_converter.renderers import HTMLRenderer, PDFRenderer

# Register parsers and renderers
registry = get_registry()
registry.register_parser(MarkdownParser())
registry.register_parser(HTMLParser())
registry.register_renderer(HTMLRenderer())
registry.register_renderer(PDFRenderer())

# Create converter
converter = DocumentConverter(registry)

# Convert document
result = converter.convert(
    source="input.md",
    target_format="html",
    output_path="output.html"
)

if result.success:
    print(f"โœ… Conversion successful: {result.output_path}")
else:
    print(f"โŒ Conversion failed: {result.error_message}")

Tool Interface Details

convert_document

Convert a document from one format to another.

Parameters:

Parameter

Type

Required

Description

source_path

string

โœ…

Source file path, supports absolute or relative paths

target_format

string

โœ…

Target format: html, pdf, markdown, docx, text

output_path

string

โŒ

Output file path (optional, defaults to source filename)

source_format

string

โŒ

Source format (optional, auto-detected from file extension)

options

object

โŒ

Conversion options

Options:

Option

Type

Default

Description

template

string

-

Template name

css

string

-

Custom CSS styles

preserve_metadata

boolean

true

Whether to preserve metadata

extract_images

boolean

true

Whether to extract images

Example:

{
  "source_path": "/path/to/document.md",
  "target_format": "html",
  "output_path": "/path/to/output.html",
  "options": {
    "css": "body { font-family: Arial; }",
    "preserve_metadata": true
  }
}

Extension Development

Adding a New Parser

from typing import List, Union
from pathlib import Path
from mcp_document_converter.core.parser import BaseParser
from mcp_document_converter.core.ir import DocumentIR, Node, NodeType

class MyParser(BaseParser):
    @property
    def supported_extensions(self) -> List[str]:
        return [".myext"]
    
    @property
    def format_name(self) -> str:
        return "myformat"
    
    @property
    def mime_types(self) -> List[str]:
        return ["application/x-myformat"]
    
    def parse(self, source: Union[str, Path, bytes], **options) -> DocumentIR:
        # Read source file
        content = self._read_source(source)
        
        # Parse into DocumentIR
        document = DocumentIR()
        document.title = "My Document"
        
        # Add content nodes
        document.add_node(Node(
            type=NodeType.PARAGRAPH,
            content=[Node(type=NodeType.TEXT, content="Hello World")]
        ))
        
        return document

Adding a New Renderer

from typing import Any
from mcp_document_converter.core.renderer import BaseRenderer
from mcp_document_converter.core.ir import DocumentIR

class MyRenderer(BaseRenderer):
    @property
    def output_extension(self) -> str:
        return ".myext"
    
    @property
    def format_name(self) -> str:
        return "myformat"
    
    @property
    def mime_type(self) -> str:
        return "application/x-myformat"
    
    def render(self, document: DocumentIR, **options: Any) -> str:
        # Render DocumentIR to target format
        parts = []
        
        if document.title:
            parts.append(f"# {document.title}")
        
        for node in document.content:
            # Render each node
            pass
        
        return "\n".join(parts)

Registering Extensions

from mcp_document_converter.registry import get_registry

# Register new parser and renderer
registry = get_registry()
registry.register_parser(MyParser())
registry.register_renderer(MyRenderer())

Testing

# Run all tests
python tests/test_conversion.py

# Run specific test
python tests/test_conversion.py::test_markdown_to_html

Environment Variables

Variable

Description

Default

MCP_CONVERTER_LOG_LEVEL

Log level

INFO

MCP_CONVERTER_TEMP_DIR

Temporary files directory

System temp directory

Dependencies

Core Dependencies

  • mcp >= 1.26.0 - MCP protocol implementation

  • pydantic >= 2.12.5 - Data validation

Parser Dependencies

  • markdown >= 3.5.0 - Markdown parsing

  • beautifulsoup4 >= 4.12.0 - HTML parsing

  • python-docx >= 1.1.0 - DOCX parsing

  • pypdf >= 6.7.4 - PDF parsing

  • chardet >= 5.0.0 - Encoding detection

  • pyyaml >= 6.0.0 - YAML parsing

Renderer Dependencies

  • weasyprint >= 60.0 - PDF rendering

  • pygments >= 2.17.0 - Code highlighting

  • jinja2 >= 3.1.6 - Template engine

  • reportlab >= 4.0.0 - PDF generation

Development Dependencies

  • pytest >= 7.0.0 - Testing framework

  • pytest-asyncio >= 0.21.0 - Async testing support

  • pytest-cov >= 4.0.0 - Coverage reporting

  • basedpyright >= 1.0.0 - Type checking

  • ruff >= 0.1.0 - Linting and formatting

License

MIT License

Contributing

Issues and Pull Requests are welcome!

Available Tools

3 tools
can_convertA

Check if conversion from source format to target format is supported

ParametersJSON Schema
NameRequiredDescriptionDefault
source_formatYesSource format
target_formatYesTarget format

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. 'Check if' clearly conveys a read-only, non-executing behavior, which is helpful. However, it does not disclose the return shape (e.g., boolean) or behavior when a pair is unsupported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, compact sentence front-loads the action and resource with no filler or repetition. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter predicate with enumerated values, the core purpose is covered. However, the absence of an output schema means the return value is not explained, and the description does not explicitly connect this tool to its siblings as a pre-conversion guard.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are fully enumerated, so the schema already explains the parameters. The description only restates the source-to-target relationship and adds no extra meaning about formats or edge cases.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific predicate: checking whether a conversion between two given formats is supported. It directly distinguishes itself from the sibling tools by naming the check operation rather than listing formats or performing the conversion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies that this tool should be used when an agent needs to verify support for a specific format pair, but it does not explicitly say when to use it instead of convert_document or list_supported_formats. No exclusions or alternative routing are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

convert_documentB

Convert a document from one format to another. Supports conversion between Markdown, HTML, DOCX, PDF, and Text formats.

ParametersJSON Schema
NameRequiredDescriptionDefault
optionsNoConversion options
output_pathNoOutput file path (optional, defaults to source filename)
source_pathYesSource file path, supports absolute or relative paths
source_formatNoSource format (optional, auto-detected from file extension)
target_formatYesTarget format

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. The description only states the core conversion action but does not disclose side effects, such as whether output files are overwritten, whether permissions are required, or what happens on failure. This is a significant gap for a tool that likely creates or modifies files.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the core action and lists supported formats with zero wasted words. It delivers its message efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (5 parameters, nested options, two enums) and no output schema, the description is incomplete. It does not mention what the tool returns or where the output goes, nor does it clarify the role of optional parameters like output_path or source_format. An agent would need to open the schema to understand basic behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and each parameter has a descriptive comment. The description adds no parameter-specific meaning beyond listing supported formats, which are already covered by the enums in the schema. Per calibration, a baseline of 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Convert a document from one format to another') and lists the exact formats supported (Markdown, HTML, DOCX, PDF, Text). This clearly distinguishes it from sibling tools like list_supported_formats and can_convert, which are about listing formats and checking convertibility, not performing the conversion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus the siblings. There is no mention of prerequisites, when to use can_convert first, or any contextual conditions. The description merely states the general purpose without any usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_supported_formatsA

List all supported document formats and their conversion capabilities

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. The verb 'List' clearly indicates a read-only, non-mutating operation, which is useful, but the description does not address output structure, whether the list is static or dynamically computed, or whether any authentication or access requirements exist. For a simple listing tool this is adequate but not richly transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It communicates the tool's exact purpose and scope efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless list tool with no output schema, the description is nearly complete: it names the resource and the type of information returned. The only minor gap is that it does not specify the format of the returned list, but this is largely self-evident from the tool's purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4 per the rubric. The description adds meaningful context by clarifying that the returned data includes both supported formats and their conversion capabilities, which defines what the tool exposes without needing any input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a clear resource ('all supported document formats'), and the additional scope ('their conversion capabilities'). This distinguishes it from the sibling tools convert_document and can_convert, which clearly perform conversion or check convertibility rather than enumerate supported formats.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies that this tool should be used when an agent needs to discover which document formats are supported and what conversions are possible. However, it does not explicitly state when to prefer this over can_convert or convert_document, leaving the routing decision implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.2.2
    • First observedcan_convert
    • First observedconvert_document
    • First observedlist_supported_formats

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation5/5

The three tools are clearly distinguishable: one lists all supported formats, one converts documents, and one checks feasibility of a specific conversion. There is no ambiguity in what each tool does because the descriptions clearly separate the listing and checking roles.

Naming Consistency4/5

Tool names use snake_case and mostly follow a verb-noun pattern (list_supported_formats, convert_document). However, can_convert breaks the pattern by being a modal verb phrase without an explicit object, making it a slight outlier.

Tool Count5/5

With only three tools, the server is tightly scoped for its converting purpose. Each tool serves a necessary functionโ€”discovery, capability check, and executionโ€”and there are no filler or extraneous tools.

Completeness4/5

The core conversion lifecycle is covered: users can discover formats, validate conversions, and execute a conversion. The only minor gap is that conversion status or error diagnostics are not provided, but for a simple converter this is not a blocking deficiency.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers