Skip to main content
Glama
echelongraph

EchelonGraph MCP Server

Official

Search CVEs

search_cves
Read-onlyIdempotent

Search and filter CVEs from an aggregated feed (NVD, MITRE, CISA KEV, EPSS, GHSA) by severity, CVSS, text, and sort; returns CVE details with scores and KEV/EPSS data.

Instructions

Search/list CVEs from EchelonGraph's CVE feed (NVD + MITRE-CNA pre-NVD + CISA-KEV + EPSS + GitHub GHSA, each polled on a schedule). Filter by severity, minimum CVSS, free text, and sort; page with limit and offset. Returns cves, each with cve_id, severity, cvss_v3_score, echelongraph_score and score_assessed (whether EchelonGraph has scored it), epss_score and kev_listed where the record has them, and the list's total, total_counted (false: total is not a count), total_is_lower_bound (true: at least total), search_relaxed, limit and offset. echelongraph_score, echelongraph_severity and echelongraph_risk are EchelonGraph's score only when score_assessed is true. With score_assessed false the CVE is NOT YET SCORED, not scored 0: any of those three it carries (0, NONE, 0) is a placeholder, not a rating, and does not mean the CVE is harmless; score_unassessed_reason says why, and the note labels each such CVE NOT YET SCORED. An answer with no score_assessed (an API older than that field) does not say whether the CVE was scored, the note says so, and a 0 there is not a rating either. patch_available is true when EchelonGraph holds, or once held, fix evidence for the CVE; patch_evidence is what it holds now, strongest first. patch_available false means no fix evidence is on record, which is not a finding that no fix exists. Its freshness is null: the feed serves no poll-completion time. Past 30,000 characters of JSON, the first text block holds data cut to fit, and the note says what the cut leaves out and where to read it (TEXT CUT); so is structured data (DATA CUT), unless full: true. Cut, each row keeps at least the fields named above and the first 200 characters of its description (100 on a page too long for that), or rows are left out and the note gives the offset to call next.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fullNotrue: data in the structured result is the answer whole, however long. Without it, a structured result past 30,000 characters of JSON has its data cut (DATA CUT): in an order the note states, the entries of its longest lists keep only some of their fields, and then the lists only some of their entries; data_truncated is true, and truncated gives each list cut with its total, the number returned and whether its entries are thinned. Whole data is for a program; a client that sizes structured results, as Claude Code does against MAX_MCP_OUTPUT_TOKENS, can refuse an answer past its cap.
sortNosort order (default: published)
limitNopage size (default 20, max 50)
offsetNorows to skip (default 0)
searchNofree-text search (product, vendor, or keyword, e.g. 'tomcat')
min_cvssNominimum CVSS score
severityNofilter to one severity

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changedv3.0.2
    • addedInput schema / properties / full
      Added value: +{
      +  "description": "true: data in the structured result is the answer whole, however long. Without it, a structured result past 30,000 characters of JSON has its data cut (DATA CUT): in an order the note states, the entries of its longest lists keep only some of their fields, and then the lists only some of their entries; data_truncated is true, and truncated gives each list cut with its total, the number returned and whether its entries are thinned. Whole data is for a program; a client that sizes structured results, as Claude Code does against MAX_MCP_OUTPUT_TOKENS, can refuse an answer past its cap.",
      +  "type": "boolean"
      +}
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "limit": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "offset": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "returned": {
      -                "description": "The rows in this page.",
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "search_relaxed": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "total_counted": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total_is_lower_bound": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              }
      -            },
      -            "required": [
      -              "total",
      -              "total_counted",
      -              "total_is_lower_bound",
      -              "search_relaxed",
      -              "returned",
      -              "limit",
      -              "offset"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "What the answer covers; null where the answer says nothing about it."
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cves": {
      -            "items": {
      -              "additionalProperties": {},
      -              "properties": {
      -                "cpe_configurations": {
      -                  "anyOf": [
      -                    {
      -                      "items": {},
      -                      "type": "array"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -                },
      -                "cpe_match": {
      -                  "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -                },
      -                "cve_id": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "cvss_v3_score": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "cvss_v4_score": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "cvss_v4_severity": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "description": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "echelongraph_risk": {
      -                  "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "echelongraph_score": {
      -                  "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "echelongraph_severity": {
      -                  "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "epss_percentile": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "epss_score": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "ghsa_id": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "kev_added_date": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "kev_due_date": {
      -                  "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "kev_listed": {
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "kev_notes_urls": {
      -                  "anyOf": [
      -                    {
      -                      "items": {
      -                        "type": "string"
      -                      },
      -                      "type": "array"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      -                },
      -                "kev_ransomware": {
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "kev_required_action": {
      -                  "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 22-01, by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "kev_short_description": {
      -                  "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "modified": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "patch_available": {
      -                  "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "patch_evidence": {
      -                  "anyOf": [
      -                    {
      -                      "items": {
      -                        "anyOf": [
      -                          {
      -                            "enum": [
      -                              "vendor_patch",
      -                              "fixed_version",
      -                              "release_reference",
      -                              "nvd_patch_reference",
      -                              "cna_patch_reference"
      -                            ],
      -                            "type": "string"
      -                          },
      -                          {
      -                            "type": "string"
      -                          }
      -                        ]
      -                      },
      -                      "type": "array"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), nvd_patch_reference (an NVD reference tagged Patch) and cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      -                },
      -                "published": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "references": {},
      -                "remediation": {
      -                  "anyOf": [
      -                    {
      -                      "additionalProperties": {},
      -                      "properties": {},
      -                      "type": "object"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      -                },
      -                "score_assessed": {
      -                  "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "score_confidence": {
      -                  "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "score_unassessed_reason": {
      -                  "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "severity": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "updated_at": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                }
      -              },
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "limit": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "offset": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "search_relaxed": {
      -            "description": "true: a search phrase was relaxed to all of its words.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "total": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "total_counted": {
      -            "description": "false: the matches were not counted, so total is not a count.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "total_is_lower_bound": {
      -            "description": "true: there are at least total matches.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "limit": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "offset": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "returned": {
      -                "description": "The rows in this page.",
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "search_relaxed": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "total_counted": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total_is_lower_bound": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              }
      -            },
      -            "required": [
      -              "total",
      -              "total_counted",
      -              "total_is_lower_bound",
      -              "search_relaxed",
      -              "returned",
      -              "limit",
      -              "offset"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": {},
      +    "properties": {
      +      "coverage": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "limit": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "offset": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "returned": {
      +                "description": "The rows in this page.",
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "search_relaxed": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "total_counted": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total_is_lower_bound": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "total",
      +              "total_counted",
      +              "total_is_lower_bound",
      +              "search_relaxed",
      +              "returned",
      +              "limit",
      +              "offset"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "What the answer covers; null where the answer says nothing about it."
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cves": {
      +            "items": {
      +              "additionalProperties": {},
      +              "properties": {
      +                "cna": {
      +                  "anyOf": [
      +                    {
      +                      "additionalProperties": {},
      +                      "properties": {
      +                        "name": {
      +                          "type": [
      +                            "string",
      +                            "null"
      +                          ]
      +                        },
      +                        "short_name": {
      +                          "type": [
      +                            "string",
      +                            "null"
      +                          ]
      +                        }
      +                      },
      +                      "type": "object"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "The CNA that wrote the CVE record: short_name as the record gives it, and name, the CVE Program's name for that CNA (the short name where its list does not hold it). Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field."
      +                },
      +                "cna_solution": {
      +                  "description": "The sentence of the CVE record's solutions or workarounds, written by its CNA, that names a released fix, verbatim: what makes cna_solution patch evidence. It is the CNA's text, not EchelonGraph's advice. cna_solution_section says which of the two sections it is. Absent where the record's solutions name no fixed version, as well as where the field itself is: Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "cna_solution_section": {
      +                  "anyOf": [
      +                    {
      +                      "anyOf": [
      +                        {
      +                          "enum": [
      +                            "solution",
      +                            "workaround"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        {
      +                          "type": "string"
      +                        }
      +                      ]
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "Which section of the CVE record cna_solution was read from: solution (the record's solutions) or workaround (its workarounds, read only where its solutions name no fix: a temporary measure the CNA lists beside its fix). A workaround's sentence is the record's workaround, never its solution. Present whenever cna_solution is; absent from an API older than the field."
      +                },
      +                "cpe_configurations": {
      +                  "anyOf": [
      +                    {
      +                      "items": {},
      +                      "type": "array"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +                },
      +                "cpe_match": {
      +                  "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +                },
      +                "cve_id": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "cvss_v3_score": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "cvss_v4_score": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "cvss_v4_severity": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "date_public": {
      +                  "description": "When the vulnerability was made public, as the CVE record's CNA states it (the record's datePublic: \"if known, the date/time the vulnerability was disclosed publicly\"). It is the CNA's date, not the record's own publication date, which is published. Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "date_public_source": {
      +                  "description": "Whose date date_public is: cna, the CVE record's CNA. Absent whenever date_public is.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "description": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_risk": {
      +                  "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_score": {
      +                  "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_severity": {
      +                  "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_ssvc_decision": {
      +                  "description": "The SSVC decision (Act, Attend, Track* or Track) EchelonGraph computes with CISA's decision table at medium mission impact. CISA publishes the table and, for some CVEs, its inputs, not a decision for a CVE. score_factors.ssvc gives the decision at low, medium and high mission impact, with each input and its source.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "epss_percentile": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "epss_score": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "ghsa_id": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_added_date": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_due_date": {
      +                  "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_listed": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "kev_notes_urls": {
      +                  "anyOf": [
      +                    {
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      +                },
      +                "kev_ransomware": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "kev_required_action": {
      +                  "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 26-04 (which replaced BOD 22-01 on 10 June 2026), by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_short_description": {
      +                  "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "modified": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "patch_available": {
      +                  "description": "true: EchelonGraph holds, or once held, evidence of a fix for the CVE; patch_evidence names the sources it holds now. true beside an empty patch_evidence means evidence of a fix once held has since been withdrawn (patch_available is never set back to false), and fix_status (remediation.fix_status in the CVE's record) is the current reading, not patch_available. false: no fix evidence is on record, which is not a finding that no fix exists. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "patch_evidence": {
      +                  "anyOf": [
      +                    {
      +                      "items": {
      +                        "anyOf": [
      +                          {
      +                            "enum": [
      +                              "vendor_patch",
      +                              "fixed_version",
      +                              "release_reference",
      +                              "vendor_advisory_fix",
      +                              "nvd_patch_reference",
      +                              "cna_patch_reference",
      +                              "cna_solution",
      +                              "description_fix",
      +                              "vendor_fix_released"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "string"
      +                          }
      +                        ]
      +                      },
      +                      "type": "array"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), vendor_advisory_fix (a vendor advisory that lists a fix for the CVE under the vendor's own structured category: Red Hat's CSAF vendor_fix, Microsoft's Vendor Fix), nvd_patch_reference (an NVD reference tagged Patch), cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record), cna_solution (a sentence of the CVE record's solutions or workarounds, written by its CNA, that names a fixed version; relayed as cna_solution), description_fix (a sentence of the CVE description that names a fixed version) and vendor_fix_released (the vendor states, in the CVE record, that a fix is released and the record names no fixed version; check the vendor's advisory). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +                },
      +                "published": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "references": {},
      +                "remediation": {
      +                  "anyOf": [
      +                    {
      +                      "additionalProperties": {},
      +                      "properties": {
      +                        "fix_status": {
      +                          "anyOf": [
      +                            {
      +                              "additionalProperties": {},
      +                              "properties": {
      +                                "basis": {
      +                                  "type": [
      +                                    "string",
      +                                    "null"
      +                                  ]
      +                                },
      +                                "described_by": {
      +                                  "type": [
      +                                    "string",
      +                                    "null"
      +                                  ]
      +                                },
      +                                "listed_in_patch_table": {
      +                                  "type": [
      +                                    "boolean",
      +                                    "null"
      +                                  ]
      +                                },
      +                                "solution_by": {
      +                                  "anyOf": [
      +                                    {
      +                                      "additionalProperties": {},
      +                                      "properties": {
      +                                        "cna": {
      +                                          "type": [
      +                                            "string",
      +                                            "null"
      +                                          ]
      +                                        },
      +                                        "section": {
      +                                          "type": [
      +                                            "string",
      +                                            "null"
      +                                          ]
      +                                        },
      +                                        "statement": {
      +                                          "type": [
      +                                            "string",
      +                                            "null"
      +                                          ]
      +                                        }
      +                                      },
      +                                      "type": "object"
      +                                    },
      +                                    {
      +                                      "type": "null"
      +                                    }
      +                                  ]
      +                                },
      +                                "state": {
      +                                  "anyOf": [
      +                                    {
      +                                      "anyOf": [
      +                                        {
      +                                          "enum": [
      +                                            "available",
      +                                            "fix_referenced",
      +                                            "fix_merged",
      +                                            "none_confirmed",
      +                                            "unknown"
      +                                          ],
      +                                          "type": "string"
      +                                        },
      +                                        {
      +                                          "type": "string"
      +                                        }
      +                                      ]
      +                                    },
      +                                    {
      +                                      "type": "null"
      +                                    }
      +                                  ]
      +                                },
      +                                "stated_in_record": {
      +                                  "type": [
      +                                    "boolean",
      +                                    "null"
      +                                  ]
      +                                },
      +                                "unread_inputs": {
      +                                  "anyOf": [
      +                                    {
      +                                      "items": {
      +                                        "type": "string"
      +                                      },
      +                                      "type": "array"
      +                                    },
      +                                    {
      +                                      "type": "null"
      +                                    }
      +                                  ]
      +                                },
      +                                "vendor_released": {
      +                                  "anyOf": [
      +                                    {
      +                                      "additionalProperties": {},
      +                                      "properties": {
      +                                        "statement": {
      +                                          "type": [
      +                                            "string",
      +                                            "null"
      +                                          ]
      +                                        }
      +                                      },
      +                                      "type": "object"
      +                                    },
      +                                    {
      +                                      "type": "null"
      +                                    }
      +                                  ]
      +                                }
      +                              },
      +                              "type": "object"
      +                            },
      +                            {
      +                              "type": "null"
      +                            }
      +                          ],
      +                          "description": "The API's fix-status rule for the CVE, the one CVE Pulse pages show: state is available (a fix is on record), fix_referenced (a reference tagged Patch, often a source commit, and no release confirmed), fix_merged (an upstream fix merged, not yet in a tagged release), none_confirmed (no fix evidence on record, which is not a finding that no fix exists) or unknown (an input could not be read). basis is the step of the rule that decided it; described_by is the CVE description's sentence naming the fix, solution_by the CVE record's solution sentence naming it (statement) and the CNA that wrote it (cna), stated_in_record that patch_evidence counts a fix the CVE record states with no sentence to quote, listed_in_patch_table that a fixed version or patch row is on record; unread_inputs names any input the API could not read. vendor_released (basis vendor_fix_released) is the vendor's own statement that a fix is released where the CVE record names no fixed version: its sentence, verbatim (statement, or null), never a version, so the fixed release is the vendor advisory's to name. solution_by's section is workarounds when the fix sentence is the record's workaround, not its solution."
      +                        }
      +                      },
      +                      "type": "object"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: fix_status first (the API's fix-status rule: state, basis, described_by, solution_by, stated_in_record, listed_in_patch_table and unread_inputs), vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation by NVD, or patch or mitigation by the CNA), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      +                },
      +                "score_assessed": {
      +                  "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "score_confidence": {
      +                  "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "score_factors": {
      +                  "description": "EchelonGraph's evidence for its score. ssvc: the SSVC decision at every mission impact level, each input with its source. bod_26_04 (scorer v3.4 and later): CISA BOD 26-04's remediation timeline, if_publicly_exposed and if_not_publicly_exposed, each a list of CERT/CC's keys (3DF, 3D, 14D, 60D, FSU) named in timelines, with kev, automatable and technical_impact, each with its source; source cisa_bod_26_04_default is CISA's own default for a CVE not in KEV that nobody has assessed."
      +                },
      +                "score_unassessed_reason": {
      +                  "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "severity": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "updated_at": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                }
      +              },
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "limit": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "offset": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "search_relaxed": {
      +            "description": "true: a search phrase was relaxed to all of its words.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "total": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "total_counted": {
      +            "description": "false: the matches were not counted, so total is not a count.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "total_is_lower_bound": {
      +            "description": "true: there are at least total matches.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "data_truncated": {
      +        "description": "false: data is the answer whole. true: the structured result would pass 30,000 characters of JSON with data whole, so data is cut (DATA CUT): the entries of some of its lists keep only some of their fields, or the lists only some of their entries, truncated gives each, and no string is shortened. The same call with full: true returns data whole.",
      +        "type": "boolean"
      +      },
      +      "freshness": {
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      },
      +      "truncated": {
      +        "additionalProperties": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "returned": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "thinned": {
      +              "const": true,
      +              "type": "boolean"
      +            },
      +            "total": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "total",
      +            "returned"
      +          ],
      +          "type": "object"
      +        },
      +        "description": "Present when data_truncated is true: each list of data that was cut, by its path in data (a dot between the names of an object and a list inside it), with total, its entries in the answer, returned, the entries data holds, and thinned, true when each of them keeps only some of its fields.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data_truncated",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "limit": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "offset": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "returned": {
      +                "description": "The rows in this page.",
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "search_relaxed": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "total_counted": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total_is_lower_bound": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "total",
      +              "total_counted",
      +              "total_is_lower_bound",
      +              "search_relaxed",
      +              "returned",
      +              "limit",
      +              "offset"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Changed1 schema field changedv2.7.0
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "limit": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "offset": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "returned": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "search_relaxed": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "total_counted": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total_is_lower_bound": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              }
      -            },
      -            "required": [
      -              "total",
      -              "total_counted",
      -              "total_is_lower_bound",
      -              "search_relaxed",
      -              "returned",
      -              "limit",
      -              "offset"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "What the answer covers; null where the answer says nothing about it."
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cves": {
      -            "items": {
      -              "additionalProperties": {},
      -              "properties": {
      -                "cpe_configurations": {
      -                  "anyOf": [
      -                    {
      -                      "items": {},
      -                      "type": "array"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -                },
      -                "cpe_match": {
      -                  "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -                },
      -                "cve_id": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "cvss_v3_score": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "cvss_v4_score": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "cvss_v4_severity": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "description": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "echelongraph_risk": {
      -                  "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "echelongraph_score": {
      -                  "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "echelongraph_severity": {
      -                  "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "epss_percentile": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "epss_score": {
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "ghsa_id": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "kev_added_date": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "kev_listed": {
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "kev_ransomware": {
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "modified": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "published": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "references": {},
      -                "score_assessed": {
      -                  "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -                  "type": [
      -                    "boolean",
      -                    "null"
      -                  ]
      -                },
      -                "score_confidence": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "score_unassessed_reason": {
      -                  "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "severity": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                },
      -                "updated_at": {
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                }
      -              },
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "limit": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "offset": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "search_relaxed": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "total": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "total_counted": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "total_is_lower_bound": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "limit": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "offset": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "returned": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "search_relaxed": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "total_counted": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              },
      -              "total_is_lower_bound": {
      -                "type": [
      -                  "boolean",
      -                  "null"
      -                ]
      -              }
      -            },
      -            "required": [
      -              "total",
      -              "total_counted",
      -              "total_is_lower_bound",
      -              "search_relaxed",
      -              "returned",
      -              "limit",
      -              "offset"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "limit": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "offset": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "returned": {
      +                "description": "The rows in this page.",
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "search_relaxed": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "total_counted": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total_is_lower_bound": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "total",
      +              "total_counted",
      +              "total_is_lower_bound",
      +              "search_relaxed",
      +              "returned",
      +              "limit",
      +              "offset"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "What the answer covers; null where the answer says nothing about it."
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cves": {
      +            "items": {
      +              "additionalProperties": {},
      +              "properties": {
      +                "cpe_configurations": {
      +                  "anyOf": [
      +                    {
      +                      "items": {},
      +                      "type": "array"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +                },
      +                "cpe_match": {
      +                  "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +                },
      +                "cve_id": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "cvss_v3_score": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "cvss_v4_score": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "cvss_v4_severity": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "description": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_risk": {
      +                  "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_score": {
      +                  "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "echelongraph_severity": {
      +                  "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "epss_percentile": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "epss_score": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "ghsa_id": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_added_date": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_due_date": {
      +                  "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_listed": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "kev_notes_urls": {
      +                  "anyOf": [
      +                    {
      +                      "items": {
      +                        "type": "string"
      +                      },
      +                      "type": "array"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      +                },
      +                "kev_ransomware": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "kev_required_action": {
      +                  "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 22-01, by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "kev_short_description": {
      +                  "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "modified": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "patch_available": {
      +                  "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "patch_evidence": {
      +                  "anyOf": [
      +                    {
      +                      "items": {
      +                        "anyOf": [
      +                          {
      +                            "enum": [
      +                              "vendor_patch",
      +                              "fixed_version",
      +                              "release_reference",
      +                              "nvd_patch_reference",
      +                              "cna_patch_reference"
      +                            ],
      +                            "type": "string"
      +                          },
      +                          {
      +                            "type": "string"
      +                          }
      +                        ]
      +                      },
      +                      "type": "array"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), nvd_patch_reference (an NVD reference tagged Patch) and cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +                },
      +                "published": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "references": {},
      +                "remediation": {
      +                  "anyOf": [
      +                    {
      +                      "additionalProperties": {},
      +                      "properties": {},
      +                      "type": "object"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      +                },
      +                "score_assessed": {
      +                  "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "score_confidence": {
      +                  "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "score_unassessed_reason": {
      +                  "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "severity": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                },
      +                "updated_at": {
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                }
      +              },
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "limit": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "offset": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "search_relaxed": {
      +            "description": "true: a search phrase was relaxed to all of its words.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "total": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "total_counted": {
      +            "description": "false: the matches were not counted, so total is not a count.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "total_is_lower_bound": {
      +            "description": "true: there are at least total matches.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "limit": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "offset": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "returned": {
      +                "description": "The rows in this page.",
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "search_relaxed": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "total_counted": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              "total_is_lower_bound": {
      +                "type": [
      +                  "boolean",
      +                  "null"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "total",
      +              "total_counted",
      +              "total_is_lower_bound",
      +              "search_relaxed",
      +              "returned",
      +              "limit",
      +              "offset"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  3. Changed4 schema fields changedv2.6.3
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • removedInput schema / additionalProperties
      Removed value: -false
    • addedInput schema / properties / offset
      Added value: +{
      +  "description": "rows to skip (default 0)",
      +  "maximum": 10000,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "oneOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "coverage": {
      +          "anyOf": [
      +            {
      +              "additionalProperties": false,
      +              "properties": {
      +                "limit": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "offset": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "returned": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "search_relaxed": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "total": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "total_counted": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "total_is_lower_bound": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                }
      +              },
      +              "required": [
      +                "total",
      +                "total_counted",
      +                "total_is_lower_bound",
      +                "search_relaxed",
      +                "returned",
      +                "limit",
      +                "offset"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "What the answer covers; null where the answer says nothing about it."
      +        },
      +        "data": {
      +          "additionalProperties": {},
      +          "properties": {
      +            "cves": {
      +              "items": {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "cpe_configurations": {
      +                    "anyOf": [
      +                      {
      +                        "items": {},
      +                        "type": "array"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +                  },
      +                  "cpe_match": {
      +                    "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +                  },
      +                  "cve_id": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "cvss_v3_score": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "cvss_v4_score": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "cvss_v4_severity": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "description": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "echelongraph_risk": {
      +                    "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "echelongraph_score": {
      +                    "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "echelongraph_severity": {
      +                    "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "epss_percentile": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "epss_score": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "ghsa_id": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "kev_added_date": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "kev_listed": {
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "kev_ransomware": {
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "modified": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "published": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "references": {},
      +                  "score_assessed": {
      +                    "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "score_confidence": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "score_unassessed_reason": {
      +                    "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "severity": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "updated_at": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "type": "array"
      +            },
      +            "limit": {
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "offset": {
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "search_relaxed": {
      +              "type": [
      +                "boolean",
      +                "null"
      +              ]
      +            },
      +            "total": {
      +              "type": [
      +                "number",
      +                "null"
      +              ]
      +            },
      +            "total_counted": {
      +              "type": [
      +                "boolean",
      +                "null"
      +              ]
      +            },
      +            "total_is_lower_bound": {
      +              "type": [
      +                "boolean",
      +                "null"
      +              ]
      +            }
      +          },
      +          "type": "object"
      +        },
      +        "freshness": {
      +          "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +          "type": "null"
      +        },
      +        "measured_at": {
      +          "anyOf": [
      +            {
      +              "description": "An RFC 3339 instant.",
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +        },
      +        "method": {
      +          "description": "How the numbers were produced.",
      +          "type": "string"
      +        },
      +        "notes": {
      +          "description": "Caveats, one sentence each.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "state": {
      +          "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +          "enum": [
      +            "measured",
      +            "not_assessed"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "state",
      +        "measured_at",
      +        "method",
      +        "coverage",
      +        "freshness",
      +        "notes",
      +        "data"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "coverage": {
      +          "anyOf": [
      +            {
      +              "additionalProperties": false,
      +              "properties": {
      +                "limit": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "offset": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "returned": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "search_relaxed": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "total": {
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "total_counted": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                },
      +                "total_is_lower_bound": {
      +                  "type": [
      +                    "boolean",
      +                    "null"
      +                  ]
      +                }
      +              },
      +              "required": [
      +                "total",
      +                "total_counted",
      +                "total_is_lower_bound",
      +                "search_relaxed",
      +                "returned",
      +                "limit",
      +                "offset"
      +              ],
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ]
      +        },
      +        "error": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "kind": {
      +              "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +              "enum": [
      +                "network",
      +                "timeout",
      +                "http",
      +                "not_json",
      +                "not_object",
      +                "invalid_input",
      +                "internal",
      +                "unexpected_shape",
      +                "radars"
      +              ],
      +              "type": "string"
      +            },
      +            "message": {
      +              "description": "The cause: the API's own message, or what went wrong.",
      +              "type": "string"
      +            },
      +            "path": {
      +              "description": "The API path requested, when a request was made.",
      +              "type": [
      +                "string",
      +                "null"
      +              ]
      +            },
      +            "status": {
      +              "anyOf": [
      +                {
      +                  "maximum": 9007199254740991,
      +                  "minimum": -9007199254740991,
      +                  "type": "integer"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ],
      +              "description": "The HTTP status, when the API answered one."
      +            }
      +          },
      +          "required": [
      +            "kind",
      +            "path",
      +            "status",
      +            "message"
      +          ],
      +          "type": "object"
      +        },
      +        "freshness": {
      +          "type": "null"
      +        },
      +        "measured_at": {
      +          "type": "null"
      +        },
      +        "method": {
      +          "type": "null"
      +        },
      +        "notes": {
      +          "description": "Caveats, one sentence each.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "state": {
      +          "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +          "enum": [
      +            "failed",
      +            "invalid_input"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "state",
      +        "measured_at",
      +        "method",
      +        "coverage",
      +        "freshness",
      +        "notes",
      +        "error"
      +      ],
      +      "type": "object"
      +    }
      +  ],
      +  "type": "object"
      +}
  4. First observedv1.0.3

TDQS

A3.9/5.0
Behavior5/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description adds substantial non-obvious behavior: score_assessed semantics (unscored is NOT scored 0), placeholder caveats, patch_available meaning, null freshness, and the 30,000-character TEXT CUT / DATA CUT truncation rules. This is rich context well beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, but the body runs long and dense with repetitive clauses about field semantics, much of which duplicates the existing output schema. Every sentence carries real semantic content, but the volume is heavier than the tool's selection task requires.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with multiple upstream feeds, scoring semantics, and truncation behavior, the description covers the tricky edge cases (unscored CVEs, patch evidence absence, cut output and continuation offsets) that an agent could otherwise misread. With an output schema present, the return-value detail is extra but not harmful.

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?

Schema description coverage is 100%, so the baseline is 3, and the schema already documents sort, limit, offset, search, min_cvss, severity, and full. The description mostly restates filter/paging behavior and adds only the 'unless full: true' caveat, so it does not meaningfully exceed the schema.

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?

The description gives a specific verb+resource ('Search/list CVEs from EchelonGraph's CVE feed') and enumerates the underlying sources, so the agent knows exactly what corpus this queries. It implicitly separates itself from the singular get_cve sibling via 'search/list', but never names an alternative tool explicitly.

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?

Usage is only implied through the filter/paging parameters ('Filter by severity, minimum CVSS, free text, and sort; page with limit and offset'). There is no statement of when to choose this over cve_intel, cve_summary, or get_cve, and no when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.