Skip to main content
Glama
notasandy

MCP Code Sanitizer

generate_report

Generates an HTML report from code analysis results to visualize bugs, vulnerabilities, and security issues.

Instructions

Generates a beautiful HTML report from analyze_code or analyze_file results.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
analysis_jsonYesJSON string from analyze_code or analyze_file.
output_pathNoPath to save the HTML file (optional).
source_nameNoFile/fragment name for the report title.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function 'generate_report' that accepts analysis_json (JSON string from analyze_code/analyze_file), optional output_path, and optional source_name. Parses the JSON, builds an HTML report via build_html(), optionally saves to disk, and returns JSON with 'html', 'saved_to', and 'length' fields.
    async def generate_report(
        analysis_json: str,
        output_path: str = "",
        source_name: str = "",
    ) -> str:
        """
        Generates a beautiful HTML report from analyze_code or analyze_file results.
    
        Args:
            analysis_json: JSON string from analyze_code or analyze_file.
            output_path:   Path to save the HTML file (optional).
            source_name:   File/fragment name for the report title.
    
        Returns:
            JSON with fields: html, saved_to, length.
        """
        try:
            data = json.loads(analysis_json)
        except json.JSONDecodeError as e:
            return error_response("Invalid JSON in analysis_json", str(e))
    
        html     = build_html(data, source_name=source_name)
        saved_to = ""
    
        if output_path:
            out = Path(output_path).expanduser().resolve()
            try:
                out.parent.mkdir(parents=True, exist_ok=True)
                out.write_text(html, encoding="utf-8")
                saved_to = str(out)
            except OSError as e:
                return error_response("Failed to save file", str(e))
    
        return json.dumps({"html": html, "saved_to": saved_to, "length": len(html)}, ensure_ascii=False)
  • Input schema for generate_report: analysis_json (str, required), output_path (str, optional), source_name (str, optional). The return type is str (JSON string with html, saved_to, length fields).
    async def generate_report(
        analysis_json: str,
        output_path: str = "",
        source_name: str = "",
    ) -> str:
  • build_html() is the core helper that constructs the full HTML report from the analysis data dictionary. It produces a styled document with a header (score ring, verdict, metadata), severity pill counters, and sections for issues, warnings, and suggestions.
    def build_html(data: dict, source_name: str = "") -> str:
        score       = data.get("score", 0)
        summary     = data.get("summary", "")
        issues      = data.get("issues", [])
        warnings    = data.get("warnings", [])
        suggestions = data.get("suggestions", [])
        stats       = data.get("stats", {})
        filename    = data.get("file", source_name)
        lang        = data.get("language", "")
        lines       = data.get("lines", "")
    
        meta = "".join([
            f'<span><b>{filename}</b></span>' if filename else "",
            f'<span>Language: <b>{lang}</b></span>' if lang else "",
            f'<span>Lines: <b>{lines}</b></span>' if lines else "",
        ])
    
        header = (
            f'<div class="header">'
            f'<h1>Code Sanitizer <span>Report</span></h1>'
            f'<div class="meta">{meta}</div>'
            f'<div class="score-row">'
            f'{_ring(score)}'
            f'<div class="verdict"><b>Verdict:</b> {summary}</div>'
            f'</div></div>'
        )
    
        pills = "".join(
            f'<div class="pill {s}"><div class="n">{stats.get(s, 0)}</div><div class="l">{s}</div></div>'
            for s in _SEVERITY_ORDER
        ) if stats else ""
    
        sorted_issues = sorted(issues, key=lambda x: _SEVERITY_ORDER.index(x.get("severity", "low")))
        issues_html   = "".join(_issue_card(i) for i in sorted_issues) or '<div class="empty">No issues found</div>'
        warns_html    = "".join(
            f'<div class="warn"><div class="warn-title">{w.get("title","")}</div>'
            f'<div class="warn-desc">{w.get("description","")}</div></div>'
            for w in warnings
        ) or '<div class="empty">No warnings</div>'
        sugs_html = "".join(
            f'<div class="sug"><div class="sug-text">{s}</div></div>'
            for s in suggestions
        ) or '<div class="empty">No suggestions</div>'
    
        body = (
            header
            + (f'<div class="pills">{pills}</div>' if pills else "")
            + _section("๐Ÿ”ด", "Issues", issues_html, len(issues))
            + _section("โš ๏ธ", "Warnings", warns_html, len(warnings))
            + _section("๐Ÿ’ก", "Suggestions", sugs_html, len(suggestions))
            + '<div class="footer">Generated by <b>mcp-code-sanitizer</b> ยท Powered by Groq</div>'
        )
    
        return (
            f'<!DOCTYPE html><html lang="en"><head>'
            f'<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">'
            f'<title>Code Sanitizer โ€” {filename or "Report"}</title>'
            f'<style>{_CSS}</style></head>'
            f'<body><div class="wrap">{body}</div></body></html>'
        )
  • server.py:36-36 (registration)
    Registration of generate_report as an MCP tool via mcp.tool()(generate_report) on the FastMCP server instance 'code-sanitizer'.
    mcp.tool()(generate_report)
  • tools/__init__.py:7-7 (registration)
    Export of generate_report from the tools package, imported from tools.report module.
    from .report    import generate_report
Behavior2/5

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

No annotations provided; description only states basic function with no details on side effects, authorizations, or file handling (e.g., overwrite behavior).

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, 13 words, front-loaded with action and resource, no wasted words.

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?

Adequate but ambiguous about behavior when output_path is empty (e.g., returns HTML vs. saves file); output schema may help but not provided.

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?

Input schema covers all parameters with descriptions; description adds 'beautiful HTML report' but no extra parameter meaning beyond 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 generates an HTML report from analyze_code or analyze_file results, specifying the verb, resource, and source.

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?

Implies usage after analysis tools but lacks explicit when-not-to-use or comparison to siblings like generate_tests.

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/notasandy/mcp-code-sanitizer'

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