Skip to main content
Glama
echelongraph

EchelonGraph MCP Server

Official

EPSS change history for one CVE

epss_history
Read-onlyIdempotent

Get a CVE's recorded EPSS score and percentile changes over time, plus current value and coverage limits, to track exploit-prediction probability shifts.

Instructions

How one CVE's EPSS score (FIRST's exploit-prediction probability, 0 to 1, with its percentile) has changed, as EchelonGraph recorded it: points, oldest first, each with at, epss_score, epss_percentile and score_date (FIRST's score date, null where the record does not hold it); current, the record's value now (epss_score, epss_percentile, epss_updated_at); series_kind, always change_only; series_starts_at, when EchelonGraph began recording EPSS changes for any CVE; complete_since, from when the record holds every change; coverage, which FIRST score dates the record holds; history_rows, points_truncated and latest_point_matches_current. Pass a CVE ID like CVE-2023-44487. The series is change-only: a point is a recorded change, and a day without a point is not a recorded value. A daily series interpolated from it holds values EchelonGraph never recorded, so the series is never a daily series. Before series_starts_at nothing was recorded, so a missing point there means not recorded, not unchanged, and the value in force before a CVE's first point is not in the series. Between series_starts_at and complete_since the record misses changes, so a missing point there does not mean unchanged either; only from complete_since on is every change a point. coverage.days_missing and coverage.days_partial name the FIRST score dates the record does not hold, or holds for some CVEs only. latest_point_matches_current false means a change is missing from the series. Its structured result's measured_at is current.epss_updated_at (when EchelonGraph last wrote a changed value, not FIRST's score date), its coverage says which part of the record is complete and which score dates it holds, and its freshness is null. 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.

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.
cve_idYesa CVE ID, e.g. CVE-2023-44487

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": {
      -              "complete_since": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "From when every change is a point; null when the API did not say, and then no part of the series is known complete."
      -              },
      -              "days_held": {
      -                "anyOf": [
      -                  {
      -                    "maximum": 9007199254740991,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Score dates from first_day to last_day the record holds; null when none are listed."
      -              },
      -              "days_missing": {
      -                "description": "Score dates from first_day to last_day the record does not hold.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "days_partial": {
      -                "description": "Score dates held for some CVEs only.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "first_day": {
      -                "description": "The earliest FIRST score date the run log lists; null when it lists none.",
      -                "type": [
      -                  "string",
      -                  "null"
      -                ]
      -              },
      -              "last_day": {
      -                "type": [
      -                  "string",
      -                  "null"
      -                ]
      -              },
      -              "points": {
      -                "description": "How many points the series holds.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "points_before_complete_since": {
      -                "anyOf": [
      -                  {
      -                    "maximum": 9007199254740991,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "How many of them fall where changes are missing; null when the API did not say."
      -              },
      -              "points_truncated": {
      -                "type": "boolean"
      -              },
      -              "series_complete": {
      -                "description": "True only when the API says nothing in the record predates complete_since.",
      -                "type": "boolean"
      -              },
      -              "series_kind": {
      -                "enum": [
      -                  "change_only"
      -                ],
      -                "type": "string"
      -              },
      -              "series_starts_at": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              }
      -            },
      -            "required": [
      -              "series_kind",
      -              "series_starts_at",
      -              "complete_since",
      -              "series_complete",
      -              "points",
      -              "points_before_complete_since",
      -              "points_truncated",
      -              "first_day",
      -              "last_day",
      -              "days_held",
      -              "days_partial",
      -              "days_missing"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "What the answer covers; null where the answer says nothing about it."
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "complete_since": {
      -            "anyOf": [
      -              {
      -                "description": "An RFC 3339 instant.",
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "From when the record holds every change a refresh applied. Between series_starts_at and complete_since changes are missing, so a missing point there does not mean unchanged. Absent from an API older than #2867."
      -          },
      -          "coverage": {
      -            "anyOf": [
      -              {
      -                "additionalProperties": {},
      -                "properties": {
      -                  "complete_since": {
      -                    "anyOf": [
      -                      {
      -                        "description": "An RFC 3339 instant.",
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "From here on every change a refresh applied is a point; before it changes are missing."
      -                  },
      -                  "days_held": {
      -                    "anyOf": [
      -                      {
      -                        "maximum": 9007199254740991,
      -                        "minimum": 0,
      -                        "type": "integer"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "Score dates from first_day to last_day that a refresh applied completely."
      -                  },
      -                  "days_missing": {
      -                    "anyOf": [
      -                      {
      -                        "items": {
      -                          "description": "A FIRST score date, YYYY-MM-DD.",
      -                          "type": "string"
      -                        },
      -                        "type": "array"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "Score dates from first_day to last_day that no refresh applied."
      -                  },
      -                  "days_partial": {
      -                    "anyOf": [
      -                      {
      -                        "items": {
      -                          "description": "A FIRST score date, YYYY-MM-DD.",
      -                          "type": "string"
      -                        },
      -                        "type": "array"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "Score dates whose refreshes all failed part-way: some CVEs hold that day, some do not."
      -                  },
      -                  "first_day": {
      -                    "anyOf": [
      -                      {
      -                        "description": "A FIRST score date, YYYY-MM-DD.",
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "The earliest score date in the run log."
      -                  },
      -                  "last_day": {
      -                    "anyOf": [
      -                      {
      -                        "description": "A FIRST score date, YYYY-MM-DD.",
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "The latest score date in the run log."
      -                  },
      -                  "points_before_complete_since": {
      -                    "anyOf": [
      -                      {
      -                        "maximum": 9007199254740991,
      -                        "minimum": 0,
      -                        "type": "integer"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "This CVE's points in the part of the record that misses changes."
      -                  },
      -                  "recorded_from": {
      -                    "anyOf": [
      -                      {
      -                        "description": "An RFC 3339 instant.",
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "series_starts_at: when recording began."
      -                  },
      -                  "refresh_runs_truncated": {
      -                    "type": [
      -                      "boolean",
      -                      "null"
      -                    ]
      -                  },
      -                  "run_log_since": {
      -                    "anyOf": [
      -                      {
      -                        "description": "An RFC 3339 instant.",
      -                        "type": "string"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "The first logged refresh: score dates before it are not listed, held or missing."
      -                  },
      -                  "runs_undated": {
      -                    "anyOf": [
      -                      {
      -                        "maximum": 9007199254740991,
      -                        "minimum": 0,
      -                        "type": "integer"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ]
      -                  },
      -                  "series_complete": {
      -                    "description": "True only when nothing in the record predates complete_since.",
      -                    "type": [
      -                      "boolean",
      -                      "null"
      -                    ]
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Which part of the record is complete and which FIRST score dates it holds."
      -          },
      -          "current": {
      -            "additionalProperties": {},
      -            "properties": {
      -              "epss_percentile": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "epss_score": {
      -                "description": "The record's EPSS probability now; null when it holds none.",
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "epss_updated_at": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "When EchelonGraph last wrote a changed EPSS value for this CVE."
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "cve_id": {
      -            "type": "string"
      -          },
      -          "history_rows": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Raw history rows read, before repeated records of one change were collapsed."
      -          },
      -          "latest_point_matches_current": {
      -            "description": "Whether the newest point equals current; false means a change is missing from the series; null when there is no point or no current value.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "points": {
      -            "description": "Recorded changes, oldest first. Never a daily series.",
      -            "items": {
      -              "additionalProperties": {},
      -              "properties": {
      -                "at": {
      -                  "description": "When EchelonGraph recorded this change.",
      -                  "type": "string"
      -                },
      -                "epss_percentile": {
      -                  "description": "Its percentile (0 to 1), null where the record held none.",
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "epss_score": {
      -                  "description": "The EPSS probability (0 to 1) from that change on.",
      -                  "type": "number"
      -                },
      -                "score_date": {
      -                  "description": "FIRST's score date (YYYY-MM-DD) of the logged refresh that wrote this point; null where no logged refresh covers it.",
      -                  "type": [
      -                    "string",
      -                    "null"
      -                  ]
      -                }
      -              },
      -              "required": [
      -                "at",
      -                "epss_score"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "points_truncated": {
      -            "description": "True when only the newest rows were read, so the earliest points are missing.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "series_kind": {
      -            "description": "Always change_only: one point per recorded change, none for a day without one.",
      -            "enum": [
      -              "change_only"
      -            ],
      -            "type": "string"
      -          },
      -          "series_starts_at": {
      -            "anyOf": [
      -              {
      -                "description": "An RFC 3339 instant.",
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The earliest EPSS change EchelonGraph recorded for any CVE: when recording began. Null when nothing has been recorded."
      -          }
      -        },
      -        "required": [
      -          "cve_id",
      -          "series_kind",
      -          "series_starts_at",
      -          "current",
      -          "points"
      -        ],
      -        "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": {
      -              "complete_since": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "From when every change is a point; null when the API did not say, and then no part of the series is known complete."
      -              },
      -              "days_held": {
      -                "anyOf": [
      -                  {
      -                    "maximum": 9007199254740991,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Score dates from first_day to last_day the record holds; null when none are listed."
      -              },
      -              "days_missing": {
      -                "description": "Score dates from first_day to last_day the record does not hold.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "days_partial": {
      -                "description": "Score dates held for some CVEs only.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              "first_day": {
      -                "description": "The earliest FIRST score date the run log lists; null when it lists none.",
      -                "type": [
      -                  "string",
      -                  "null"
      -                ]
      -              },
      -              "last_day": {
      -                "type": [
      -                  "string",
      -                  "null"
      -                ]
      -              },
      -              "points": {
      -                "description": "How many points the series holds.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "points_before_complete_since": {
      -                "anyOf": [
      -                  {
      -                    "maximum": 9007199254740991,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "How many of them fall where changes are missing; null when the API did not say."
      -              },
      -              "points_truncated": {
      -                "type": "boolean"
      -              },
      -              "series_complete": {
      -                "description": "True only when the API says nothing in the record predates complete_since.",
      -                "type": "boolean"
      -              },
      -              "series_kind": {
      -                "enum": [
      -                  "change_only"
      -                ],
      -                "type": "string"
      -              },
      -              "series_starts_at": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              }
      -            },
      -            "required": [
      -              "series_kind",
      -              "series_starts_at",
      -              "complete_since",
      -              "series_complete",
      -              "points",
      -              "points_before_complete_since",
      -              "points_truncated",
      -              "first_day",
      -              "last_day",
      -              "days_held",
      -              "days_partial",
      -              "days_missing"
      -            ],
      -            "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": {
      +              "complete_since": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "From when every change is a point; null when the API did not say, and then no part of the series is known complete."
      +              },
      +              "days_held": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Score dates from first_day to last_day the record holds; null when none are listed."
      +              },
      +              "days_missing": {
      +                "description": "Score dates from first_day to last_day the record does not hold.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "days_partial": {
      +                "description": "Score dates held for some CVEs only.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "first_day": {
      +                "description": "The earliest FIRST score date the run log lists; null when it lists none.",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "last_day": {
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "points": {
      +                "description": "How many points the series holds.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "points_before_complete_since": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "How many of them fall where changes are missing; null when the API did not say."
      +              },
      +              "points_truncated": {
      +                "type": "boolean"
      +              },
      +              "series_complete": {
      +                "description": "True only when the API says nothing in the record predates complete_since.",
      +                "type": "boolean"
      +              },
      +              "series_kind": {
      +                "enum": [
      +                  "change_only"
      +                ],
      +                "type": "string"
      +              },
      +              "series_starts_at": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              }
      +            },
      +            "required": [
      +              "series_kind",
      +              "series_starts_at",
      +              "complete_since",
      +              "series_complete",
      +              "points",
      +              "points_before_complete_since",
      +              "points_truncated",
      +              "first_day",
      +              "last_day",
      +              "days_held",
      +              "days_partial",
      +              "days_missing"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "What the answer covers; null where the answer says nothing about it."
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "complete_since": {
      +            "anyOf": [
      +              {
      +                "description": "An RFC 3339 instant.",
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "From when the record holds every change a refresh applied. Between series_starts_at and complete_since changes are missing, so a missing point there does not mean unchanged. Absent from an API older than #2867."
      +          },
      +          "coverage": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "complete_since": {
      +                    "anyOf": [
      +                      {
      +                        "description": "An RFC 3339 instant.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "From here on every change a refresh applied is a point; before it changes are missing."
      +                  },
      +                  "days_held": {
      +                    "anyOf": [
      +                      {
      +                        "maximum": 9007199254740991,
      +                        "minimum": 0,
      +                        "type": "integer"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Score dates from first_day to last_day that a refresh applied completely."
      +                  },
      +                  "days_missing": {
      +                    "anyOf": [
      +                      {
      +                        "items": {
      +                          "description": "A FIRST score date, YYYY-MM-DD.",
      +                          "type": "string"
      +                        },
      +                        "type": "array"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Score dates from first_day to last_day that no refresh applied."
      +                  },
      +                  "days_partial": {
      +                    "anyOf": [
      +                      {
      +                        "items": {
      +                          "description": "A FIRST score date, YYYY-MM-DD.",
      +                          "type": "string"
      +                        },
      +                        "type": "array"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Score dates whose refreshes all failed part-way: some CVEs hold that day, some do not."
      +                  },
      +                  "first_day": {
      +                    "anyOf": [
      +                      {
      +                        "description": "A FIRST score date, YYYY-MM-DD.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The earliest score date in the run log."
      +                  },
      +                  "last_day": {
      +                    "anyOf": [
      +                      {
      +                        "description": "A FIRST score date, YYYY-MM-DD.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The latest score date in the run log."
      +                  },
      +                  "points_before_complete_since": {
      +                    "anyOf": [
      +                      {
      +                        "maximum": 9007199254740991,
      +                        "minimum": 0,
      +                        "type": "integer"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "This CVE's points in the part of the record that misses changes."
      +                  },
      +                  "recorded_from": {
      +                    "anyOf": [
      +                      {
      +                        "description": "An RFC 3339 instant.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "series_starts_at: when recording began."
      +                  },
      +                  "refresh_runs_truncated": {
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "run_log_since": {
      +                    "anyOf": [
      +                      {
      +                        "description": "An RFC 3339 instant.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The first logged refresh: score dates before it are not listed, held or missing."
      +                  },
      +                  "runs_undated": {
      +                    "anyOf": [
      +                      {
      +                        "maximum": 9007199254740991,
      +                        "minimum": 0,
      +                        "type": "integer"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "series_complete": {
      +                    "description": "True only when nothing in the record predates complete_since.",
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Which part of the record is complete and which FIRST score dates it holds."
      +          },
      +          "current": {
      +            "additionalProperties": {},
      +            "properties": {
      +              "epss_percentile": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "epss_score": {
      +                "description": "The record's EPSS probability now; null when it holds none.",
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "epss_updated_at": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "When EchelonGraph last wrote a changed EPSS value for this CVE."
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "cve_id": {
      +            "type": "string"
      +          },
      +          "history_rows": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Raw history rows read, before repeated records of one change were collapsed."
      +          },
      +          "latest_point_matches_current": {
      +            "description": "Whether the newest point equals current; false means a change is missing from the series; null when there is no point or no current value.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "points": {
      +            "description": "Recorded changes, oldest first. Never a daily series.",
      +            "items": {
      +              "additionalProperties": {},
      +              "properties": {
      +                "at": {
      +                  "description": "When EchelonGraph recorded this change.",
      +                  "type": "string"
      +                },
      +                "epss_percentile": {
      +                  "description": "Its percentile (0 to 1), null where the record held none.",
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "epss_score": {
      +                  "description": "The EPSS probability (0 to 1) from that change on.",
      +                  "type": "number"
      +                },
      +                "score_date": {
      +                  "description": "FIRST's score date (YYYY-MM-DD) of the logged refresh that wrote this point; null where no logged refresh covers it.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                }
      +              },
      +              "required": [
      +                "at",
      +                "epss_score"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "points_truncated": {
      +            "description": "True when only the newest rows were read, so the earliest points are missing.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "series_kind": {
      +            "description": "Always change_only: one point per recorded change, none for a day without one.",
      +            "enum": [
      +              "change_only"
      +            ],
      +            "type": "string"
      +          },
      +          "series_starts_at": {
      +            "anyOf": [
      +              {
      +                "description": "An RFC 3339 instant.",
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The earliest EPSS change EchelonGraph recorded for any CVE: when recording began. Null when nothing has been recorded."
      +          }
      +        },
      +        "required": [
      +          "cve_id",
      +          "series_kind",
      +          "series_starts_at",
      +          "current",
      +          "points"
      +        ],
      +        "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": {
      +              "complete_since": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "From when every change is a point; null when the API did not say, and then no part of the series is known complete."
      +              },
      +              "days_held": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Score dates from first_day to last_day the record holds; null when none are listed."
      +              },
      +              "days_missing": {
      +                "description": "Score dates from first_day to last_day the record does not hold.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "days_partial": {
      +                "description": "Score dates held for some CVEs only.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "first_day": {
      +                "description": "The earliest FIRST score date the run log lists; null when it lists none.",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "last_day": {
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "points": {
      +                "description": "How many points the series holds.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "points_before_complete_since": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "How many of them fall where changes are missing; null when the API did not say."
      +              },
      +              "points_truncated": {
      +                "type": "boolean"
      +              },
      +              "series_complete": {
      +                "description": "True only when the API says nothing in the record predates complete_since.",
      +                "type": "boolean"
      +              },
      +              "series_kind": {
      +                "enum": [
      +                  "change_only"
      +                ],
      +                "type": "string"
      +              },
      +              "series_starts_at": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              }
      +            },
      +            "required": [
      +              "series_kind",
      +              "series_starts_at",
      +              "complete_since",
      +              "series_complete",
      +              "points",
      +              "points_before_complete_since",
      +              "points_truncated",
      +              "first_day",
      +              "last_day",
      +              "days_held",
      +              "days_partial",
      +              "days_missing"
      +            ],
      +            "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": {
      -              "points": {
      -                "description": "How many points the series holds.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "points_truncated": {
      -                "type": "boolean"
      -              },
      -              "series_kind": {
      -                "enum": [
      -                  "change_only"
      -                ],
      -                "type": "string"
      -              },
      -              "series_starts_at": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              }
      -            },
      -            "required": [
      -              "series_kind",
      -              "series_starts_at",
      -              "points",
      -              "points_truncated"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "What the answer covers; null where the answer says nothing about it."
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "current": {
      -            "additionalProperties": {},
      -            "properties": {
      -              "epss_percentile": {
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "epss_score": {
      -                "description": "The record's EPSS probability now; null when it holds none.",
      -                "type": [
      -                  "number",
      -                  "null"
      -                ]
      -              },
      -              "epss_updated_at": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "When EchelonGraph last wrote a changed EPSS value for this CVE."
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "cve_id": {
      -            "type": "string"
      -          },
      -          "history_rows": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Raw history rows read, before repeated records of one change were collapsed."
      -          },
      -          "latest_point_matches_current": {
      -            "description": "Whether the newest point equals current; false means a change is missing from the series; null when there is no point or no current value.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "points": {
      -            "description": "Recorded changes, oldest first. Never a daily series.",
      -            "items": {
      -              "additionalProperties": {},
      -              "properties": {
      -                "at": {
      -                  "description": "When EchelonGraph recorded this change.",
      -                  "type": "string"
      -                },
      -                "epss_percentile": {
      -                  "description": "Its percentile (0 to 1), null where the record held none.",
      -                  "type": [
      -                    "number",
      -                    "null"
      -                  ]
      -                },
      -                "epss_score": {
      -                  "description": "The EPSS probability (0 to 1) from that change on.",
      -                  "type": "number"
      -                }
      -              },
      -              "required": [
      -                "at",
      -                "epss_score"
      -              ],
      -              "type": "object"
      -            },
      -            "type": "array"
      -          },
      -          "points_truncated": {
      -            "description": "True when only the newest rows were read, so the earliest points are missing.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "series_kind": {
      -            "description": "Always change_only: one point per recorded change, none for a day without one.",
      -            "enum": [
      -              "change_only"
      -            ],
      -            "type": "string"
      -          },
      -          "series_starts_at": {
      -            "anyOf": [
      -              {
      -                "description": "An RFC 3339 instant.",
      -                "type": "string"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The earliest EPSS change EchelonGraph recorded for any CVE: when recording began. Null when nothing has been recorded."
      -          }
      -        },
      -        "required": [
      -          "cve_id",
      -          "series_kind",
      -          "series_starts_at",
      -          "current",
      -          "points"
      -        ],
      -        "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": {
      -              "points": {
      -                "description": "How many points the series holds.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "points_truncated": {
      -                "type": "boolean"
      -              },
      -              "series_kind": {
      -                "enum": [
      -                  "change_only"
      -                ],
      -                "type": "string"
      -              },
      -              "series_starts_at": {
      -                "anyOf": [
      -                  {
      -                    "description": "An RFC 3339 instant.",
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ]
      -              }
      -            },
      -            "required": [
      -              "series_kind",
      -              "series_starts_at",
      -              "points",
      -              "points_truncated"
      -            ],
      -            "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": {
      +              "complete_since": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "From when every change is a point; null when the API did not say, and then no part of the series is known complete."
      +              },
      +              "days_held": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Score dates from first_day to last_day the record holds; null when none are listed."
      +              },
      +              "days_missing": {
      +                "description": "Score dates from first_day to last_day the record does not hold.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "days_partial": {
      +                "description": "Score dates held for some CVEs only.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "first_day": {
      +                "description": "The earliest FIRST score date the run log lists; null when it lists none.",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "last_day": {
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "points": {
      +                "description": "How many points the series holds.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "points_before_complete_since": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "How many of them fall where changes are missing; null when the API did not say."
      +              },
      +              "points_truncated": {
      +                "type": "boolean"
      +              },
      +              "series_complete": {
      +                "description": "True only when the API says nothing in the record predates complete_since.",
      +                "type": "boolean"
      +              },
      +              "series_kind": {
      +                "enum": [
      +                  "change_only"
      +                ],
      +                "type": "string"
      +              },
      +              "series_starts_at": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              }
      +            },
      +            "required": [
      +              "series_kind",
      +              "series_starts_at",
      +              "complete_since",
      +              "series_complete",
      +              "points",
      +              "points_before_complete_since",
      +              "points_truncated",
      +              "first_day",
      +              "last_day",
      +              "days_held",
      +              "days_partial",
      +              "days_missing"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "What the answer covers; null where the answer says nothing about it."
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "complete_since": {
      +            "anyOf": [
      +              {
      +                "description": "An RFC 3339 instant.",
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "From when the record holds every change a refresh applied. Between series_starts_at and complete_since changes are missing, so a missing point there does not mean unchanged. Absent from an API older than #2867."
      +          },
      +          "coverage": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "complete_since": {
      +                    "anyOf": [
      +                      {
      +                        "description": "An RFC 3339 instant.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "From here on every change a refresh applied is a point; before it changes are missing."
      +                  },
      +                  "days_held": {
      +                    "anyOf": [
      +                      {
      +                        "maximum": 9007199254740991,
      +                        "minimum": 0,
      +                        "type": "integer"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Score dates from first_day to last_day that a refresh applied completely."
      +                  },
      +                  "days_missing": {
      +                    "anyOf": [
      +                      {
      +                        "items": {
      +                          "description": "A FIRST score date, YYYY-MM-DD.",
      +                          "type": "string"
      +                        },
      +                        "type": "array"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Score dates from first_day to last_day that no refresh applied."
      +                  },
      +                  "days_partial": {
      +                    "anyOf": [
      +                      {
      +                        "items": {
      +                          "description": "A FIRST score date, YYYY-MM-DD.",
      +                          "type": "string"
      +                        },
      +                        "type": "array"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Score dates whose refreshes all failed part-way: some CVEs hold that day, some do not."
      +                  },
      +                  "first_day": {
      +                    "anyOf": [
      +                      {
      +                        "description": "A FIRST score date, YYYY-MM-DD.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The earliest score date in the run log."
      +                  },
      +                  "last_day": {
      +                    "anyOf": [
      +                      {
      +                        "description": "A FIRST score date, YYYY-MM-DD.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The latest score date in the run log."
      +                  },
      +                  "points_before_complete_since": {
      +                    "anyOf": [
      +                      {
      +                        "maximum": 9007199254740991,
      +                        "minimum": 0,
      +                        "type": "integer"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "This CVE's points in the part of the record that misses changes."
      +                  },
      +                  "recorded_from": {
      +                    "anyOf": [
      +                      {
      +                        "description": "An RFC 3339 instant.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "series_starts_at: when recording began."
      +                  },
      +                  "refresh_runs_truncated": {
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "run_log_since": {
      +                    "anyOf": [
      +                      {
      +                        "description": "An RFC 3339 instant.",
      +                        "type": "string"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The first logged refresh: score dates before it are not listed, held or missing."
      +                  },
      +                  "runs_undated": {
      +                    "anyOf": [
      +                      {
      +                        "maximum": 9007199254740991,
      +                        "minimum": 0,
      +                        "type": "integer"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "series_complete": {
      +                    "description": "True only when nothing in the record predates complete_since.",
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Which part of the record is complete and which FIRST score dates it holds."
      +          },
      +          "current": {
      +            "additionalProperties": {},
      +            "properties": {
      +              "epss_percentile": {
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "epss_score": {
      +                "description": "The record's EPSS probability now; null when it holds none.",
      +                "type": [
      +                  "number",
      +                  "null"
      +                ]
      +              },
      +              "epss_updated_at": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "When EchelonGraph last wrote a changed EPSS value for this CVE."
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "cve_id": {
      +            "type": "string"
      +          },
      +          "history_rows": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Raw history rows read, before repeated records of one change were collapsed."
      +          },
      +          "latest_point_matches_current": {
      +            "description": "Whether the newest point equals current; false means a change is missing from the series; null when there is no point or no current value.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "points": {
      +            "description": "Recorded changes, oldest first. Never a daily series.",
      +            "items": {
      +              "additionalProperties": {},
      +              "properties": {
      +                "at": {
      +                  "description": "When EchelonGraph recorded this change.",
      +                  "type": "string"
      +                },
      +                "epss_percentile": {
      +                  "description": "Its percentile (0 to 1), null where the record held none.",
      +                  "type": [
      +                    "number",
      +                    "null"
      +                  ]
      +                },
      +                "epss_score": {
      +                  "description": "The EPSS probability (0 to 1) from that change on.",
      +                  "type": "number"
      +                },
      +                "score_date": {
      +                  "description": "FIRST's score date (YYYY-MM-DD) of the logged refresh that wrote this point; null where no logged refresh covers it.",
      +                  "type": [
      +                    "string",
      +                    "null"
      +                  ]
      +                }
      +              },
      +              "required": [
      +                "at",
      +                "epss_score"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "points_truncated": {
      +            "description": "True when only the newest rows were read, so the earliest points are missing.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "series_kind": {
      +            "description": "Always change_only: one point per recorded change, none for a day without one.",
      +            "enum": [
      +              "change_only"
      +            ],
      +            "type": "string"
      +          },
      +          "series_starts_at": {
      +            "anyOf": [
      +              {
      +                "description": "An RFC 3339 instant.",
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The earliest EPSS change EchelonGraph recorded for any CVE: when recording began. Null when nothing has been recorded."
      +          }
      +        },
      +        "required": [
      +          "cve_id",
      +          "series_kind",
      +          "series_starts_at",
      +          "current",
      +          "points"
      +        ],
      +        "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": {
      +              "complete_since": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "From when every change is a point; null when the API did not say, and then no part of the series is known complete."
      +              },
      +              "days_held": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Score dates from first_day to last_day the record holds; null when none are listed."
      +              },
      +              "days_missing": {
      +                "description": "Score dates from first_day to last_day the record does not hold.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "days_partial": {
      +                "description": "Score dates held for some CVEs only.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "first_day": {
      +                "description": "The earliest FIRST score date the run log lists; null when it lists none.",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "last_day": {
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "points": {
      +                "description": "How many points the series holds.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "points_before_complete_since": {
      +                "anyOf": [
      +                  {
      +                    "maximum": 9007199254740991,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "How many of them fall where changes are missing; null when the API did not say."
      +              },
      +              "points_truncated": {
      +                "type": "boolean"
      +              },
      +              "series_complete": {
      +                "description": "True only when the API says nothing in the record predates complete_since.",
      +                "type": "boolean"
      +              },
      +              "series_kind": {
      +                "enum": [
      +                  "change_only"
      +                ],
      +                "type": "string"
      +              },
      +              "series_starts_at": {
      +                "anyOf": [
      +                  {
      +                    "description": "An RFC 3339 instant.",
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ]
      +              }
      +            },
      +            "required": [
      +              "series_kind",
      +              "series_starts_at",
      +              "complete_since",
      +              "series_complete",
      +              "points",
      +              "points_before_complete_since",
      +              "points_truncated",
      +              "first_day",
      +              "last_day",
      +              "days_held",
      +              "days_partial",
      +              "days_missing"
      +            ],
      +            "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. Addedv2.6.3

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the read-only/idempotent annotations, it discloses substantial behavior: the 30,000-character JSON cut with TEXT CUT / DATA CUT markers, the meaning of missing points before series_starts_at and before complete_since, latest_point_matches_current=false as a signal of a missed change, and measured_at/freshness semantics. This is well past what the annotations carry.

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?

Every clause is relevant, but the description is a very long semicolon-chained run-on and the first sentence crams the entire output shape before the practical guidance. It is thorough rather than front-loaded and would benefit from being broken into scannable units.

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 complex tool with an output schema and full annotation coverage, the description supplies everything an agent needs to call it and read the result correctly, including truncation, coverage, and completeness caveats.

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 both parameters (cve_id and full) are already documented in the schema, including full's truncation behavior. The description's 'Pass a CVE ID like CVE-2023-44487' adds nothing the schema lacks, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening states a specific verb (how the EPSS score 'has changed') and resource (one CVE's EPSS score as recorded by EchelonGraph), and the change-only framing distinguishes it from a point-in-time tool like get_cve or cve_intel. An agent can tell what this returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context ('Pass a CVE ID like CVE-2023-44487') and an implicit when-not warning ('the series is never a daily series', don't interpolate), which steers interpretation. It never names a sibling tool or states an explicit alternative for point-in-time EPSS, so routing guidance is contextual rather than comparative.

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