@mcp.tool()
def convert_mermaid_to_image(
mermaid_code: str,
output_format: str = "png",
theme: str = "default",
background_color: str = "",
width: Optional[int] = None,
height: Optional[int] = None
) -> Dict[str, Any]:
"""
将 Mermaid 图表代码转换为多种格式的图像(PNG、JPG、PDF、SVG)。
参数:
mermaid_code: 要转换的 Mermaid 图表语法代码
output_format: 输出格式 - png、jpg、svg 或 pdf(默认:png)
theme: 视觉主题 - default、dark、neutral 或 forest(默认:default)
background_color: 背景颜色,十六进制代码(如 FF0000)或带 ! 前缀的命名颜色(如 !white)
width: 图像宽度(像素,可选)
height: 图像高度(像素,可选)
返回:
包含转换后图像数据和元数据的字典
"""
try:
# 验证输入参数
if not mermaid_code or not mermaid_code.strip():
return {
"success": False,
"error": "Mermaid 代码是必需的,不能为空"
}
# 清理 Mermaid 代码(移除 markdown 代码块标记)
cleaned_code = mermaid_code.replace("```mermaid", "").replace("```", "").strip()
# 验证输出格式
valid_formats = ["png", "jpg", "jpeg", "svg", "pdf"]
output_format = output_format.lower()
if output_format not in valid_formats:
return {
"success": False,
"error": f"无效的输出格式 '{output_format}'。支持的格式:{', '.join(valid_formats)}"
}
# 验证主题
valid_themes = ["default", "dark", "neutral", "forest"]
if theme not in valid_themes:
return {
"success": False,
"error": f"无效的主题 '{theme}'。支持的主题:{', '.join(valid_themes)}"
}
logger.info(f"Converting Mermaid diagram to {output_format} format with theme {theme}")
# Base64 编码 Mermaid 代码
try:
encoded_diagram = base64.urlsafe_b64encode(cleaned_code.encode('utf-8')).decode('ascii')
except Exception as e:
return {
"success": False,
"error": f"编码图表失败:{str(e)}"
}
# 构建 API URL
url = _build_api_url(encoded_diagram, output_format, theme, background_color, width, height)
logger.info(f"Making request to {url}")
# 发送 HTTP 请求
try:
response = requests.get(url, timeout=30)
if response.status_code != 200:
if response.status_code == 400:
error_msg = f"无效的 Mermaid 语法:{response.text}"
elif response.status_code == 413:
error_msg = "图表对于 API 来说太大了"
else:
error_msg = f"转换失败:HTTP {response.status_code}"
logger.error(error_msg)
return {
"success": False,
"error": error_msg
}
# 确定 MIME 类型
mime_types = {
"png": "image/png",
"jpg": "image/jpeg",
"jpeg": "image/jpeg",
"svg": "image/svg+xml",
"pdf": "application/pdf"
}
mime_type = mime_types.get(output_format, "image/png")
filename = f"mermaid_diagram.{output_format}"
# 将图像数据编码为 base64 以便传输
image_base64 = base64.b64encode(response.content).decode('ascii')
logger.info(f"Successfully converted diagram to {output_format} ({len(response.content)} bytes)")
return {
"success": True,
"data": {
"image_base64": image_base64,
"mime_type": mime_type,
"filename": filename,
"size_bytes": len(response.content),
"format": output_format,
"theme": theme
},
"message": f"成功将 Mermaid 图表转换为 {output_format.upper()} 格式"
}
except requests.Timeout:
error_msg = "转换超时 - mermaid.ink 响应时间过长"
logger.error(error_msg)
return {
"success": False,
"error": error_msg
}
except requests.ConnectionError:
error_msg = "连接错误:无法访问 mermaid.ink 服务"
logger.error(error_msg)
return {
"success": False,
"error": error_msg
}
except Exception as e:
error_msg = f"请求错误:{str(e)}"
logger.error(error_msg)
return {
"success": False,
"error": error_msg
}
except Exception as e:
error_msg = f"转换过程中发生意外错误:{str(e)}"
logger.error(error_msg)
return {
"success": False,
"error": error_msg
}