RTFM

MCP Tool Reference

Auto-generated from the running MCP server's descriptors. Last refreshed at 2026-06-29T11:55:36.197Z.

  1. list_manufacturers

    List manufacturers that have documented models.

        Pass `equipment_type` — one of "string_inverters", "micro_inverters",
        or "batteries" — to narrow the list to one type; omit it to get all
        three mixed together. Each returned manufacturer is tagged with the
        equipment types it actually has documented (`types`), so a single
        unfiltered call is enough to answer "which brand has what" without
        per-manufacturer follow-ups.
    
        When to use: the user wants to browse brands, or did not mention one
        and you need to offer choices. If the user already named a brand, use
        `search_manufacturers` instead — it is faster and returns a match
        score.
    
        Prerequisite ids: none — this is an entry point.
    
        Returns: `{"manufacturers": [{"id": int, "name": str, "types":
        [str, ...]}, ...]}`, sorted by name. `types` lists the documented
        equipment types for that brand, using the same vocabulary as the
        `equipment_type` filter (so a value can be passed straight back) —
        when a filter is supplied every `types` is just `[that type]`. Only
        manufacturers that own at least one model with an ingested manual
        page or extracted alert/behavior are returned; CEC-registered
        manufacturers whose models are all stubs (no manual on file) are
        excluded — when the `equipment_type` filter is supplied, the
        documentation check is scoped to that type. Feed `id` as
        `manufacturer_id` into `list_models` or `search_models_by_model_number`
        to get a `model_id`.
    
        Args:
            equipment_type (optional): One of "string_inverters",
                "micro_inverters", "batteries". Omit or pass
                `null` to return manufacturers across every equipment type.
                When specified, only manufacturers with at least one
                documented model of that type are returned.
        
    

    Parameters

    NameTypeRequiredDescription
    equipment_typestringno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "list_manufacturers",
        "arguments": {
          "equipment_type": "string_inverters"
        }
      }
    }
  2. search_manufacturers

    Search for manufacturers by curated keyword.

        Pass `equipment_type` — one of "string_inverters", "micro_inverters",
        or "batteries" — to narrow the search to one type; omit it to search
        across all three. Each match is tagged with the equipment types it has
        documented (`types`), the same vocabulary as the filter.
    
        QUERY GUIDANCE:
        Supply 1-2 words that are the most distinctive identifier for the
        manufacturer — the brand name as it appears on the equipment nameplate,
        or a well-known product family. Search runs against a curated keywords
        field, not the manufacturer's full legal name.
    
        Do NOT include:
          - Locality prefixes ("Shenzhen", "Shanghai", "Xiamen")
          - Legal suffixes ("Inc", "Ltd", "Co", "GmbH", "Corp")
          - Generic industry words ("Power", "Energy", "Electric", "Technology",
            "Solar", "New Energy") unless load-bearing in the brand
            (e.g. "SolarEdge", "SunPower", "Canadian Solar").
    
        GOOD queries:
          "Growatt"      → matches Shenzhen Growatt New Energy Co., Ltd.
          "SOSEN"        → matches Shenzhen SOSEN Innovation Technology
          "SolarEdge"    → matches SolarEdge Technologies Ltd.
          "Solis"        → matches Ginlong Technologies (markets as Solis)
          "Bluetti"      → matches Shenzhen Poweroak (markets as Bluetti)
          "Powerwall"    → matches Tesla Inc.
    
        BAD queries:
          "Shenzhen"                              → too generic; matches ~10% of the database
          "Shenzhen Growatt New Energy Co Ltd"    → 5+ words; legal name not brand
          "Energy"                                → generic industry word
    
        If the equipment nameplate shows a model number rather than a brand,
        use `search_models_by_model_number` instead. To enumerate all manufacturers, use
        `list_manufacturers`.
    
        Returns: `{"matches": [{"id": int, "name": str, "confidence":
        float, "types": [str, ...]}, ...]}` sorted by confidence. `types`
        lists the documented equipment types for that brand in the same
        vocabulary as the `equipment_type` filter (so a value can be passed
        straight back); when a filter is supplied every `types` is just
        `[that type]`. Only manufacturers that own at
        least one model with an ingested manual page or extracted
        alert/behavior are returned; CEC-registered manufacturers whose
        models are all stubs (no manual on file) are excluded — when the
        `equipment_type` filter is supplied, the documentation check is
        scoped to that type. Pick the top match (or ask the user to clarify
        if confidence is low or several matches are close) and feed `id` as
        `manufacturer_id` into `search_models_by_model_number` to get a `model_id`.
    
        Args:
            query: 1–2-word brand keyword as the user said it, e.g. "SMA",
                "Fronius", "Enphase", "Tesla", "Powerwall".
            equipment_type (optional): One of "string_inverters",
                "micro_inverters", "batteries". Omit or pass
                `null` to match manufacturers across every equipment type.
                When specified, only manufacturers with at least one
                documented model of that type are considered.
        
    

    Parameters

    NameTypeRequiredDescription
    querystringyes
    equipment_typestringno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_manufacturers",
        "arguments": {
          "query": "example query"
        }
      }
    }
  3. list_models

    List every model for a given manufacturer, optionally filtered by type.

        When to use: the user named a brand but not a specific model, or you
        want to show them what's on file for that brand. If the user did name
        a model, use `search_models_by_model_number` instead.
    
        Prerequisite ids:
          • manufacturer_id — get from `search_manufacturers` (preferred) or
            `list_manufacturers`.
    
        Returns: the unified model envelope shared by all three
        model-discovery tools — `{"matches": [{"marketing_name": str,
        "manufacturer_name": str, "confidence": float, "models":
        [{"model_id": int, "model_name": str, "type": str, "alert_count":
        int, "behavior_count": int, "page_count": int}, ...]}, ...]}`. Each
        match is one marketing-name family; `models` lists every documented
        model under it. Because this is a complete listing (not a ranked
        search), `confidence` is always `1.0` and matches are ordered by
        marketing name. Only documented models appear (CEC stubs excluded),
        so each satisfies `alert_count + behavior_count + page_count > 0`.
        Feed a `model_id` into `list_alerts` / `search_alerts` /
        `list_behaviors` / `search_behaviors` / `search_pages`; use that
        model's counts to pick the lane.
    
        Args:
            manufacturer_id: From `search_manufacturers` or
                `list_manufacturers`.
            equipment_type (optional): One of "string_inverters",
                "micro_inverters", "batteries". Omit or pass
                `null` to return every documented model under this
                manufacturer regardless of type. When specified, restricts
                results to that type only.
        
    

    Parameters

    NameTypeRequiredDescription
    manufacturer_idintegeryes
    equipment_typestringno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "list_models",
        "arguments": {
          "manufacturer_id": 1
        }
      }
    }
  4. search_models_by_model_number

    Fuzzy-match models by registered model number (SKU / part number) within a manufacturer.

        When to use: the user gave you a model number — the catalogue
        identifier (a.k.a. SKU or part number) on the nameplate, e.g.
        "SB5.0-1SP-US-40", "IQ8M-72-M-US", "TR3.6TL-OUTD". If the user gave a
        marketing/family name instead
        ("Sunny Boy 5.0", "IQ7 series", "Powerwall 3"), use
        `search_models_by_marketing_name` — that route does not require a
        manufacturer_id and matches the human-facing name on the cover.
    
        Prerequisite ids:
          • manufacturer_id — get from `search_manufacturers` (preferred) or
            `list_manufacturers`.
    
        Returns: the unified model envelope shared by all three
        model-discovery tools — `{"matches": [{"marketing_name": str,
        "manufacturer_name": str, "confidence": float, "models":
        [{"model_id": int, "model_name": str, "type": str, "alert_count":
        int, "behavior_count": int, "page_count": int}, ...]}, ...]}` sorted
        by confidence. A SKU match surfaces its whole marketing-name family:
        each match's `models` lists every documented model sold under that
        name, and `confidence` is the best matching model's score. Only
        documented models appear (CEC stubs excluded), so each satisfies
        `alert_count + behavior_count + page_count > 0`. Feed a `model_id`
        into `list_alerts` / `search_alerts` / `list_behaviors` /
        `search_behaviors` / `search_pages`; use that model's counts to pick
        the lane.
    
        Args:
            query: Model-number / SKU / part-number string as the user said it.
            manufacturer_id: From `search_manufacturers`.
            equipment_type (optional): One of "string_inverters",
                "micro_inverters", "batteries". Omit or pass
                `null` to match across every documented model under this
                manufacturer. When specified, restricts results to that
                type only.
        
    

    Parameters

    NameTypeRequiredDescription
    querystringyes
    manufacturer_idintegeryes
    equipment_typestringno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_models_by_model_number",
        "arguments": {
          "query": "example query",
          "manufacturer_id": 1
        }
      }
    }
  5. search_models_by_marketing_name

    Fuzzy-match models by the marketing/family name printed on their manuals.

        When to use: the user typed a marketing or family name ("Sunny Boy",
        "IQ7 series", "Powerwall 3") rather than a SKU/part number. SKUs and
        catalogue model numbers should go through `search_models_by_model_number`.
    
        Marketing names are identified per-document by the triage agent at
        ingestion time and stored on the Document row. Results are grouped so
        the unit of each match is a marketing name, with the model numbers
        (SKUs) sold under it nested in a `models` list. A given model number
        may appear under more than one marketing-name match when its documents
        carry different names.
    
        Prerequisite ids: none. `manufacturer_id` is optional — marketing
        names tend to be brand-known on their own ("Sunny Boy" implies
        SMA), so a cold query without picking a brand first usually works.
    
        Returns: `{"matches": [{"marketing_name": str,
        "manufacturer_name": str, "confidence": float, "models":
        [{"model_id": int, "model_name": str, "type": str,
        "alert_count": int, "behavior_count": int, "page_count": int},
        ...]}, ...]}` — one entry per matched marketing name, sorted by
        confidence. The `models` list holds every documented model number
        under that name (CEC-registered stubs are excluded), so each listed
        model satisfies `alert_count + behavior_count + page_count > 0`; a
        marketing name with no documented models is omitted entirely. Feed a
        `model_id` into `list_alerts` / `search_alerts` / `list_behaviors` /
        `search_behaviors` / `search_pages`, and use that model's counts to
        pick the lane: `alert_count > 0` for alerts, `behavior_count > 0` for
        behaviors, `page_count > 0` for pages.
    
        Args:
            query: Marketing or family name as the user said it.
            manufacturer_id (optional): Restrict to one manufacturer (from
                `search_manufacturers` / `list_manufacturers`). Omit to
                search every manufacturer.
            equipment_type (optional): One of "string_inverters",
                "micro_inverters", "batteries". Omit or pass `null` to
                match across every equipment type.
        
    

    Parameters

    NameTypeRequiredDescription
    querystringyes
    manufacturer_idno
    equipment_typestringno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_models_by_marketing_name",
        "arguments": {
          "query": "example query"
        }
      }
    }
  6. list_alerts

    List every documented alert code for one equipment model.

        When to use: the user wants to browse error codes for their model, or
        you want to confirm that an unfamiliar code belongs to this model. If
        the user typed a specific code like "E23" or "F-12-01", prefer
        `search_alerts` — it tolerates formatting differences.
    
        Set `include_details=true` for the "give me the full troubleshooting
        reference for this model" workflow — it returns every alert's full
        record (root cause, recommended actions, page citation) in this same
        call, avoiding a per-id fan-out through `get_alert_details`.
    
        Prerequisite ids:
          • model_id — get from `search_models_by_model_number` (preferred) or `list_models`.
            Only worth calling when that model's `alert_count > 0`; otherwise
            this returns an empty list.
    
        Returns: `{"total": int, "alerts": [{"alert_code_id": int,
        "alert_code": str, "meaning": str, ...}, ...]}`. With
        `include_details=false` (default), each alert has only the three
        summary fields above. With `include_details=true`, each alert is
        additionally enriched with `root_cause`, `recommended_actions`,
        `recommended_action_type`, `document_id`, `page_number` — the same
        shape that `get_alert_details` returns.
    
        Args:
            model_id: From `search_models_by_model_number` or `list_models`.
            include_details: When true, enrich each alert with full
                troubleshooting fields. Default false.
        
    

    Parameters

    NameTypeRequiredDescription
    model_idintegeryes
    include_detailsbooleanno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "list_alerts",
        "arguments": {
          "model_id": 1
        }
      }
    }
  7. search_alerts

    Look up an alert code across a manufacturer's product line by code string.

        When to use: the user typed a specific error/alert code ("E23",
        "F-12-01", "0x80", "ERR07"). This tool does both exact matching and
        code-aware fuzzy matching, so minor formatting differences (case,
        dashes, leading zeros) are OK.
    
        Search the whole product line by passing just `manufacturer_id` +
        `equipment_type`; each match lists every model the code is documented
        for, so you can show the user a code and the models that share it.
        Pass `model_id` to narrow to a single model (its `models` list then
        collapses to that one model) — useful to disambiguate when several
        models surface.
    
        Set `include_details=true` when you already know the user needs the
        full troubleshooting record and want to skip the follow-up
        `get_alert_details` call. Leave it `false` if you intend to confirm
        the match with the user before fetching details.
    
        Prerequisite ids:
          • manufacturer_id (required) — from `search_manufacturers` /
            `list_manufacturers`.
          • model_id (optional) — from `search_models_by_model_number` /
            `search_models_by_marketing_name` / `list_models`, to narrow to
            one model.
    
        Returns: `{"matches": [{"alert_code_id": int, "alert_code": str,
        "meaning": str, "models": [{"model_id": int, "model_name": str},
        ...], ...}, ...]}`. Each match is one documented code; its `models`
        list holds every in-scope model that documents it. With
        `include_details=false` (default), each match has only the summary
        fields above. With `include_details=true`, each match is additionally
        enriched with `root_cause`, `recommended_actions`,
        `recommended_action_type`, `document_id`, `page_number` — the same
        shape that `get_alert_details` returns.
    
        Args:
            alert_code_query: The code as the user typed it, e.g. "E23",
                "F-12-01".
            manufacturer_id: From `search_manufacturers` / `list_manufacturers`.
            equipment_type: One of "string_inverters", "micro_inverters",
                "batteries".
            model_id (optional): Narrow to a single model. Omit to search the
                whole product line.
            include_details: When true, enrich each match with full
                troubleshooting fields. Default false.
        
    

    Parameters

    NameTypeRequiredDescription
    alert_code_querystringyes
    manufacturer_idintegeryes
    equipment_typestringyes
    model_idno
    include_detailsbooleanno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_alerts",
        "arguments": {
          "alert_code_query": "E23",
          "manufacturer_id": 1,
          "equipment_type": "string_inverters"
        }
      }
    }
  8. get_alert_details

    Get the full troubleshooting record for one or more alert codes.

        When to use: after `search_alerts` or `list_alerts` has narrowed the
        user's code(s) to specific `alert_code_id`s, call this to get what to
        actually tell the user — meaning, likely root cause, and the
        manufacturer's recommended actions. Accepts a list so multiple codes
        resolve in a single round trip; a list of one is the explicit
        single-record case. For the "give me the full reference for this
        model" pattern, prefer `list_alerts(model_id, include_details=true)`
        — it returns every alert in one call without needing IDs first.
    
        Prerequisite ids:
          • alert_code_ids — get from `search_alerts` or `list_alerts`.
    
        Returns: `{"results": [{"id": int, "found": bool, "data": {...}?,
        "error": str?}, ...]}`. Response order matches the input order
        exactly (duplicates in the input return duplicate entries). On a hit,
        `data` is `{"alert_code_id": int, "alert_code": str, "meaning": str,
        "root_cause": str | null, "recommended_actions": List[str],
        "recommended_action_type": str, "document_id": int,
        "page_number": int}`; `recommended_actions` is an ordered list (empty
        list if none documented). On a miss, `found: false` and `error:
        "not_found"`. Use `document_id` + `page_number` to cite the manual
        via `get_page_markdown` (text) or `get_page_image` (image).
    
        Batch size is capped at 50 IDs per call; exceeding the cap returns a
        top-level `{"error": "too_many_ids", "message": str}` with no
        partial results. An empty list returns `{"results": []}`.
    
        Args:
            alert_code_ids: From `search_alerts` or `list_alerts`. Up to 50
                IDs per call.
        
    

    Parameters

    NameTypeRequiredDescription
    alert_code_idsarrayyes

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "get_alert_details",
        "arguments": {
          "alert_code_ids": [
            1
          ]
        }
      }
    }
  9. list_behaviors

    List every documented fault behavior for one equipment model.

        "Fault behaviors" are observable symptoms that are not numbered alert
        codes — things like "red LED flashing", "unit will not power on",
        "display reads NO AC". They are extracted from the manual as a
        separate category from alert codes.
    
        When to use: the user wants to browse the symptom catalogue for their
        model, or you want to confirm a described symptom is in the manual.
        If the user described a specific symptom in words, prefer
        `search_behaviors` — it uses semantic search.
    
        Set `include_details=true` for the "give me the full troubleshooting
        reference for this model" workflow — it returns every behavior's
        full record (root cause, recommended actions, page citation) in this
        same call, avoiding a per-id fan-out through `get_behavior_details`.
    
        Prerequisite ids:
          • model_id — get from `search_models_by_model_number` (preferred) or `list_models`.
            Only worth calling when that model's `behavior_count > 0`;
            otherwise this returns an empty list.
    
        Returns: `{"total": int, "behaviors": [{"behavior_id": int,
        "behavior_description": str, ...}, ...]}`. With
        `include_details=false` (default), each behavior has only the two
        summary fields above. With `include_details=true`, each behavior is
        additionally enriched with `meaning`, `root_cause`,
        `recommended_actions`, `recommended_action_type`, `document_id`,
        `page_number` — the same shape that `get_behavior_details` returns.
    
        Args:
            model_id: From `search_models_by_model_number` or `list_models`.
            include_details: When true, enrich each behavior with full
                troubleshooting fields. Default false.
        
    

    Parameters

    NameTypeRequiredDescription
    model_idintegeryes
    include_detailsbooleanno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "list_behaviors",
        "arguments": {
          "model_id": 1
        }
      }
    }
  10. search_behaviors

    Semantic search for a fault behavior across a manufacturer's product line.

        When to use: the user described a symptom in words rather than
        reading off an alert code — e.g. "the red LED is flashing once a
        second", "it won't turn on", "shows dashes on the display". Pass
        their natural description as `description`; the tool uses vector
        embeddings to find the closest documented behaviors.
    
        Search the whole product line by passing just `manufacturer_id` +
        `equipment_type`; each match lists every model the behavior is
        documented for. Pass `model_id` to narrow to a single model (its
        `models` list then collapses to that one model).
    
        Set `include_details=true` when you already know the user needs the
        full troubleshooting record and want to skip the follow-up
        `get_behavior_details` call. Leave it `false` if you intend to
        confirm the match with the user before fetching details.
    
        Prerequisite ids:
          • manufacturer_id (required) — from `search_manufacturers` /
            `list_manufacturers`.
          • model_id (optional) — from `search_models_by_model_number` /
            `search_models_by_marketing_name` / `list_models`, to narrow to
            one model.
    
        Returns: `{"matches": [{"behavior_id": int,
        "behavior_description": str, "document_filename": str,
        "confidence": float, "models": [{"model_id": int, "model_name":
        str}, ...], ...}, ...]}` sorted by confidence. Each match's `models`
        list holds every in-scope model that documents the behavior. With
        `include_details=false` (default), each match has only the summary
        fields above. With `include_details=true`, each match is additionally
        enriched with `meaning`, `root_cause`, `recommended_actions`,
        `recommended_action_type`, `document_id`, `page_number` — the same
        shape that `get_behavior_details` returns (the ranking fields
        `document_filename` and `confidence` are kept). If no match is
        returned, try `search_pages` as a free-text fallback.
    
        Args:
            description: Natural-language description of what the user sees
                or hears.
            manufacturer_id: From `search_manufacturers` / `list_manufacturers`.
            equipment_type: One of "string_inverters", "micro_inverters",
                "batteries".
            model_id (optional): Narrow to a single model. Omit to search the
                whole product line.
            include_details: When true, enrich each match with full
                troubleshooting fields. Default false.
        
    

    Parameters

    NameTypeRequiredDescription
    descriptionstringyes
    manufacturer_idintegeryes
    equipment_typestringyes
    model_idno
    include_detailsbooleanno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_behaviors",
        "arguments": {
          "description": "red led blinking",
          "manufacturer_id": 1,
          "equipment_type": "string_inverters"
        }
      }
    }
  11. get_behavior_details

    Get the full troubleshooting record for one or more fault behaviors.

        When to use: after `search_behaviors` or `list_behaviors` has
        narrowed the user's described symptom(s) to specific `behavior_id`s,
        call this to get what to actually tell the user — meaning, likely
        root cause, and the manufacturer's recommended actions. Accepts a
        list so multiple behaviors resolve in a single round trip; a list of
        one is the explicit single-record case. For the "give me the full
        reference for this model" pattern, prefer
        `list_behaviors(model_id, include_details=true)` — it returns every
        behavior in one call without needing IDs first.
    
        Prerequisite ids:
          • behavior_ids — get from `search_behaviors` or `list_behaviors`.
    
        Returns: `{"results": [{"id": int, "found": bool, "data": {...}?,
        "error": str?}, ...]}`. Response order matches the input order
        exactly (duplicates in the input return duplicate entries). On a
        hit, `data` is `{"behavior_id": int, "behavior_description": str,
        "meaning": str, "root_cause": str | null, "recommended_actions":
        List[str], "recommended_action_type": str, "document_id": int,
        "page_number": int}`; `recommended_actions` is an ordered list
        (empty list if none documented). On a miss, `found: false` and
        `error: "not_found"`. Use `document_id` + `page_number` to cite the
        manual via `get_page_markdown` or `get_page_image`.
    
        Batch size is capped at 50 IDs per call; exceeding the cap returns a
        top-level `{"error": "too_many_ids", "message": str}` with no
        partial results. An empty list returns `{"results": []}`.
    
        Args:
            behavior_ids: From `search_behaviors` or `list_behaviors`. Up to
                50 IDs per call.
        
    

    Parameters

    NameTypeRequiredDescription
    behavior_idsarrayyes

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "get_behavior_details",
        "arguments": {
          "behavior_ids": [
            1
          ]
        }
      }
    }
  12. search_pages

    Free-text semantic search across all manual pages for one model.

        When to use: as a **fallback** when `search_alerts` and
        `search_behaviors` both come back empty, or when the user's question
        is not a specific code or symptom (e.g. "how do I ground this unit",
        "what does the install look like"). Returns raw manual snippets, not
        structured answers, so prefer the alert/behavior tools first.
    
        Prerequisite ids:
          • model_id — get from `search_models_by_model_number` (preferred) or `list_models`.
            Only worth calling when that model's `page_count > 0`;
            otherwise this returns an empty list.
    
        Returns: `{"matches": [{"document_id": int,
        "document_filename": str, "page_number": int, "confidence": float,
        "snippet": str}, ...]}`. Feed `document_id` + `page_number` into
        `get_page_markdown` for the full page text, or `get_page_image` to
        show the page to the user.
    
        Args:
            query: Natural-language description of the topic you are
                looking for.
            model_id: From `search_models_by_model_number` or `list_models`.
            top_n: Maximum number of pages to return, 1-20. Default 5.
        
    

    Parameters

    NameTypeRequiredDescription
    querystringyes
    model_idintegeryes
    top_nintegerno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "search_pages",
        "arguments": {
          "query": "example query",
          "model_id": 1
        }
      }
    }
  13. get_page_markdown

    Fetch the extracted markdown text of one manual page.

        When to use: to cite a source to the user or to read more surrounding
        context than `get_alert_details` / `get_behavior_details` give you.
        Any extracted image/chart descriptions for the page are appended
        under a "PAGE IMAGE AND CHART DESCRIPTIONS" section.
    
        Prerequisite ids:
          • document_id and page_number together — get from
            `get_alert_details`, `get_behavior_details`, or any
            `search_pages` match.
    
        Returns: `{"document_id": int, "page_number": int,
        "markdown": str}`.
    
        Args:
            document_id: From a `get_*_details` result or `search_pages`
                match.
            page_number: 1-indexed page number from the same source.
        
    

    Parameters

    NameTypeRequiredDescription
    document_idintegeryes
    page_numberintegeryes

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "get_page_markdown",
        "arguments": {
          "document_id": 1,
          "page_number": 1
        }
      }
    }
  14. get_page_image

    Fetch the rendered image of one manual page.

        When to use: the user wants to *see* a page — a wiring diagram, a
        status-light chart, the layout of a terminal block, etc. Prefer
        `get_page_markdown` for text-only answers (it is cheaper and easier
        to quote from).
    
        Prerequisite ids:
          • document_id and page_number together — get from
            `get_alert_details`, `get_behavior_details`, or any
            `search_pages` match.
    
        Returns: an MCP `Image` containing the page bitmap (PNG/JPEG).
    
        Args:
            document_id: From a `get_*_details` result or `search_pages`
                match.
            page_number: 1-indexed page number from the same source.
        
    

    Parameters

    NameTypeRequiredDescription
    document_idintegeryes
    page_numberintegeryes

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "get_page_image",
        "arguments": {
          "document_id": 1,
          "page_number": 1
        }
      }
    }
  15. explain_alert_text

    Look up which documented alert patterns most resemble a raw alert string (experimental).

        When to use: LAST-RESORT fallback, only after the normal workflow
        dead-ends — the user's manufacturer/model could not be identified,
        or `search_alerts` / `search_behaviors` / `search_pages` returned
        nothing for their equipment. It searches a labelled corpus of alert
        records across ALL manufacturers, so it works when no manual is on
        file — but it returns generic documented patterns, not the user's
        manual.
    
        This is a co-occurrence lookup, NOT a diagnosis. The tool finds the
        (component, state, automated_response) combinations actually
        recorded together in manuals that read most like `alert_text`, and
        lists the operator actions those alerts were documented alongside.
        Every figure is a documentation frequency or a text-similarity
        score — never a probability that this is the user's actual fault.
        Present results as "alerts like this are commonly associated
        with ...", never as a confirmed cause.
    
        Returns: `{"query": str, "hardware_scope": str, "method": str,
        "match_method": "embedding" | "lexical", "matches": [{"summary":
        str, "pattern": str, "component": str|null, "state": str|null,
        "automated_response": str|null, "times_documented": int,
        "text_similarity": float, "match": str, "commonly_associated_actions":
        [{"action": str, "co_occurrences": int}, ...]}, ...]}` sorted by
        similarity. `times_documented` is how many corpus alerts fit the
        pattern; each action's `co_occurrences` is how many of those also
        recorded that action.
    
        Args:
            alert_text: The user's raw alert/error/fault text, as they
                reported it (e.g. "Fault F032: PV insulation resistance too
                low at startup").
            hardware_type (optional): One of "string_inverters",
                "micro_inverters", "batteries". Omit to search all three.
            top: Maximum number of pattern matches to return (1-10,
                default 4).
        
    

    Parameters

    NameTypeRequiredDescription
    alert_textstringyes
    hardware_typestringno
    topintegerno

    Example call

    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "tools/call",
      "params": {
        "name": "explain_alert_text",
        "arguments": {
          "alert_text": "example"
        }
      }
    }