{
 "schema": "mcp-freshness/1",
 "measured_at": "2026-10-19T06:13:44Z",
 "measured_date": "2026-10-19",
 "script": "scripts/measure-cve-freshness.py",
 "method_version": "cve-freshness/1",
 "window": {
  "start": "2026-09-19T06:13:44Z",
  "end": "2026-10-19T06:13:44Z",
  "days": 30
 },
 "metrics": {
  "pre_nvd_lead": {
   "n": 14424,
   "window": {
    "start": "2026-09-19T06:13:44Z",
    "end": "2026-10-19T06:13:44Z",
    "days": 30
   },
   "measured_at": "2026-10-19T06:13:44Z",
   "method": "For every CVE NVD's API 2.0 lists as published in the window (pubStartDate/pubEndDate), and every CVE EchelonGraph's public list returns with published in the window: EchelonGraph's created_at (the time the record was first written; an upsert never rewrites it) against NVD's published. A CVE in our window that NVD's window listing lacks is looked up in NVD by ID. ours_first: created_at earlier than NVD's published; nvd_first: not earlier; not_in_nvd: NVD returned no record by ID at measured_at; not_served_by_us: NVD published it in the window and our public API returned 404. Percentiles are nearest-rank.",
   "results": {
    "n": 14424,
    "n_in_both": 14405,
    "counts": {
     "not_in_nvd": 7,
     "not_served_by_us": 12,
     "nvd_first": 153,
     "ours_first": 14252
    },
    "ours_first_share_of_in_both": 98.9,
    "ours_first_over_24h": 45,
    "lead_minutes_when_ours_first": {
     "n": 14252,
     "unit": "minutes",
     "p10": 6.6,
     "p25": 18.4,
     "median": 29.6,
     "p75": 45.8,
     "p90": 52.1,
     "min": 0.1,
     "max": 178506.5
    },
    "lag_minutes_when_nvd_first": {
     "n": 153,
     "unit": "minutes",
     "p10": 0.3,
     "p25": 1.3,
     "median": 36.9,
     "p75": 127.8,
     "p90": 174.1,
     "min": 0.1,
     "max": 187.7
    },
    "not_in_nvd_age_minutes": {
     "n": 7,
     "unit": "minutes",
     "p10": 3528.5,
     "p25": 3528.5,
     "median": 4908.5,
     "p75": 6408.6,
     "p90": 23728.8,
     "min": 3528.5,
     "max": 23728.8
    }
   },
   "nvd_listing": {
    "total_results": 14910,
    "fetched": 14910
   },
   "nvd_window_cves_not_checked": 0,
   "nvd_per_id_lookups": 22,
   "source_fields": {
    "ours": "created_at (GET /api/v1/public/cves, /cves/:id)",
    "nvd": "published (NVD API 2.0)"
   }
  },
  "kev_latency": {
   "n": 32,
   "window": {
    "start": "2026-09-19T06:13:44Z",
    "end": "2026-10-19T06:13:44Z",
    "days": 30
   },
   "measured_at": "2026-10-19T06:13:44Z",
   "method": "For every entry in CISA's known_exploited_vulnerabilities.json with dateAdded in the window: dateAdded against our_first_seen_kev from GET /api/v1/public/kev/recent, compared as calendar dates in UTC. CISA's dateAdded is a date with no time and no stated timezone, so same_day means the same UTC date, not a latency in hours; earlier means our UTC date precedes CISA's date.",
   "results": {
    "n": 32,
    "n_with_first_seen": 32,
    "counts": {
     "same_day": 32
    },
    "same_day_share_of_with_first_seen": 100.0,
    "same_or_next_day_share_of_with_first_seen": 100.0
   },
   "cisa_catalog_version": "2026.10.16",
   "cisa_date_released": "2026-10-16T17:15:48.8752Z",
   "our_catalog": {
    "source": "CISA KEV catalog",
    "feed_url": "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json",
    "last_successful_fetch_at": "2026-10-19T06:16:43.02382Z",
    "catalog_version": "2026.10.16",
    "date_released": "2026-10-16T17:15:48.8752Z",
    "catalog_count": 1748
   }
  },
  "epss_freshness": {
   "n": 100,
   "window": {
    "start": "2026-09-19T06:13:44Z",
    "end": "2026-10-19T06:13:44Z",
    "days": 30
   },
   "measured_at": "2026-10-19T06:13:44Z",
   "method": "For a deterministic sample of window CVEs (smallest sha256(date|CVE)): EchelonGraph's epss_score and epss_percentile from GET /api/v1/public/cves/:id against FIRST's api.first.org/data/v1/epss (scope=time-series) to 5 decimals. matches_latest: equal to FIRST's value for its latest date; matches_older: equal only to an earlier date (lag_days = latest minus that date). The public API has no EPSS score-date field, so the match is by value; epss_updated_at changes only when the value changes and is reported separately.",
   "results": {
    "n": 100,
    "n_scored_by_first": 89,
    "counts": {
     "first_has_no_score": 11,
     "matches_latest": 89
    },
    "matches_latest_share_of_scored_by_first": 100.0,
    "lag_days_distribution": {
     "n": 89,
     "unit": "days",
     "p10": 0.0,
     "p25": 0.0,
     "median": 0.0,
     "p75": 0.0,
     "p90": 0.0,
     "min": 0.0,
     "max": 0.0
    },
    "first_latest_dates": [
     "2026-10-18"
    ],
    "epss_updated_at_day_equals_first_latest": {
     "n": 89,
     "count": 83
    }
   },
   "sample": {
    "n": 100,
    "population": 14362,
    "seed": "2026-10-19"
   },
   "missing_public_field": "epss_score_date: the FIRST model date of the served score. Without it the API cannot say which day's EPSS it serves; this metric infers it by value."
  },
  "enrichment": {
   "n": 100,
   "window": {
    "start": "2026-09-19T06:13:44Z",
    "end": "2026-10-19T06:13:44Z",
    "days": 30
   },
   "measured_at": "2026-10-19T06:13:44Z",
   "method": "For the same sample: cvss_v3 and cvss_v4 present on GET /api/v1/public/cves/:id (a cvss_v3_score of 0 with no cvss_source, or equal to cvss_v4_score, is not counted as v3: the field holds a placeholder or the v4 fallback there); cwe, affected_packages, exploit_references (exploits_total > 0) and vendor_advisories non-empty on GET /api/v1/public/cves/:id/enrichment. A section listed in failed_sections is not assessed and is left out of that field's n. NVD's own record of the same CVEs (any cvssMetricV31/V30, cvssMetricV40, CWE weakness, primary or secondary) is shown alongside.",
   "results": {
    "n": 100,
    "fields": {
     "cvss_v3": {
      "n": 100,
      "count": 87,
      "share": 87.0,
      "not_assessed": 0
     },
     "cvss_v4": {
      "n": 100,
      "count": 31,
      "share": 31.0,
      "not_assessed": 0
     },
     "cwe": {
      "n": 100,
      "count": 91,
      "share": 91.0,
      "not_assessed": 0
     },
     "affected_packages": {
      "n": 100,
      "count": 19,
      "share": 19.0,
      "not_assessed": 0
     },
     "exploit_references": {
      "n": 100,
      "count": 0,
      "share": 0.0,
      "not_assessed": 0
     },
     "vendor_advisories": {
      "n": 100,
      "count": 22,
      "share": 22.0,
      "not_assessed": 0
     }
    },
    "nvd_same_cves": {
     "cvss_v3": {
      "n": 98,
      "count": 83,
      "share": 84.7
     },
     "cvss_v4": {
      "n": 98,
      "count": 29,
      "share": 29.6
     },
     "cwe": {
      "n": 98,
      "count": 89,
      "share": 90.8
     }
    }
   },
   "sample": {
    "n": 100,
    "population": 14362,
    "seed": "2026-10-19"
   }
  }
 },
 "comparison": {
  "measured_at": "2026-10-19T06:13:44Z",
  "method": "Each MCP server was asked, over its own MCP transport (Streamable HTTP: initialize, notifications/initialized, tools/list, tools/call; EchelonGraph: the published npm package over stdio), about the same CVE set on the same run, with one configured tool per question. Answered means the response carried that field for that CVE, read by fixed rules (read_answer in the script); it is not a judgement of correctness, except kev_agrees_with_cisa, which compares a stated KEV status with CISA's catalogue fetched in the same run. A call the server answered with a rate limit or a temporary error (often its own upstream, NVD) was retried after the wait it asked for (at most 60 s, twice); if it still failed, its questions are counted as errored, not as unanswered. Calls were spaced 2 s apart. Raw responses, every attempt included, are kept.",
  "cve_set": [
   {
    "cve_id": "CVE-2026-102764",
    "group": "kev_recent",
    "kev_date_added": "2026-10-16"
   },
   {
    "cve_id": "CVE-2025-61624",
    "group": "kev_recent",
    "kev_date_added": "2026-10-16"
   },
   {
    "cve_id": "CVE-2026-21589",
    "group": "kev_recent",
    "kev_date_added": "2026-10-15"
   },
   {
    "cve_id": "CVE-2026-76519",
    "group": "kev_recent",
    "kev_date_added": "2026-10-14"
   },
   {
    "cve_id": "CVE-2026-105134",
    "group": "kev_recent",
    "kev_date_added": "2026-10-14"
   },
   {
    "cve_id": "CVE-2026-105133",
    "group": "kev_recent",
    "kev_date_added": "2026-10-14"
   },
   {
    "cve_id": "CVE-2026-0322",
    "group": "kev_recent",
    "kev_date_added": "2026-10-14"
   },
   {
    "cve_id": "CVE-2026-96951",
    "group": "kev_recent",
    "kev_date_added": "2026-10-13"
   },
   {
    "cve_id": "CVE-2026-104935",
    "group": "kev_recent",
    "kev_date_added": "2026-10-13"
   },
   {
    "cve_id": "CVE-2023-22894",
    "group": "kev_recent",
    "kev_date_added": "2026-10-08"
   },
   {
    "cve_id": "CVE-2026-111873",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T05:16:27Z"
   },
   {
    "cve_id": "CVE-2026-111872",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T04:16:35Z"
   },
   {
    "cve_id": "CVE-2026-111871",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T04:16:35Z"
   },
   {
    "cve_id": "CVE-2026-111870",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T04:16:31Z"
   },
   {
    "cve_id": "CVE-2026-111869",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T03:16:28Z"
   },
   {
    "cve_id": "CVE-2026-111997",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T01:16:35Z"
   },
   {
    "cve_id": "CVE-2026-111868",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T01:16:34Z"
   },
   {
    "cve_id": "CVE-2026-111866",
    "group": "nvd_recent",
    "nvd_published": "2026-10-18T00:16:37Z"
   },
   {
    "cve_id": "CVE-2026-111865",
    "group": "nvd_recent",
    "nvd_published": "2026-10-17T21:16:25Z"
   },
   {
    "cve_id": "CVE-2026-111934",
    "group": "nvd_recent",
    "nvd_published": "2026-10-17T19:16:36Z"
   }
  ],
  "cve_set_rule": {
   "total": 20,
   "kev_recent": 10,
   "nvd_recent": 10,
   "nvd_hours_from": 72,
   "nvd_hours_to": 24
  },
  "truth": {
   "CVE-2026-102764": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2025-61624": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-21589": {
    "kev_listed": true,
    "first_has_epss": false
   },
   "CVE-2026-76519": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-105134": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-105133": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-0322": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-96951": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-104935": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2023-22894": {
    "kev_listed": true,
    "first_has_epss": true
   },
   "CVE-2026-111873": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111872": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111871": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111870": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111869": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111997": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111868": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111866": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111865": {
    "kev_listed": false,
    "first_has_epss": true
   },
   "CVE-2026-111934": {
    "kev_listed": false,
    "first_has_epss": true
   }
  },
  "echelongraph_mcp_version": "3.0.2",
  "servers": [
   {
    "id": "echelongraph",
    "name": "EchelonGraph (echelongraph-mcp from npm, stdio)",
    "registry": "io.echelongraph/echelongraph-mcp",
    "endpoint": "npx -y echelongraph-mcp@3.0.2",
    "attempted_at": "2026-10-19T06:22:06Z",
    "measured": true,
    "reason": null,
    "server_info": {
     "name": "echelongraph-mcp",
     "version": "3.0.2"
    },
    "package_version": "3.0.2",
    "n": 20,
    "answered": {
     "knows": 20,
     "cvss": 20,
     "kev": 20,
     "epss": 20
    },
    "errored": {
     "knows": 0,
     "cvss": 0,
     "kev": 0,
     "epss": 0
    },
    "kev_agrees_with_cisa": {
     "n": 20,
     "count": 20
    }
   },
   {
    "id": "cve-security",
    "name": "cve-security.com",
    "registry": "com.cve-security/cve-intelligence",
    "endpoint": "https://cve-security.com/api/mcp",
    "attempted_at": "2026-10-19T06:22:51Z",
    "measured": true,
    "reason": null,
    "server_info": {
     "name": "cve-security",
     "title": "CVE Security",
     "version": "1.9.0"
    },
    "package_version": null,
    "n": 20,
    "answered": {
     "knows": 19,
     "cvss": 19,
     "kev": 19,
     "epss": 19
    },
    "errored": {
     "knows": 0,
     "cvss": 0,
     "kev": 0,
     "epss": 0
    },
    "kev_agrees_with_cisa": {
     "n": 19,
     "count": 19
    }
   },
   {
    "id": "datakoot",
    "name": "Datakoot Security Intel",
    "registry": "com.datakoot/cve-vulnerability-lookup",
    "endpoint": "https://security.datakoot.com/mcp",
    "attempted_at": "2026-10-19T06:23:38Z",
    "measured": true,
    "reason": null,
    "server_info": {
     "name": "security-intel",
     "version": "2.1.0"
    },
    "package_version": null,
    "n": 20,
    "answered": {
     "knows": 20,
     "cvss": 18,
     "kev": 20,
     "epss": 19
    },
    "errored": {
     "knows": 0,
     "cvss": 0,
     "kev": 0,
     "epss": 0
    },
    "kev_agrees_with_cisa": {
     "n": 20,
     "count": 20
    }
   },
   {
    "id": "cvelens",
    "name": "CVELens",
    "registry": "com.cvelens/cvelens",
    "endpoint": "https://api.cvelens.com/mcp",
    "attempted_at": "2026-10-19T06:26:21Z",
    "measured": false,
    "reason": "not reachable without credentials or not answering: initialize: unreachable: URLError(SSLError(1, '[SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:992)')); its registry entry declares an X-API-Key header",
    "server_info": null,
    "package_version": null
   },
   {
    "id": "notcve",
    "name": "notCVE",
    "registry": "org.notcve/vulnerability-intelligence",
    "endpoint": "https://notcve.org/mcp",
    "attempted_at": "2026-10-19T06:26:22Z",
    "measured": false,
    "reason": "not reachable without credentials or not answering: initialize: HTTP 401 application/json: {\"error\":\"invalid_request\",\"error_description\":\"Missing Authorization header.\",\"resource_metadata\":\"https://notcve.org/.well-known/oauth-protected-resource\"}",
    "server_info": null,
    "package_version": null
   },
   {
    "id": "openkrill",
    "name": "OpenKrill CVE Risk Check",
    "registry": "app.openkrill/cve",
    "endpoint": "https://cve.openkrill.app/mcp",
    "attempted_at": "2026-10-19T06:26:22Z",
    "measured": true,
    "reason": null,
    "server_info": {
     "name": "cve",
     "title": "CVE Risk Check: CVE and dependency triage",
     "version": "1.2.0"
    },
    "package_version": null,
    "n": 20,
    "answered": {
     "knows": 19,
     "cvss": 18,
     "kev": 19,
     "epss": 18
    },
    "errored": {
     "knows": 1,
     "cvss": 1,
     "kev": 1,
     "epss": 1
    },
    "kev_agrees_with_cisa": {
     "n": 19,
     "count": 19
    }
   },
   {
    "id": "pipeworx-circl",
    "name": "Pipeworx CIRCL Vulnerability-Lookup",
    "registry": "io.github.pipeworx-io/circl-vulnerability-lookup",
    "endpoint": "https://gateway.pipeworx.io/circl-vulnerability-lookup/mcp",
    "attempted_at": "2026-10-19T06:30:04Z",
    "measured": true,
    "reason": null,
    "server_info": {
     "name": "pipeworx-gateway",
     "version": "0.1.0"
    },
    "package_version": null,
    "n": 20,
    "answered": {
     "knows": 20,
     "cvss": 19,
     "kev": 0,
     "epss": 0
    },
    "errored": {
     "knows": 0,
     "cvss": 0,
     "kev": 0,
     "epss": 0
    },
    "kev_agrees_with_cisa": {
     "n": 0,
     "count": 0
    }
   },
   {
    "id": "aislabs",
    "name": "AIS CVE",
    "registry": "ai.aislabs/cve",
    "endpoint": "https://api.aislabs.ai/cve/mcp",
    "attempted_at": "2026-10-19T06:31:04Z",
    "measured": false,
    "reason": "the cve_verdict tool's own description says it needs payment: \"PAID \u2014 unlock with an AIS CVE key ($19 / 30 days) or campus pass (https://aislabs.ai/gateway/), or pay per call over x402 on the HTTP twin: $0.005. One CVE's pr\"",
    "server_info": {
     "name": "ais-cve",
     "version": "0.1.0"
    },
    "package_version": null
   },
   {
    "id": "a2awire-cvewatch",
    "name": "A2AWire cvewatch",
    "registry": "com.a2awire/data-cve-security-advisory-vulnerability-database",
    "endpoint": "https://a2awire.com/mcp/data/cvewatch-cve-security-advisories-nvd-high-critical-9a16b6/http",
    "attempted_at": "2026-10-19T06:31:05Z",
    "measured": false,
    "reason": "the data_session_query tool's own description says it needs payment: \"Buy per-query access to live data listings \u2014 first taste free via data_preview. Listing: cvewatch: CVE Security Advisories (NVD, High & Critical) at 0.01 USDC p\"",
    "server_info": {
     "name": "a2awire",
     "version": "0.1.0",
     "websiteUrl": "https://a2awire.com/api/v1/docs"
    },
    "package_version": null
   },
   {
    "id": "nexlab",
    "name": "Nexlab vulnerability-intel",
    "registry": "net.nexlab/vulnerability-intel",
    "endpoint": "https://mcp.nexlab.net/mcp/vulnerability-intel",
    "attempted_at": "2026-10-19T06:31:05Z",
    "measured": false,
    "reason": "not reachable without credentials or not answering: initialize: HTTP 401 application/json: {\"error\":{\"code\":\"api_key_required\",\"message\":\"Supply an API key or OAuth token as 'Authorization: Bearer <token>'.\",\"get_one_at\":\"/account\"}}",
    "server_info": null,
    "package_version": null
   },
   {
    "id": "censys",
    "name": "Censys (investigate_cve)",
    "registry": null,
    "endpoint": null,
    "attempted_at": null,
    "measured": false,
    "reason": "paid / token-gated (#2304); not called",
    "server_info": null,
    "package_version": null
   },
   {
    "id": "vulncheck",
    "name": "VulnCheck (search_target_intel)",
    "registry": null,
    "endpoint": null,
    "attempted_at": null,
    "measured": false,
    "reason": "paid / token-gated (#2304); not called",
    "server_info": null,
    "package_version": null
   }
  ],
  "questions": {
   "knows": "does it return a record for the CVE",
   "cvss": "does it give a CVSS base score",
   "kev": "does it state CISA KEV status (listed or not)",
   "epss": "does it give an EPSS score"
  }
 },
 "csv": {
  "freshness": "/mcp-freshness/cve-freshness-2026-10-19.csv",
  "comparison": "/mcp-freshness/mcp-comparison-2026-10-19.csv"
 },
 "not_measured": [
  "Time from a CVE's publication by its CNA to EchelonGraph serving it (created_at is compared with NVD, not with CVE.org).",
  "KEV latency in hours: CISA's dateAdded has no time of day.",
  "Correctness of other servers' CVSS and EPSS values (only whether they were given).",
  "Servers that need an API key, OAuth or payment, and servers that did not answer (listed with the reason).",
  "Anything about a CVE outside the stated window and sample."
 ]
}
