87 lines
2.8 KiB
Python
87 lines
2.8 KiB
Python
|
|
"""Mermaid MCP Server Integration.
|
||
|
|
|
||
|
|
Manages the external @peng-shawn/mermaid-mcp-server process for diagram generation.
|
||
|
|
|
||
|
|
Architecture:
|
||
|
|
Garvis → (stdio) → mermaid-mcp-server (Node.js) → Puppeteer → PNG images
|
||
|
|
"""
|
||
|
|
|
||
|
|
import os
|
||
|
|
from pathlib import Path
|
||
|
|
from typing import Any, Dict, List
|
||
|
|
import yaml
|
||
|
|
|
||
|
|
_CONFIG_FILE = Path("config/mermaid_mcp.yaml")
|
||
|
|
|
||
|
|
def _load_config() -> Dict[str, Any]:
|
||
|
|
"""Load Mermaid MCP configuration from YAML and env vars."""
|
||
|
|
config = {}
|
||
|
|
if _CONFIG_FILE.exists():
|
||
|
|
try:
|
||
|
|
with open(_CONFIG_FILE, encoding="utf-8") as f:
|
||
|
|
config = yaml.safe_load(f) or {}
|
||
|
|
except Exception:
|
||
|
|
pass # Use defaults if config fails to load
|
||
|
|
|
||
|
|
mermaid = config.get("mermaid_mcp", {})
|
||
|
|
|
||
|
|
# Apply env var overrides
|
||
|
|
if os.getenv("MERMAID_ENABLED"):
|
||
|
|
mermaid["enabled"] = os.getenv("MERMAID_ENABLED").lower() in ("true", "1")
|
||
|
|
if os.getenv("MERMAID_OUTPUT_DIR"):
|
||
|
|
mermaid["output_dir"] = os.getenv("MERMAID_OUTPUT_DIR")
|
||
|
|
if os.getenv("MERMAID_DEFAULT_FORMAT"):
|
||
|
|
mermaid["default_format"] = os.getenv("MERMAID_DEFAULT_FORMAT")
|
||
|
|
if os.getenv("MERMAID_THEME"):
|
||
|
|
mermaid["theme"] = os.getenv("MERMAID_THEME")
|
||
|
|
|
||
|
|
# Set defaults if not configured
|
||
|
|
mermaid.setdefault("enabled", True)
|
||
|
|
mermaid.setdefault("output_dir", "downloads/diagrams/mermaid")
|
||
|
|
mermaid.setdefault("default_format", "png")
|
||
|
|
mermaid.setdefault("theme", "default")
|
||
|
|
|
||
|
|
return mermaid
|
||
|
|
|
||
|
|
def is_mermaid_enabled() -> bool:
|
||
|
|
"""Check if Mermaid MCP integration is enabled."""
|
||
|
|
config = _load_config()
|
||
|
|
return config.get("enabled", True)
|
||
|
|
|
||
|
|
def get_mermaid_server_config() -> Dict[str, Any]:
|
||
|
|
"""Build the MCP server configuration for Agent SDK registration.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Dict with command, args, and env for subprocess execution
|
||
|
|
"""
|
||
|
|
config = _load_config()
|
||
|
|
output_dir = config.get("output_dir", "downloads/diagrams/mermaid")
|
||
|
|
|
||
|
|
# Ensure output directory exists
|
||
|
|
Path(output_dir).mkdir(parents=True, exist_ok=True)
|
||
|
|
|
||
|
|
# Build environment variables for the MCP server
|
||
|
|
env = {
|
||
|
|
"PATH": os.environ.get("PATH", ""),
|
||
|
|
"HOME": os.environ.get("HOME", os.environ.get("USERPROFILE", "")),
|
||
|
|
"APPDATA": os.environ.get("APPDATA", ""),
|
||
|
|
"TEMP": os.environ.get("TEMP", os.environ.get("TMP", "")),
|
||
|
|
}
|
||
|
|
|
||
|
|
# Add config as env vars for the server
|
||
|
|
env["MERMAID_OUTPUT_DIR"] = str(Path(output_dir).absolute())
|
||
|
|
env["MERMAID_DEFAULT_FORMAT"] = config.get("default_format", "png")
|
||
|
|
env["MERMAID_THEME"] = config.get("theme", "default")
|
||
|
|
|
||
|
|
return {
|
||
|
|
"command": "npx",
|
||
|
|
"args": ["-y", "@peng-shawn/mermaid-mcp-server"],
|
||
|
|
"env": env,
|
||
|
|
}
|
||
|
|
|
||
|
|
# Tool names exposed by mermaid-mcp-server
|
||
|
|
# Based on @peng-shawn/mermaid-mcp-server documentation
|
||
|
|
MERMAID_TOOLS: List[str] = [
|
||
|
|
"render_mermaid", # Main tool: convert Mermaid syntax to PNG
|
||
|
|
]
|