Skip to main content
Glama
rtuin

mcp-mermaid-validator

by rtuin

validateMermaid

Validate a Mermaid diagram by checking its syntax; returns a rendered PNG or SVG image only for valid diagrams. Helps ensure diagram accuracy before integration.

Instructions

Validates a Mermaid diagram and returns the rendered image (PNG or SVG) if valid

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
diagramYes
formatNopng

Implementation Reference

  • src/main.ts:14-21 (registration)
    Registration of the 'validateMermaid' tool with the MCP server, including schema definition for 'diagram' (string) and 'format' (enum 'svg'|'png', default 'png').
    // Add a mermaid validation tool
    server.tool(
      "validateMermaid",
      "Validates a Mermaid diagram and returns the rendered image (PNG or SVG) if valid",
      { 
        diagram: z.string(),
        format: z.enum(["svg", "png"]).optional().default("png")
      },
  • Input schema for validateMermaid: 'diagram' (z.string()) and 'format' (z.enum(['svg','png']) with default 'png').
    { 
      diagram: z.string(),
      format: z.enum(["svg", "png"]).optional().default("png")
    },
  • Handler function that spawns @mermaid-js/mermaid-cli via npx, pipes the diagram to stdin, reads the rendered image from stdout, and returns the result as a base64-encoded image (PNG or SVG) or an error message if invalid.
    async ({ diagram, format = "png" }) => {
      try {
        try {
          // Use child_process.spawn to create a process and pipe the diagram to stdin
          // Read diagram from STDIN and write image to STDOUT.
          // Use "-" instead of "/dev/stdin" for cross-platform compatibility (WSL, Windows, CI).
          const args = [
            "@mermaid-js/mermaid-cli",
            "-i",
            "-", // read from stdin
            "-o",
            "-", // write to stdout
            "-e",
            format,
          ];
          
          // Add transparent background for PNG format
          if (format === "png") {
            args.push("-b", "transparent");
          }
          
          const mmdc = spawn("npx", args, { stdio: ["pipe", "pipe", "pipe"] });
    
          // Write the diagram to stdin and close it
          mmdc.stdin.write(diagram);
          mmdc.stdin.end();
    
          // Capture stdout (image content) and stderr (error messages)
          const outputChunks: Buffer[] = [];
          let svgContent = "";
          let errorOutput = "";
    
          mmdc.stdout.on("data", (data: Buffer) => {
            if (format === "svg") {
              svgContent += data.toString();
            } else {
              outputChunks.push(data);
            }
          });
    
          mmdc.stderr.on("data", (data: Buffer) => {
            errorOutput += data.toString();
          });
    
          // Wait for the process to complete
          await new Promise<void>((resolve, reject) => {
            mmdc.on("close", (code: number) => {
              if (code === 0) {
                resolve();
              } else {
                reject(
                  new Error(
                    `mermaid-cli process exited with code ${code}${errorOutput ? "\n\nError details:\n" + errorOutput : ""}`,
                  ),
                );
              }
            });
    
            mmdc.on("error", (err: Error) => {
              reject(
                new Error(
                  `${err.message}${errorOutput ? "\n\nError details:\n" + errorOutput : ""}`,
                ),
              );
            });
          });
    
          // If we get here, the diagram is valid
          if (format === "svg") {
            return {
              content: [
                {
                  type: "text",
                  text: "Mermaid diagram is valid",
                },
                {
                  type: "image",
                  data: Buffer.from(svgContent).toString("base64"),
                  mimeType: "image/svg+xml",
                },
              ],
            };
          } else {
            const pngBuffer = Buffer.concat(outputChunks);
            return {
              content: [
                {
                  type: "text",
                  text: "Mermaid diagram is valid",
                },
                {
                  type: "image",
                  data: pngBuffer.toString("base64"),
                  mimeType: "image/png",
                },
              ],
            };
          }
        } catch (validationError: unknown) {
          // The diagram is invalid
          const errorMessage =
            validationError instanceof Error
              ? validationError.message
              : String(validationError);
    
          // Split the error message to separate the main error from stderr details
          const [mainError, ...errorDetails] = errorMessage.split(
            "\n\nError details:\n",
          );
    
          const errorContent: Array<{ type: "text"; text: string }> = [
            {
              type: "text",
              text: "Mermaid diagram is invalid",
            },
            {
              type: "text",
              text: mainError,
            },
          ];
    
          // Add stderr output if available
          if (errorDetails.length > 0) {
            errorContent.push({
              type: "text",
              text: "Detailed error output:\n" + errorDetails.join("\n"),
            });
          }
    
          return {
            content: errorContent,
          };
        }
      } catch (error: unknown) {
        return {
          content: [
            {
              type: "text",
              text: `Error processing Mermaid diagram: ${error instanceof Error ? error.message : String(error)}`,
            },
          ],
        };
      }
    },
Behavior2/5

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

No annotations; description fails to disclose what happens on invalid input (e.g., error messages), side effects, or rate limits. Minimal behavioral context.

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?

Single sentence, no fluff. Efficient for its brevity.

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?

No output schema; description mentions 'rendered image' but not format details (binary vs base64) or validation success/failure behavior. Lacks completeness for a validation tool.

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

Parameters1/5

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

Schema description coverage is 0%; tool description does not explain parameters beyond schema fields. 'diagram' and 'format' remain underdocumented.

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?

Clear verb-resource: 'Validates a Mermaid diagram' and specifies output ('rendered image'). Lacks sibling differentiation but no siblings exist.

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 on when to use or when not to, no alternatives mentioned. Implied usage only.

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/rtuin/mcp-mermaid-validator'

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