Skip to main content
Glama

convert_markdown_to_docx

Convert Markdown files to professionally styled Word documents with theme options, table of contents, and formatting preservation.

Instructions

Enhanced Markdown to DOCX conversion with professional styling and theme support. Preserves formatting, supports tables, lists, headings, and inline formatting with beautiful Word document output. Output directory is controlled by OUTPUT_DIR environment variable. Files will be automatically saved to OUTPUT_DIR with auto-generated names.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
markdownPathYesMarkdown file path to convert
themeNoTheme to applyprofessional
includeTableOfContentsNoGenerate table of contents
preserveStylesNoPreserve Markdown formatting and styles

Implementation Reference

  • Exported handler function for the 'convert_markdown_to_docx' tool. Creates converter instance and calls the main conversion method.
    export async function convertMarkdownToDocx(
      inputPath: string,
      options: MarkdownToDocxOptions = {}
    ): Promise<MarkdownToDocxResult> {
      const converter = new MarkdownToDocxConverter();
      return await converter.convertMarkdownToDocx(inputPath, options);
    }
  • Core implementation of Markdown to DOCX conversion within the converter class: reads file, parses Markdown elements (headings, paragraphs, tables, code blocks, etc.), applies themes and styles using docx library, generates and returns DOCX buffer.
    async convertMarkdownToDocx(
      inputPath: string,
      options: MarkdownToDocxOptions = {}
    ): Promise<MarkdownToDocxResult> {
      try {
        this.options = {
          preserveStyles: true,
          theme: 'default',
          includeTableOfContents: false,
          debug: false,
          ...options,
        };
    
        if (this.options.debug) {
          console.log('🚀 开始 Markdown 到 DOCX 转换...');
          console.log('📄 输入文件:', inputPath);
          console.log('🎨 使用主题:', this.options.theme);
        }
    
        // 读取 Markdown 文件
        const markdownContent = await fs.readFile(inputPath, 'utf-8');
    
        // 解析 Markdown 内容
        const parsedElements = await this.parseMarkdown(markdownContent);
    
        // 生成 DOCX 文档
        const docxDocument = await this.generateDocxDocument(parsedElements);
    
        // 生成文档缓冲区
        const docxBuffer = await Packer.toBuffer(docxDocument);
    
        // 保存文件(如果指定了输出路径)
        let docxPath: string | undefined;
        if (this.options.outputPath) {
          const { validateAndSanitizePath } = require('../security/securityConfig');
          const allowedPaths = [process.cwd()];
          const validatedPath = validateAndSanitizePath(this.options.outputPath, allowedPaths);
          if (validatedPath) {
            docxPath = validatedPath;
            await fs.writeFile(validatedPath, docxBuffer);
          }
    
          if (this.options.debug) {
            console.log('✅ DOCX 文件已保存:', docxPath);
          }
        }
    
        // 分析内容统计
        const stats = this.analyzeContent(parsedElements);
    
        if (this.options.debug) {
          console.log('📊 转换统计:', stats);
          console.log('✅ Markdown 转换完成');
        }
    
        return {
          success: true,
          content: docxBuffer,
          docxPath,
          metadata: {
            originalFormat: 'markdown',
            targetFormat: 'docx',
            stylesPreserved: this.options.preserveStyles ?? false,
        theme: this.options.theme ?? 'default',
            converter: 'markdown-to-docx-converter',
            contentLength: docxBuffer.length,
            ...stats,
          },
        };
      } catch (error: any) {
        console.error('❌ Markdown 转换失败:', error.message);
        return {
          success: false,
          error: error.message,
        };
      }
    }
  • TypeScript interface defining the input parameters/options schema for the conversion tool.
    interface MarkdownToDocxOptions {
      preserveStyles?: boolean;
      theme?: 'default' | 'professional' | 'academic' | 'modern';
      includeTableOfContents?: boolean;
      customStyles?: {
        fontSize?: number;
        fontFamily?: string;
        lineSpacing?: number;
        margins?: {
          top?: number;
          bottom?: number;
          left?: number;
          right?: number;
        };
      };
      outputPath?: string;
      debug?: boolean;
    }
  • TypeScript interface defining the output result schema for the tool.
    interface MarkdownToDocxResult {
      success: boolean;
      content?: Buffer;
      docxPath?: string;
      metadata?: {
        originalFormat: string;
        targetFormat: string;
        stylesPreserved: boolean;
        theme: string;
        converter: string;
        contentLength: number;
        headingsCount: number;
        paragraphsCount: number;
        tablesCount: number;
      };
      error?: string;
    }
  • Main converter class containing all helper methods for parsing Markdown, generating styled DOCX elements (headings, tables, code blocks, etc.), theme management, and content analysis.
    class MarkdownToDocxConverter {
      private options: MarkdownToDocxOptions = {};
      private themes: Map<string, any>;
    
      constructor() {
        this.themes = new Map();
        this.initializeThemes();
      }
    
      /**
       * 初始化预设主题
       */
      private initializeThemes(): void {
        // 默认主题
        this.themes.set('default', {
          fontSize: 11,
          fontFamily: 'Segoe UI',
          lineSpacing: 1.15,
          headingStyles: {
            h1: { size: 16, color: '2F5496', bold: false },
            h2: { size: 13, color: '2F5496', bold: false },
            h3: { size: 12, color: '1F3763', bold: false },
            h4: { size: 11, color: '2F5496', bold: true },
            h5: { size: 11, color: '2F5496', bold: true },
            h6: { size: 11, color: '2F5496', bold: true },
          },
          margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 }, // 1 inch = 1440 twips
        });
    
        // 专业主题
        this.themes.set('professional', {
          fontSize: 12,
          fontFamily: 'Segoe UI',
          lineSpacing: 1.5,
          headingStyles: {
            h1: { size: 18, color: '000000', bold: true },
            h2: { size: 16, color: '000000', bold: true },
            h3: { size: 14, color: '000000', bold: true },
            h4: { size: 12, color: '000000', bold: true },
            h5: { size: 12, color: '000000', bold: true },
            h6: { size: 12, color: '000000', bold: true },
          },
          margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 },
        });
    
        // 学术主题
        this.themes.set('academic', {
          fontSize: 12,
          fontFamily: 'Segoe UI',
          lineSpacing: 2.0,
          headingStyles: {
            h1: { size: 14, color: '000000', bold: true },
            h2: { size: 13, color: '000000', bold: true },
            h3: { size: 12, color: '000000', bold: true },
            h4: { size: 12, color: '000000', bold: false },
            h5: { size: 12, color: '000000', bold: false },
            h6: { size: 12, color: '000000', bold: false },
          },
          margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 },
        });
    
        // 现代主题
        this.themes.set('modern', {
          fontSize: 11,
          fontFamily: 'Segoe UI',
          lineSpacing: 1.2,
          headingStyles: {
            h1: { size: 20, color: '0078D4', bold: true },
            h2: { size: 16, color: '0078D4', bold: true },
            h3: { size: 14, color: '323130', bold: true },
            h4: { size: 12, color: '323130', bold: true },
            h5: { size: 11, color: '323130', bold: true },
            h6: { size: 11, color: '323130', bold: true },
          },
          margins: { top: 1440, bottom: 1440, left: 1440, right: 1440 },
        });
      }
    
      /**
       * 主转换函数
       */
      async convertMarkdownToDocx(
        inputPath: string,
        options: MarkdownToDocxOptions = {}
      ): Promise<MarkdownToDocxResult> {
        try {
          this.options = {
            preserveStyles: true,
            theme: 'default',
            includeTableOfContents: false,
            debug: false,
            ...options,
          };
    
          if (this.options.debug) {
            console.log('🚀 开始 Markdown 到 DOCX 转换...');
            console.log('📄 输入文件:', inputPath);
            console.log('🎨 使用主题:', this.options.theme);
          }
    
          // 读取 Markdown 文件
          const markdownContent = await fs.readFile(inputPath, 'utf-8');
    
          // 解析 Markdown 内容
          const parsedElements = await this.parseMarkdown(markdownContent);
    
          // 生成 DOCX 文档
          const docxDocument = await this.generateDocxDocument(parsedElements);
    
          // 生成文档缓冲区
          const docxBuffer = await Packer.toBuffer(docxDocument);
    
          // 保存文件(如果指定了输出路径)
          let docxPath: string | undefined;
          if (this.options.outputPath) {
            const { validateAndSanitizePath } = require('../security/securityConfig');
            const allowedPaths = [process.cwd()];
            const validatedPath = validateAndSanitizePath(this.options.outputPath, allowedPaths);
            if (validatedPath) {
              docxPath = validatedPath;
              await fs.writeFile(validatedPath, docxBuffer);
            }
    
            if (this.options.debug) {
              console.log('✅ DOCX 文件已保存:', docxPath);
            }
          }
    
          // 分析内容统计
          const stats = this.analyzeContent(parsedElements);
    
          if (this.options.debug) {
            console.log('📊 转换统计:', stats);
            console.log('✅ Markdown 转换完成');
          }
    
          return {
            success: true,
            content: docxBuffer,
            docxPath,
            metadata: {
              originalFormat: 'markdown',
              targetFormat: 'docx',
              stylesPreserved: this.options.preserveStyles ?? false,
          theme: this.options.theme ?? 'default',
              converter: 'markdown-to-docx-converter',
              contentLength: docxBuffer.length,
              ...stats,
            },
          };
        } catch (error: any) {
          console.error('❌ Markdown 转换失败:', error.message);
          return {
            success: false,
            error: error.message,
          };
        }
      }
Behavior4/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. It effectively describes key behaviors: it preserves formatting, supports specific elements (tables, lists, headings), uses an output directory via environment variable, and auto-generates filenames. However, it does not mention error handling, file size limits, or performance considerations, leaving some gaps.

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

Conciseness4/5

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

The description is appropriately sized and front-loaded, starting with the core purpose and key features. However, the second sentence could be more streamlined, as it lists formatting elements redundantly (e.g., 'preserves formatting' and 'supports tables, lists, headings, and inline formatting' overlap slightly). Overall, it is efficient with minimal waste.

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?

Given the complexity (conversion tool with multiple parameters) and no annotations or output schema, the description is moderately complete. It covers the main purpose, key features, and output behavior, but lacks details on error cases, return values, or advanced usage scenarios, which would be helpful for an AI agent.

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?

The input schema has 100% description coverage, so the baseline is 3. The description adds minimal parameter semantics beyond the schema, mentioning theme support and output directory control, but does not elaborate on parameter interactions or provide additional context for the parameters listed in the schema.

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 clearly states the tool's purpose: converting Markdown files to DOCX format with professional styling and theme support. It specifies the exact transformation (Markdown to DOCX) and distinguishes it from sibling tools like convert_markdown_to_html and convert_markdown_to_pdf by focusing on DOCX output with styling features.

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 usage by mentioning theme support and output directory control, but it does not explicitly state when to use this tool versus alternatives like convert_markdown_to_pdf or create_word_document. It provides some context (e.g., for professional styling) but lacks clear exclusions or comparisons with siblings.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Tele-AI/doc-ops-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server