Skip to main content
Glama

render_mermaid_chart

Convert Mermaid diagram code into PNG, SVG, or PDF image files with customizable dimensions, themes, and background colors for documentation and presentations.

Instructions

将 Mermaid 代码渲染为高质量图片文件

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
mermaidCodeYesMermaid 图表代码
outputPathYes输出文件路径(包含文件名和扩展名)
formatNo输出格式(png, svg, pdf),默认为 pngpng
widthNo图片宽度(像素),默认为 1200
heightNo图片高度(像素),默认为 800
backgroundColorNo背景颜色,默认为 whitewhite
themeNoMermaid 主题,默认为 defaultdefault
uploadToMinioNo是否上传到MinIO存储并返回在线链接,默认为 false
minioExpiryDaysNoMinIO文件有效期(天数),默认7天,最大30天,超过30天按30天计算

Implementation Reference

  • Core handler function that implements the Mermaid chart rendering logic using Puppeteer browser automation, Sharp for image processing, and optional MinIO upload.
    async renderChart(options: RenderOptions): Promise<RenderResult> {
      const {
        mermaidCode,
        outputPath,
        format = 'png',
        width = 1200,
        height = 800,
        backgroundColor = 'white',
        theme = 'default',
        uploadToMinio = false,
        minioExpiryDays = 7,
      } = options;
    
      try {
        // 确保输出目录存在
        const outputDir = dirname(outputPath);
        await fs.ensureDir(outputDir);
    
        // 初始化浏览器
        const browser = await this.initBrowser();
        const page = await browser.newPage();
    
        // 设置高分辨率视口和设备像素比
        await page.setViewport({ 
          width, 
          height,
          deviceScaleFactor: 2, // 设置设备像素比为2,提高PNG渲染质量
        });
    
        // 增加页面错误监听
        page.on('console', msg => {
          if (msg.type() === 'error') {
            console.error('页面控制台错误:', msg.text());
          }
        });
    
        page.on('pageerror', error => {
          console.error('页面运行时错误:', error);
        });
    
        // 创建 HTML 内容
        const htmlContent = this.createHtmlContent(mermaidCode, theme, backgroundColor);
    
        // 加载 HTML 内容
        console.log('加载HTML内容...');
        await page.setContent(htmlContent, { waitUntil: 'domcontentloaded', timeout: 30000 });
    
        // 等待 Mermaid 渲染完成,增加更长的超时时间
        console.log('等待Mermaid渲染...');
        try {
          await page.waitForSelector('#mermaid-diagram', { timeout: 30000 });
          
          // 检查是否渲染成功
          const isRendered = await page.waitForFunction(
            () => {
              const element = document.querySelector('#mermaid-diagram');
              const hasRendered = element && element.getAttribute('data-rendered') === 'true';
              const hasSvg = element && element.querySelector('svg');
              console.log('渲染状态检查:', { hasRendered, hasSvg });
              return hasRendered || hasSvg; // 任一条件满足即可
            },
            { timeout: 60000, polling: 1000 }
          );
          
          console.log('Mermaid渲染完成');
        } catch (timeoutError) {
          // 如果超时,尝试获取页面状态信息
          const pageContent = await page.content();
          console.error('渲染超时,页面内容:', pageContent.substring(0, 500));
          
          const diagramElement = await page.$('#mermaid-diagram');
          if (diagramElement) {
            const innerHTML = await page.evaluate(el => el.innerHTML, diagramElement);
            console.error('图表元素内容:', innerHTML);
          }
          
          throw new Error(`Mermaid渲染超时: ${timeoutError instanceof Error ? timeoutError.message : String(timeoutError)}`);
        }
    
        // 根据格式渲染
        if (format === 'svg') {
          await this.renderSVG(page, outputPath);
        } else if (format === 'pdf') {
          await this.renderPDF(page, outputPath, width, height);
        } else {
          await this.renderPNG(page, outputPath, width, height);
        }
    
        await page.close();
    
        // 基础渲染结果
        const result: RenderResult = {
          outputPath,
          format,
          width,
          height,
        };
    
        // 如果需要上传到MinIO
        if (uploadToMinio) {
          try {
            console.log('🔄 开始MinIO上传...');
            const minioConfig = createDefaultMinIOConfig();
            const minioUploader = new MinIOUploader(minioConfig);
            await minioUploader.initialize();
            
            const uploadResult = await minioUploader.uploadFile(outputPath, {
              expiryDays: minioExpiryDays
            });
            
            result.uploadResult = uploadResult;
            if (uploadResult.success && uploadResult.url) {
              result.minioUrl = uploadResult.url;
              console.log('✅ MinIO上传成功');
            } else {
              console.error('❌ MinIO上传失败:', uploadResult.error);
            }
          } catch (minioError) {
            console.error('❌ MinIO上传过程中发生错误:', minioError);
            result.uploadResult = {
              success: false,
              error: `MinIO上传失败: ${minioError instanceof Error ? minioError.message : String(minioError)}`
            };
          }
        }
    
        return result;
      } catch (error) {
        throw new Error(`渲染失败: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
  • Input schema/JSON Schema definition for the render_mermaid_chart tool parameters.
    inputSchema: {
      type: 'object',
      properties: {
        mermaidCode: {
          type: 'string',
          description: 'Mermaid 图表代码',
        },
        outputPath: {
          type: 'string',
          description: '输出文件路径(包含文件名和扩展名)',
        },
        format: {
          type: 'string',
          enum: ['png', 'svg', 'pdf'],
          description: '输出格式(png, svg, pdf),默认为 png',
          default: 'png',
        },
        width: {
          type: 'number',
          description: '图片宽度(像素),默认为 1200',
          default: 1200,
        },
        height: {
          type: 'number',
          description: '图片高度(像素),默认为 800',
          default: 800,
        },
        backgroundColor: {
          type: 'string',
          description: '背景颜色,默认为 white',
          default: 'white',
        },
        theme: {
          type: 'string',
          enum: ['default', 'dark', 'forest', 'neutral'],
          description: 'Mermaid 主题,默认为 default',
          default: 'default',
        },
        uploadToMinio: {
          type: 'boolean',
          description: '是否上传到MinIO存储并返回在线链接,默认为 false',
          default: false,
        },
        minioExpiryDays: {
          type: 'number',
          description: 'MinIO文件有效期(天数),默认7天,最大30天,超过30天按30天计算',
          default: 7,
          minimum: 1,
          maximum: 30,
        },
      },
      required: ['mermaidCode', 'outputPath'],
    },
  • src/index.ts:37-99 (registration)
    Registration of the tool in the ListToolsRequestSchema handler, including name, description, and schema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: 'render_mermaid_chart',
            description: '将 Mermaid 代码渲染为高质量图片文件',
            inputSchema: {
              type: 'object',
              properties: {
                mermaidCode: {
                  type: 'string',
                  description: 'Mermaid 图表代码',
                },
                outputPath: {
                  type: 'string',
                  description: '输出文件路径(包含文件名和扩展名)',
                },
                format: {
                  type: 'string',
                  enum: ['png', 'svg', 'pdf'],
                  description: '输出格式(png, svg, pdf),默认为 png',
                  default: 'png',
                },
                width: {
                  type: 'number',
                  description: '图片宽度(像素),默认为 1200',
                  default: 1200,
                },
                height: {
                  type: 'number',
                  description: '图片高度(像素),默认为 800',
                  default: 800,
                },
                backgroundColor: {
                  type: 'string',
                  description: '背景颜色,默认为 white',
                  default: 'white',
                },
                theme: {
                  type: 'string',
                  enum: ['default', 'dark', 'forest', 'neutral'],
                  description: 'Mermaid 主题,默认为 default',
                  default: 'default',
                },
                uploadToMinio: {
                  type: 'boolean',
                  description: '是否上传到MinIO存储并返回在线链接,默认为 false',
                  default: false,
                },
                minioExpiryDays: {
                  type: 'number',
                  description: 'MinIO文件有效期(天数),默认7天,最大30天,超过30天按30天计算',
                  default: 7,
                  minimum: 1,
                  maximum: 30,
                },
              },
              required: ['mermaidCode', 'outputPath'],
            },
          },
        ],
      };
    });
  • src/index.ts:102-171 (registration)
    Registration of the CallToolRequestSchema handler that dispatches to the render_mermaid_chart implementation.
      this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
        const { name, arguments: args } = request.params;
    
        if (name === 'render_mermaid_chart') {
          try {
            const {
              mermaidCode,
              outputPath,
              format = 'png',
              width = 1200,
              height = 800,
              backgroundColor = 'white',
              theme = 'default',
              uploadToMinio = false,
              minioExpiryDays = 7,
            } = args as {
              mermaidCode: string;
              outputPath: string;
              format?: 'png' | 'svg' | 'pdf';
              width?: number;
              height?: number;
              backgroundColor?: string;
              theme?: 'default' | 'dark' | 'forest' | 'neutral';
              uploadToMinio?: boolean;
              minioExpiryDays?: number;
            };
    
            // 验证必需参数
            if (!mermaidCode || !outputPath) {
              throw new Error('mermaidCode 和 outputPath 是必需参数');
            }
    
            // 渲染图表
            const result = await this.renderer.renderChart({
              mermaidCode,
              outputPath,
              format,
              width,
              height,
              backgroundColor,
              theme,
              uploadToMinio,
              minioExpiryDays,
            });
    
            return {
              content: [
                {
                  type: 'text',
                  text: this.formatRenderResult(result),
                },
              ],
            };
          } catch (error) {
            const errorMessage = error instanceof Error ? error.message : '未知错误';
            return {
              content: [
                {
                  type: 'text',
                  text: `渲染失败: ${errorMessage}`,
                },
              ],
              isError: true,
            };
          }
        }
    
        throw new Error(`未知工具: ${name}`);
      });
    }
  • TypeScript interface defining the input options for the renderChart handler, matching the schema.
    export interface RenderOptions {
      mermaidCode: string;
      outputPath: string;
      format?: 'png' | 'svg' | 'pdf';
      width?: number;
      height?: number;
      backgroundColor?: string;
      theme?: 'default' | 'dark' | 'forest' | 'neutral';
      uploadToMinio?: boolean; // 是否上传到MinIO
      minioExpiryDays?: number; // MinIO文件有效期(天数),默认7天,最大30天
    }
Behavior2/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 mentions rendering to an image file but lacks details on permissions, side effects (e.g., file system changes), error handling, or performance aspects. This is inadequate for a tool with 9 parameters and potential system impacts.

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, efficient sentence that directly states the tool's purpose without unnecessary words. It is front-loaded and wastes no space, making it easy for an agent to parse quickly.

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 complexity (9 parameters, no output schema, and no annotations), the description is insufficient. It lacks information on return values, error conditions, and behavioral traits needed for safe and effective use. The agent would be left guessing about outcomes and side effects.

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%, so the schema fully documents all parameters. The description does not add any parameter-specific information beyond what the schema provides, such as usage examples or constraints. Baseline 3 is appropriate when the schema handles all parameter documentation.

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

Purpose4/5

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

The description clearly states the action ('render') and resource ('Mermaid code to high-quality image file'). It specifies the transformation from code to image, which is specific and unambiguous. However, without sibling tools, we cannot assess differentiation, so it cannot earn a perfect 5.

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?

The description provides no guidance on when to use this tool versus alternatives, prerequisites, or constraints. It states what the tool does but not the context or scenarios for its application, leaving the agent without usage direction.

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/pickstar-2002/mermaid-chart-mcp'

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