mcpField
E
EchelonGraph CVE & Exposure

EchelonGraph CVE & Exposure

远程服务
echelongraph.io安全83 天前更新

关于 EchelonGraph CVE & Exposure

EchelonGraph MCP server 为安全团队和开发者提供 CVE、漏洞利用、修复版本及互联网暴露情况查询。它融合多个漏洞来源的数据,并为结果标注测量状态、覆盖范围和时效信息。

主要功能

  1. 01查询 CVE 记录及修复信息
  2. 02查看 EPSS 历史和厂商公告
  3. 03查询 KEV 漏洞暴露足迹
  4. 04检查产品版本、SBOM 和锁文件
  5. 05提供提示词、资源和模板

适用场景

  1. 01评估某个 CVE 的实际暴露范围
  2. 02核查产品版本是否受漏洞影响
  3. 03审查项目 SBOM 或锁文件
  4. 04整理最新 CISA KEV 漏洞

MCP 相关

该服务向 MCP 客户端提供 16 个只读工具、5 个提示词、2 个资源和 1 个资源模板。可通过本地 stdio 或无需密钥的 Streamable HTTP 端点连接。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.echelongraph.io/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npmechelongraph-mcp3.1.2

工具

16
参数类型必填说明
fullboolean否true:结构化结果中的 data 是完整答案,无论长度如何。未指定时,如果结构化结果的 JSON 超过 30,000 个字符,其 data 会被截取(DATA CUT):按照备注说明的顺序,最长列表中的条目先仅保留部分字段,随后列表仅保留部分条目;data_truncated 为 true,truncated 会列出每个被截取的列表及其总数、返回数量和条目是否经过精简。完整 data 适用于程序;像 Claude Code 这样会根据 MAX_MCP_OUTPUT_TOKENS 限制结构化结果大小的客户端,可能会拒绝超过上限的答案。

详细介绍

EchelonGraph MCP 服务

为 Claude、Cursor、VS Code、Cline 和任何 MCP 客户端提供 CVE 和互联网暴露数据,数据直接来自 EchelonGraph 的免费公共数据源。

它提供 EchelonGraph 的 CVE Pulse(将 NVD + MITRE-CNA NVD 发布前 + CISA-KEV + EPSS + GitHub GHSA 融合为一个评分),以及每个 CVE 的互联网暴露情况:EchelonGraph 的 KEV 暴露雷达记录中,有多少互联网可访问服务(不同的 ip:port)运行着可映射到该 CVE 的版本。暴露数量基于 Shodan 数据。Shodan 数据归 Shodan 所有,版权亦由其持有(© Shodan)。

这 16 个工具可查询单个 CVE(记录、漏洞利用代码和修复版本、其来源所述的修复方式、EPSS 历史记录、供应商公告、暴露情况),列出 CISA 最新添加的 KEV,检查产品或软件包版本是否受影响,检查 SBOM 或项目锁定文件,并读取 CWE 及其 CVE。每个结果都会说明测量方式(state、measured_at、method、coverage、freshness、notes),确保模型不会把服务中断或尚未评估的查询误认为一切正常。

它还提供五个提示词,即客户端可显示为斜杠命令的现成工作流(triage_cve、kev_weekly_brief、am_i_affected、sbom_review、workload_triage;参见“提示词”),两个资源(echelongraph://methodology 和 echelongraph://sources),以及一个资源模板(cve://{cve_id};参见“资源”)。

免费且无需密钥:无需 API 密钥,无需身份验证,只读。除工具回答问题所需的 API 调用外,服务不会发出其他请求。

快速开始

本地服务通过 npx 运行,需要 Node.js 20 或更高版本;不会全局安装任何内容。下方的一键扩展适用于 Claude Desktop,无需安装任何内容。将以下任一配置块添加到客户端,完全退出并重新打开客户端,然后提问:“CVE-2023-44487 是否正在遭受攻击?EchelonGraph 的雷达记录中有多少个暴露服务受到影响?”

Claude Desktop

有三种接入方式。前两种不需要 Node.js:一种是一键安装扩展,在你的机器上运行服务;另一种是连接托管端点的自定义连接器。第三种通过 npx 运行服务。

1. 在 Claude Desktop 中安装 (一键安装,无需 Node.js)。 此链接会下载 echelongraph-mcp.mcpb,这是一个 Claude Desktop 扩展。打开它,或者在 Claude Desktop 中选择 Settings → Extensions → Advanced settings → Install Extension,然后选中该文件,再选择 Install。Claude Desktop 会使用自带的 Node.js 运行服务,并写入自己的配置:无需设置 PATH,也无需编辑 JSON。要更新,请用相同方式安装下一个版本的扩展包。GitHub 上的每个新版本都会附带该扩展包(2.6.5 及更早版本除外);扩展包由发布 npm 包的工作流基于版本标签构建,并附有 SLSA 构建来源证明。验证下载文件: gh attestation verify echelongraph-mcp.mcpb --repo echelongraph/echelongraph-mcp。

2. 自定义连接器(无需安装)。 Claude Desktop 使用你的 claude.ai 账号中的连接器:依次选择 Customize → Connectors → + Add → Add custom connector。将其命名为 EchelonGraph,粘贴 https://mcp.echelongraph.io/mcp,选择 No sign in,然后添加。在 claude.ai 上添加的连接器也会显示在 Claude Desktop 中;套餐规则遵循 claude.ai 的规则(见下文“远程(无需安装)”)。

3. 通过 npx 运行本地服务。

  1. 检查 Node.js。 在终端(macOS)或 PowerShell(Windows)中运行 node -v。输出必须为 v20 或更高版本。如果输出的是更早版本或 command not found,请从 https://nodejs.org 安装 LTS 版本,或者在 macOS 上使用 Homebrew 运行 brew install node。

  2. 在纯文本编辑器中打开配置文件。 Settings → Developer → Edit Config 会显示 claude_desktop_config.json(macOS:~/Library/Application Support/Claude/claude_desktop_config.json;Windows:%APPDATA%\Claude\claude_desktop_config.json)。请使用 VS Code、Notepad 或 nano 等纯文本编辑器打开。macOS 上的 TextEdit 在启用 Smart Quotes 时会把 " 转成弯引号(“ ”),导致 JSON 出错且不显示错误:请在 Edit → Substitutions → Smart Quotes 中关闭该选项,或改用其他编辑器。

  3. 合并,不要替换。 该文件通常已经存在,并包含 Claude Desktop 自身的设置(例如 "preferences" 对象)。请保留其中的所有内容。在顶层添加 "mcpServers" 键,与现有键并列;如果已经有 "mcpServers",就在其中添加 "echelongraph" 条目。注意条目之间的逗号。最终内容如下,其中 preferences 处应为你自己的设置:

    {
      "preferences": {
        "…": "the settings already in your file stay as they are"
      },
      "mcpServers": {
        "echelongraph": {
          "command": "npx",
          "args": ["-y", "echelongraph-mcp"]
        }
      }
    }
    

    要检查文件能否解析,请在终端(macOS)中运行:

    node -e "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'))" "$HOME/Library/Application Support/Claude/claude_desktop_config.json"
    

    或在 PowerShell(Windows)中运行:

    node -e "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'))" "$env:APPDATA\Claude\claude_desktop_config.json"
    

    没有输出表示 JSON 有效。SyntaxError 表示文件有错误(通常是弯引号或缺少逗号);ENOENT 表示该路径下还没有文件。

  4. 完全退出后再重新打开。 仅关闭窗口不会重新加载配置。在 macOS 上选择 Claude → Quit Claude(⌘Q);在 Windows 上,右键单击系统托盘中的 Claude 图标,然后选择 Quit。首次启动可能需要更长时间,因为 npx 需要下载软件包。

  5. 检查是否成功。 Settings → Developer 会显示 echelongraph 正在运行,聊天框中的工具菜单会列出 EchelonGraph 的工具,也就是下文“工具”部分列出的工具。然后提出本节开头的问题。

Claude Desktop 故障排查
  • spawn npx ENOENT(或服务显示为失败)。在 macOS 上,从 Dock 打开的应用无法获取 shell 的 PATH,因此 Claude Desktop 找不到 Homebrew(Apple silicon:/opt/homebrew/bin;Intel:/usr/local/bin)或 nvm 安装的 npx。在 Terminal 中运行 which npx,然后将 Claude Desktop 的 "command" 设为该绝对路径,并将其所在文件夹设为 "env" 下的 PATH(npx 会从同一文件夹启动 node)。使用 Apple silicon 上的 Homebrew 时:

    {
      "mcpServers": {
        "echelongraph": {
          "command": "/opt/homebrew/bin/npx",
          "args": ["-y", "echelongraph-mcp"],
          "env": { "PATH": "/opt/homebrew/bin:/usr/bin:/bin" }
        }
      }
    }
    

    使用 nvm 时,请填写 which npx 输出的完整路径(JSON 不会展开 ~)。然后完全退出并重新打开应用。在 Windows 上,使用 nodejs.org 提供的安装程序安装 Node.js,这会将 npx 添加到系统 PATH,然后完全退出并重新打开 Claude Desktop。

  • 服务完全没有显示。 文件不是有效的 JSON(缺少逗号或使用了弯引号),或者应用未完全退出:请参阅步骤 2 到 4。

  • 日志。 macOS:~/Library/Logs/Claude/mcp-server-echelongraph.log(此服务的输出)和 ~/Library/Logs/Claude/mcp.log(连接)。Windows:%APPDATA%\Claude\logs\,文件名相同。

Claude Code
claude mcp add --transport stdio echelongraph -- npx -y echelongraph-mcp

在 -- 前添加 --scope user,即可在每个项目中使用;添加 --scope project,则可通过项目的 .mcp.json 共享。Claude Code 会将每个结果的 structuredContent 交给模型;除非调用传入 full: true(参见“长回答”),否则此服务会将内容限制为 30,000 个字符。MAX_MCP_OUTPUT_TOKENS(默认 25,000 个 token)是 Claude Code 对工具输出设置的上限,提高此值即可让 full: true 的回答完整通过。

Cursor

~/.cursor/mcp.json(所有项目)或 .cursor/mcp.json(单个项目):

{
  "mcpServers": {
    "echelongraph": {
      "command": "npx",
      "args": ["-y", "echelongraph-mcp"]
    }
  }
}
VS Code

工作区中的 .vscode/mcp.json(VS Code 使用的键是 servers,而不是 mcpServers):

{
  "servers": {
    "echelongraph": {
      "command": "npx",
      "args": ["-y", "echelongraph-mcp"]
    }
  }
}

或从终端运行:

code --add-mcp '{"name":"echelongraph","command":"npx","args":["-y","echelongraph-mcp"]}'
Windsurf、Cline 和其他客户端

读取 mcpServers 块的客户端(Windsurf 的 mcp_config.json、Cline 的 MCP 设置以及大多数其他客户端)都可以使用与上文 Cursor 相同的配置块。

远程(无需安装)

相同的 16 个工具、5 个提示词、2 个资源和 1 个资源模板通过 Streamable HTTP 提供,地址为:

https://mcp.echelongraph.io/mcp

无需密钥、无需登录、无状态;支持两个协议时代。托管端点已投入服务: https://mcp.echelongraph.io/health 会返回 {"status":"ok","version":…},其中包含其运行的包版本。

  • claude.ai(Free、Pro、Max、Team 和 Enterprise 计划): Customize → Connectors → + Add → Add custom connector。将名称设为 EchelonGraph,粘贴 URL,选择 No sign in,然后添加。在 Team 和 Enterprise 计划中,Owner 需先为组织添加连接器,然后每位成员再进行连接。Free 计划允许添加一个自定义连接器。

  • Claude Code:

    claude mcp add --transport http echelongraph https://mcp.echelongraph.io/mcp
    
  • Cursor(mcp.json):

    { "mcpServers": { "echelongraph": { "url": "https://mcp.echelongraph.io/mcp" } } }
    
  • VS Code(.vscode/mcp.json):

    { "servers": { "echelongraph": { "type": "http", "url": "https://mcp.echelongraph.io/mcp" } } }
    
  • Windsurf(mcp_config.json):

    { "mcpServers": { "echelongraph": { "serverUrl": "https://mcp.echelongraph.io/mcp" } } }
    

托管端点会使用此包的代码(下文的 dist/http.js)访问同一公共 API,因此其回答与 npm 包的回答一致(“隐私”部分说明了它会记录哪些内容)。

工具

所有工具均为只读(readOnlyHint: true),并声明了标题和 outputSchema。示例问题均可由客户端仅使用相应工具回答。

工具标题可回答的问题示例问题
cve_summaryCVE 源摘要按严重性等级统计的活跃 CVE 数量;没有任何来源严重性等级的 CVE 数量(summary.none,也会再次作为 summary.unscored 返回:表示尚未评分的 CVE,而不是评分为 None);按 NVD 严重性标签统计的相同 CVE 数量,用作来源信息(summary.nvd_critical 至 summary.nvd_none);不计入总数的已拒绝(已撤回)记录(summary.rejected);以及源上次更新时间。源中有多少个严重 CVE?上次更新时间是什么时候?
search_cves搜索 CVE搜索/筛选 CVE(严重性、最低 CVSS、文本、排序),并提供 EchelonGraph 评分和 score_assessed;使用 limit 和 offset 分页;备注会列出每条尚未评分的记录。查找提及 Tomcat 且 CVSS 为 9 或更高的严重 CVE。
get_cveCVE 详情单个 CVE 的记录:CVSS v3 和(已评分时的)v4、EchelonGraph 评分及其置信度、EchelonGraph 是否已为其评分(score_assessed)、EPSS、CISA-KEV 状态和已知勒索软件利用情况;对于列入 KEV 的 CVE,还会逐字转述 CISA 自己的文本(kev_required_action,即 CISA 要求美国联邦民事机构采取的行动,并非 EchelonGraph 的建议;kev_short_description;kev_notes_urls);GitHub GHSA ID、参考资料,以及发布时间、修改时间和 updated_at。CVE-2024-3094 的 CVSS、EPSS 和 CISA-KEV 状态是什么?
cve_exposure单个 CVE 的互联网暴露情况某个 CVE 的互联网暴露范围:暴露的服务数量(不同的 ip:port,即 exposed_hosts 字段)以及国家/产品细分数据,来源为 KEV 暴露雷达。EchelonGraph 的雷达记录了多少个 CVE-2023-44487 暴露服务?
exposure_radar暴露雷达总计所有暴露雷达的汇总数据:运行 CISA-KEV CVE 的服务;通过 Shodan(Shodan 查询额度不足时使用 LeakIX)发现、随后经 EchelonGraph 自有识别检查确认的未授权数据存储和可观测性 UI;泄露的凭据;影子 AI;以及 EchelonGraph 自有 Certificate Transparency 源中发现的 MCP 服务,按 RFC 9728 判定、协议时代和传输方式分类。每个数字都标明了统计对象;工具无法标注的字段会被省略并明确列出。EchelonGraph 的雷达确认了多少个未授权数据存储?
kev_recentCISA KEV 最新收录项CISA 添加到已知被利用漏洞目录中的 CVE,按最新优先排序(kev_added_date),数据来自 EchelonGraph 的目录副本,该副本每 5 分钟从 CISA 轮询一次:到期日期、供应商、产品、已知勒索软件利用情况、EchelonGraph 严重性、CVSS、EPSS、eg_kev_tier 和 our_first_seen_kev。可按日期范围、勒索软件和供应商筛选;使用 limit 和 next_cursor 分页。日期依据 last_successful_fetch_at,即我们上次成功获取 CISA 源的时间;筛选条件通过请求标头传递,绝不放在 URL 中。自 9 月 1 日以来,CISA 将哪些 CVE 添加到了 KEV?其中哪些已知被勒索软件利用?
epss_history单个 CVE 的 EPSS 变化历史EchelonGraph 记录的某个 CVE 的 EPSS 评分变化情况:每次记录到的变化对应一个数据点(series_kind 为 change_only),而不是每日序列,并附当前值;complete_since 表示从何时起每次变化都有一个数据点(在此之前记录会漏掉一些变化,因此缺失数据点不代表没有变化,且该序列绝不会被称为完整);coverage 说明记录包含和缺少哪些 FIRST 评分日期(days_missing、days_partial、days_in_progress);series_starts_at 表示开始记录的时间;早于该时间的缺失数据点表示未记录,而不是没有变化。CVE-2023-44487 的 EPSS 评分发生了哪些变化?请按 EchelonGraph 的记录说明。
check_affected我是否受到影响?(给定版本的产品或软件包)某个给定版本的产品(其 NVD CPE 产品令牌)或注册表软件包(ecosystem 和 package)是否受已知 CVE 影响,数据来自 echelongraph.io/am-i-affected 背后的匹配器:首先返回 assessed(false 表示未评估,并附 not_assessed_reason;此时数量为 0 并不表示“未受影响”);匹配到的 CVE 包含 kev_listed、ransomware、epss_score、effective_score 和 score_assessed(注册表匹配还包含 fixed_in,即该版本以上、且记录中的任何受影响区间都不包含的最低版本;如果该版本跨过重叠区间,则附 fixed_in_detail;若为 null,则附 fixed_in_reason,这并不代表已判定不存在修复版本);以及无法判定的公告数量 undetermined_count,绝不会将其视为安全。查询内容通过请求标头传递,绝不放在 URL 中。openssl 3.0.0 是否受已知 CVE 影响?npm 上的 lodash 4.17.15 呢?
check_sbom根据公告语料库检查 SBOM根据 EchelonGraph 的公告语料库(OSV.dev 记录)检查依赖项列表,每个组件给出一个判定:affected、not_affected、undetermined 或 not_assessed,并附 not_assessed_reason。每行都会说明用于查询公告的软件包(matched_package)及匹配方式(matched_via:当 deb、apk 或 alpine purl 的 upstream 限定符指定源软件包时为 upstream,Debian 和 Alpine 正是以此方式发布公告;否则为 purl_name)。每个匹配项还包含 fixed_in,即高于组件版本且不在记录任何受影响区间内的最低版本(fixed_in_detail 会指出跨过的任何重叠区间);若为 null,则附 fixed_in_reason。最多可传入 2,000 个不同的 purl,列表最多包含 10,000 项;也可传入 CycloneDX JSON 或 SPDX JSON 文档:MCP 服务会从中读取 purl,且只会将 purl 发送至 API,每批 POST 请求最多 200 个,并依次发送;文档本身不会继续发送。通过 npm 运行时,服务在你的计算机上;通过托管端点(mcp.echelongraph.io)运行时,服务属于 EchelonGraph,文件则作为请求正文发送。达到 API 的单组件速率限制(429)时,工具会等待 Retry-After 指定的时间;一次调用最多等待 50 秒,超出后会返回已有结果,并在 coverage.not_sent 中统计未发送的 purl,在 coverage.not_sent_reason 中说明原因,在 data.not_sent_purls 中列出这些 purl(完整列表时为 full: true;列表可能被 DATA CUT 截断),绝不会静默丢弃。缺少指定发行版的 distro 限定符的 deb、apk 或 rpm purl 不会被评估(distro_release_unknown):EchelonGraph 不会猜测发行版。只有 not_affected 才表示安全。不排序,不评分。根据公告语料库检查此 CycloneDX SBOM。
scan_manifest根据公告语料库检查锁文件根据同一公告语料库检查项目的锁文件或固定版本清单,每个依赖项给出一个判定;使用与 check_sbom 相同的批量路由、批次、50 秒时限和 Retry-After 等待方式。传入 files,包含 1 至 20 个 filename 和 content(文件文本),总计最多 5,000,000 个字符;根据文件名读取格式,也可通过 format 指定。可读取:requirements.txt(仅支持 == 和 === 固定版本;会去除 extras 和标记)、go.mod(require 单行和代码块形式,包含 // indirect,并应用 replace 和 exclude)、package-lock.json 和 npm-shrinkwrap.json(lockfileVersion 1 至 3)、Cargo.lock、Gemfile.lock(去除平台后缀)、composer.lock(去除开头的 v)、poetry.lock 和 gradle.lockfile。package.json、pyproject.toml、Pipfile、Gemfile、Cargo.toml、composer.json 和 build.gradle 包含版本范围,因此会被拒绝,并指出应传入的锁文件;go.sum 也会被拒绝,因为它列出的模块版本并非构建所选用的版本;目前尚不读取 pom.xml、yarn.lock 和 pnpm-lock.yaml。MCP 服务会将文件解析为 purl,且只会将 purl 发送至 API;文件名和文件内容不会继续发送。通过 npm 运行时,服务在你的计算机上;通过托管端点(mcp.echelongraph.io)运行时,服务属于 EchelonGraph,文件则作为请求正文发送。data.results 按不同 purl 各返回一行,内容与 check_sbom 相同,每个匹配项都包含 kev_listed、epss_score 和 fixed_in。每个未发送的条目都会列在 data.not_checked 中,包含其文件、行号和 reason:version_unpinned(例如 django>=4 这样的版本范围;其边界值绝不会作为版本发送)、version_unresolved、local_path、vcs_source 或 unsupported_line,并按原因计入 coverage.not_checked_by_reason;这些条目不代表安全。若文件不包含此工具可检查的任何版本,工具会返回 not_assessed,而不调用 API。只有 not_affected 才表示安全。不排序,不评分。根据公告语料库检查此 package-lock.json。
cve_intelCVE 弱点、漏洞利用和软件包单个 CVE 的弱点、漏洞利用代码和检测检查(Nuclei 模板或 API 提供用作检查器的 GitHub 仓库,用于检查系统是否受影响;不一定是漏洞利用代码,备注会单独统计两者)、受影响的软件包和修复版本,数据来自 EchelonGraph 按 CVE 丰富的信息:cwes、exploits(最多 10 项,已验证的优先)以及 exploits_total、exploits_capped、exploits_by_kind 和 exploits_by_status、affected_packages、fixed_versions 和 timeline。每条 affected_packages 记录都包含 fixed_branches,即该软件包每个受影响区间及其修复信息(introduced,以及 fixed;若没有已记录的修复,则为 last_affected);每条记录都会指出发布它的 OSV 记录(advisory_id、source),并按该记录中的顺序排列:已安装版本的修复版本,是高于它且不在该记录任何区间内的首个 fixed;若有仍包含该版本的区间,则会跨过这些区间(不跨过没有 fixed 的区间),并按该生态系统的版本顺序进行比较。fixed_version 是为保持兼容而保留的单个区间修复版本,并非所有区间的修复版本;若某软件包的区间从未加载,fixed_branches 为 null;若没有已记录的版本区间,则为 [],这并不代表已判定不存在修复版本。verified_status 是随每条引用保存的标签,并不保证漏洞利用有效。exploits 列表为空并不能证明不存在公开漏洞利用;API 无法读取的部分会列在 coverage.sections_failed 中,绝不会以空列表转述。CVE-2021-44228 是否有公开漏洞利用代码?哪些版本可以修复它?
cve_remediation如何修复单个 CVE在一个回答中说明如何修复单个 CVE,并依据其来源所述内容;所有文本均按来源原文转述,未经 EchelonGraph 验证:cisa(对于列入 KEV 的 CVE,逐字提供 CISA 的 required_action、due_date、short_description 和 notes_urls;CISA 要求美国联邦民事机构采取该行动,这并非 EchelonGraph 的建议)、fixed_branches(每个受影响软件包及其所有受影响区间和修复版本)、vendor_remediations(提及该 CVE 的每条供应商公告,最多 20 条,包含其 remediation_state 及其中针对该 CVE 列出的条目,每项附 kind,即供应商自己的分类:vendor_fix、workaround、mitigation、no_fix_planned、none_available 或 other)、fix_references(NVD 或 CNA 标记为 Patch 或 Mitigation 的参考资料)、patches、coverage 和 failed_sections,以及 CVE Pulse 页面显示的 API 修复状态规则 fix_status。如果提供了已安装的 ecosystem、package 和 version(三项要么全部提供,要么都不提供),还会返回 installed(该版本的判定)和 fixed_in:高于该版本且不在任何已记录受影响区间内的首个版本;若为 null,则附 fixed_in_reason。remediation_state 为 none_in_source 或 not_parsed,或者列表为空,都不代表已判定不存在修复版本。REJECTED CVE 会返回 not_assessed。CVE-2021-44228 是如何修复的?请依据其来源所述内容说明。
get_cweCWE 及其 CVE一个 CWE(弱点类别)及归类到该类别下的 CVE:name 和 description 来自 EchelonGraph 内嵌的 MITRE CWE 目录;还包括 total 和一页 50 条 cves,排序方式由 order 指定(优先列出 CISA-KEV 收录项,然后按 EchelonGraph 评分排序)。total 为 0 表示 EchelonGraph 的源中没有 CVE 被归类到该 CWE,并不表示不存在此类 CVE。哪些 CVE 被归类到 CWE-79?请优先列出 CISA-KEV 收录项。
vendor_advisories_for_cve单个 CVE 的供应商公告供应商发布的公告(Microsoft MSRC、Red Hat、Cisco、Palo Alto Networks、GitHub GHSA 及 EchelonGraph 轮询的其他源)中提及某个 CVE 的公告,按最新优先排序,最多 20 条;每条都包含 remediation_kinds 和 remediation_state(not_parsed 表示 EchelonGraph 未读取该供应商的修复信息,并不代表不存在修复信息)。哪些供应商公告提及 CVE-2024-3400?
get_vendor_advisory供应商公告详情完整显示一条供应商公告:描述、严重性、cve_ids 和其中在此处有 CVE 记录的子集(known_cve_ids)、affected_products、remediation 和 references,以及 remediations;每项修复信息都是供应商列出的内容,包含供应商自己的分类 kind、原文和 URL,并附 remediation_state。完整显示其中一条公告:受影响产品、修复信息和参考资料。
search_vendor_advisories搜索供应商公告按文本(标题、描述、供应商、公告 ID、产品、CVE ID)、供应商、严重性以及是否提及 CVE 搜索供应商公告。搜索文本通过请求标头发送,绝不放在 URL 中。搜索 FortiOS 相关的供应商公告,仅显示严重性为严重的公告。
这三个供应商公告工具会转发 vendor_published_at(供应商的发布日期)、our_first_seen_at
(EchelonGraph 首次记录该公告的时间)和 withdrawn(供应商撤回了该公告;说明中会列出具体公告,搜索结果会排除这些公告)。

每个工具还会转发 coverage 中每家供应商的窗口(vendor_windows;详情中为 vendor_window):纳入的公告数量、其中最早和最晚的 vendor_published_at、 held_since 和 history_backfill。held_since 是 EchelonGraph 开始读取该供应商公告的窗口起始时间:在此之前发布的公告可能未被纳入。对于尚未读取历史公告的供应商(history_backfill 为 not_supported),这个时间可能比最早纳入的公告晚数年:Cisco 的轮询器首次读取的是过去 90 天内变更的公告,Red Hat 和 GitHub 的轮询器首次读取的是过去 7 天内变更的公告,因此,较早发布但后来修订的公告会被纳入,而同期发布的其他公告则不会。 vendor_advisories_for_cve 会在 vendors_not_fully_held 中列出以下供应商:其没有出现在答案中的公告,且 EchelonGraph 未纳入该供应商的任何公告;其 held_since 晚于 CVE ID 年份的 1 月 1 日或未知;或其历史公告仍在读取中:没有来自此类供应商的公告,并不表示该供应商没有发布过公告。

每个数值的时效都取决于生成它的最近一次检查。CVE 订阅源会按计划轮询各个源。每个雷达都有自己的计划,且只会在运行时刷新;exposure_radar 的 freshness 会提供各雷达最近一次已完成检查的时间(last_run_at),前提是 API 提供该字段。

各工具如何解读其答案

每个工具会转发哪些内容、各字段的含义,以及每个数值的计数对象,详见随软件包附带的 docs/ 文件夹中的页面:

  • cve_summary 如何解读其计数: summary.none 统计尚未评分的 CVE,而不是评级为 None 的 CVE;summary.nvd_critical 到 summary.nvd_none 则按 NVD 的严重性标签(或作为替代的 NVD 前标签)计数,用作来源信息。
  • get_cve 和 search_cves 如何解读 EchelonGraph 评分: score_assessed: false 表示尚未评分,绝不表示评分为 0。
  • patch_available 表示什么, 以及 patch_evidence 列出的证据,其中包括 CVE 记录自身的修复说明 (cna_solution、description_fix):false 表示记录中没有修复证据,并不表示不存在修复。
  • cve_exposure 如何计数: 统计的是 ip:port 服务数量,而非机器数量;这些数量是根据部分 Shodan 数据样本中的横幅版本推断得出的。对于不在雷达跟踪范围内的 CVE,状态为未评估,其 0 并非测量结果。
  • exposure_radar 如何计数: 说明五个雷达各自统计的内容,并为每个雷达的数值标注计数对象。
  • check_affected 如何判断: 先读取 assessed,再读取 count;注册表匹配项的 fixed_in 是高于该版本且不在该记录任何受影响版本区间内的最低版本;否则为 null,并附有 fixed_in_reason。

提示词

现成的工作流,客户端可以将其显示为斜杠命令。每个提示词都会按顺序列出要调用的工具,并指示模型读取每个结果的 state、measured_at、method、coverage 和 notes:not_assessed 绝不会被报告为正常;assessed: false 下计数为 0 绝不会被表述为“未受影响”;每个数值都会注明其 measured_at。提示词不会发出 API 请求。

提示词参数要求模型执行的操作
triage_cvecve_id调用 get_cve(若该 CVE 列入 KEV,则包含 CISA 的截止日期 kev_due_date)、cve_intel、vendor_advisories_for_cve、epss_history 和 cve_exposure,然后按模板给出判断:是否已被利用、可能性、是否可触达、补丁、截止日期、结论。补丁一栏会列出每个受影响范围及其在 cve_intel 的 fixed_branches 中对应的修复版本;若某个软件包没有修复分支,则将 fixed_version 作为 cve_intel 对该软件包的记录列出,每个软件包列一个(通常是公告中最后一个范围的版本),绝不将其当作每个受影响分支的修复版本;并指出 get_cve 中标记为 Vendor Advisory 或 Patch 的参考资料,作为该分支的修复依据。
kev_weekly_briefdays(1 到 365,默认值为 7)根据 days 算出起始日期,从该日期起按每页 50 条翻页读取 kev_recent,并按供应商分组撰写简报,注明勒索软件标记和截止日期。
am_i_affectedproduct,或 ecosystem 和 package;version调用 check_affected,先读取 assessed 再读取 count,并使用未评估时的措辞。
sbom_reviewsbom(CycloneDX 或 SPDX JSON 文本,最多 5,000,000 个字符)将文档传给 check_sbom(如果速率限制或剩余时间导致部分 purl 未发送,则再次传入这些 purl:data.not_sent_purls;如果文本或 DATA CUT 截断了该列表,则按文档说明的位置和顺序传入文档中的 purl)。从各 purl 读取每个组件的 ecosystem、package 和 version,方式与 check_sbom 的映射规则一致(包括其映射的每种 purl 类型,以及通过 distro 限定符识别 Debian、Ubuntu 或 Alpine 发行版的 deb、apk、alpine 和 rpm;其他发行版未知,且不提供固定版本;如果 deb、apk 或 alpine purl 带有 upstream 限定符,则使用该限定符指定的源软件包;当某行的 matched_via 为 upstream 时,使用该行的 matched_package,修复列表会在 purl 旁标出该值),对每个受影响的 CVE 调用 get_cve 和 cve_intel 查找,并按 CISA-KEV 列入情况、EPSS、分数排序编写修复列表,并注明每个排序依据。若文本保留了匹配结果,其固定版本仅使用该匹配项的 fixed_in,即高于已安装版本、且该记录中没有受影响区间涵盖的最低版本;若 fixed_in 为 null,则写作“记录中没有修复版本”,并按原样附上 fixed_in_reason,不得据此断言不存在修复版本(若 DATA CUT 将其截断且未留下原因,则绝不能称为没有修复版本),也不得从文本描述(match_reason、fixed_in_reason)中读取固定版本。若文本未保留该组件的匹配结果,或匹配结果没有 fixed_in,则仅在版本高于已安装版本时提供固定版本:取 cve_intel 行的 fixed_branches 中高于该版本且不属于任何范围的第一个 fixed;若软件包没有 fixed_branches,则使用 cve_intel 的 fixed_version,每个软件包列一个(即最后一个范围的版本),该版本不一定是该组件所在分支的修复版本;否则,该行写明结果没有提供该分支的固定版本,并指出该 CVE 的公告。
workload_triagesource(可选:kubernetes、github_actions 或 images;默认描述全部三种)使用你自己的工具对 Pod、CI 作业容器或镜像进行排序:列出工作负载,并自行判断其暴露情况;为每个镜像摘要生成 SBOM,并仅将 purl 传给 check_sbom(不发送工作负载、命名空间、镜像、注册表名称、凭据或暴露标签;不包含镜像自身的 pkg:oci/pkg:docker purl)。各行按 CISA-KEV 列入情况、调用方断言的暴露情况(未知绝不与未暴露一起排序)、EPSS、分数排序,并注明每个排序依据。若某行匹配结果被 DATA CUT 截断,则读取其 matches_truncated(其中包含列入 KEV 和涉及勒索软件的 CVE ID);对每个已保留但没有匹配结果的 CVE,或缺少其所依据排序字段的匹配结果,调用 get_cve 查询;超过 30 个 CVE 后停止调用 get_cve。统计 not_assessed 行,且绝不将其报告为安全。提示词不接收任何工作负载数据。

资源

两个资源由 resources/list 列出,一个资源模板由 resources/templates/list 列出(例如,客户端会读取 cve://CVE-2024-3400):

资源内容
echelongraph://methodology说明每个信封字段和 state 值的含义,以及每个工具的测量方式(Markdown)。
echelongraph://sources读取该资源时,API 会报告其数据源的哪些信息:NVD 轮询器的 interval、last_poll_at、poll_count 和 poll_errors,这些信息都来自实际响应的那个实例(来自 /api/v1/public/cves/summary;两个计数是该实例自上次启动以来的计数,每次重启都会归零,并不表示数据源的可靠性);以及 CISA KEV 目录最近一次成功获取的时间和方法(来自 /api/v1/public/kev/recent)。它会列出没有任何端点报告其计划的数据源,并说明这些数据源均未报告计划(JSON)。
cve://{cve_id}get_cve 返回的单个 CVE:结构化结果、信封和记录,以 JSON 格式呈现。JSON 超过 30,000 个字符后,data 会像 get_cve 的第一个文本块那样被截断,data_truncated 为 true,truncated 列出每个被截断的列表,并附上一条以 DATA CUT 开头的说明,指出截断遗漏的内容;get_cve 的 structuredContent.data 会完整保留记录,并带有 full: true。如果 ID 不是 CVE ID,则会在发出任何请求前拒绝;如果 API 没有该 CVE 的记录,则会返回未找到。

结果意味着什么

每个工具都会以两种形式之一作答,因此读取结果的模型不会把服务中断误认为一切正常:

  • 成功 — 第一个文本块是 API 的 JSON 原文(超过 30,000 个字符时会截断以适应长度限制:见下文“长答案”);第二个文本块是一行说明,指出调用成功、哪个基础 URL 返回了响应,以及发现了什么;第三个文本块是结构化结果的 JSON,去掉前两个文本块已经说明的内容(见下文)。如果查询对应的数据源确实没有内容,说明会用文字明确指出(“我们查过了,但没有找到……这不是查询失败”),因为经过测量的零也是一种测量结果。以下情况除外:cve_summary 会省略答案中类型为非 outputSchema 类型的 poller 字段(或既不是 JSON 对象也不是 null 的 poller),并在说明中指出;exposure_radar:每个雷达只保留 docs/exposure-radar.md 列出的字段,且每个 kev_exposure.newest_kev 条目都会新增一个 exposure_state。其 shadow_ai 计数会按该页面所述重新归组,且 poller 块仅包含 running 和 last_run_at,若其中没有实际完成时间,则会省略该块。该块的其他字段描述的是响应请求的服务实例,而不是雷达。其 last_run_at 表示雷达的 leader 最近一次完成 Certificate Transparency(crt.sh)周期的时间;只有在答案生成前 30 分钟内完成时,running 才为 true。running 为 true 时,说明会指出雷达的 leader 最近一次在该时间完成周期;为 false 时,说明会指出自该时间起尚未完成周期;若缺少 last_run_at,说明会指出雷达的新鲜度未知,并省略该块。较旧的 API 会从处理请求的任意服务实例返回响应,而 follower 实例会发送 running: false 和零时间 0001-01-01T00:00:00Z;这同样表示新鲜度未知,绝不会被描述为雷达已停止。
  • 失败 — 只要查询未完成,就返回 MCP 错误结果(isError: true):主机无法访问、响应状态码非 2xx、耗时超过超时限制,或以 2xx 状态码响应但正文不是 JSON 对象。文本会指出工具名称、原因(状态码或错误类型)、路径和基础 URL,并说明这不是一项发现;第二个文本块是结构化结果的 JSON,去掉消息中的句子(见下文)。失败绝不会被呈现为字段为 null 的成功结果。

这两种形式都包含下文所述的结构化结果,并会在最后一个文本块中重复该结果,因此只将 content 传给模型的客户端也能看到答案是如何测量得出的。

长答案

模型读取的每个字符都需要付费,而且不同客户端会将结果的不同部分交给模型,因此每个部分都采用相同的 30,000 个字符预算,并分别按各自规则截断:

  • Claude Code 会将 structuredContent 而非文本块交给模型,并按 MAX_MCP_OUTPUT_TOKENS(默认 25,000 个 token)计算大小:超过 10,000 个 token 时会发出警告,超过上限时会将结果保存到文件,并把文件路径交给模型。在 2.7.x 及更早版本中,structuredContent.data 始终是完整答案(get_cve 的 CVE-2021-44228:2026-10-11 时为 65,540 个字符,Claude Code 将其保存到了文件)。从 3.0.0 起,该字段会截断以适应限制(见下文)。在 Claude Code 启动时所处的环境中设置 MAX_MCP_OUTPUT_TOKENS,可以提高其上限。
  • 仅传递文本块的客户端(content)会读取第一个文本块,并按下一项之后所述的方式截断。
  • 程序若读取 structuredContent.data 且需要完整答案(无论多长),可传入 full: true:所有工具都接受该参数。像 Claude Code 这样会限制结构化结果大小的客户端,可能会在答案超过上限时拒绝该答案。 结构化结果。当整个结果(信封、其中的说明和 data,按紧凑 JSON 计算) 超过 30,000 个字符,且调用未指定 full: true 时,会按每个工具说明的顺序截断 data。对于较大的行,会先精简每一行,同时保留所有行:check_sbom 和 scan_manifest 会保留每行的判定结果和 cve_ids,以及提示词读取的每个匹配字段;如果这样能让每个受影响行保留所有匹配项,则先移除其 not_affected 和 not_assessed 行(说明);check_affected 会保留每个匹配项的评分、标志、条件和 fixed_in,之后再精简更多内容;cve_remediation 会先移除每个条目的 product_ids,再移除其文本,同时保留每条公告的状态、类型、URL 和修复版本(get_vendor_advisory 会返回每条文本),精简 fixed_branches(然后限制每个软件包的范围)和 patches,接着截断 fix_references,然后是 patches,再然后是 fixed_branches,最后才是公告;说明中会注明 vendor_advisories_for_cve,该工具会列出所有公告;search_cves 会先保留每行的描述和评分,然后只保留评分;供应商公告工具会先移除 affected_products,然后移除 summary。只有在此之后才会移除行(check_sbom 和 scan_manifest:如该页面所述);check_affected 会先移除其 excluded 和 undetermined 示例,最后移除会列出所有匹配项的 cve_ids;其他返回行的工具会从末尾移除行,而该页面会说明通过 offset 或 limit 读取剩余行(search_cves 和 search_vendor_advisories 还会说明能完整放入 data 的行数对应的页面大小,以完整行数计算)。get_cve 会将 cpe_match 和 references 各自截断至相同的最多条目数,然后截断 cpe_configurations;exposure_radar 会截断其每日和每周序列,各自保留最新条目,然后截断所有排名,最后截断 kev_exposure.newest_kev;之后,data 顶层的任何其他列表也会按相同方式截断。列表能完整放入后剩余的空间会返还给先前被清空的列表,让它们尽可能多地恢复条目(序列恢复最新条目)。不会缩短任何字符串,也不会更改任何值(精简后的行会保留部分字段,这些字段在 outputSchema 中均为可选,因此 data 仍然有效;截断操作只会添加 matches_truncated 和 fixed_branches_truncated)。结果随后会显示 data_truncated: true(其他所有成功结果均为 false);truncated 会按列表在 data 中的路径列出每个被截断的列表及其 total、返回数量 returned,以及在条目经过精简时标注 thinned: true;说明末尾会包含以 DATA CUT 开头的句子,说明截断了哪些内容、如何读取剩余内容,以及使用相同调用并设置 full: true 可返回完整的 data。 第一个文本块。在 2.6.2 及更早版本中,它是 API 的 JSON,无论大小。因此,当 API 的 JSON 超过 30,000 个字符时,第一个文本块会截断内容以适应长度限制;截断的是完整答案(不是截断后的 data),无论是否使用 full: true,方式都相同。首先,将相同的 JSON 排版为每行一条记录,这不会删掉答案中的任何字符,只会去掉缩进。如果这样仍然太长,返回记录列表的工具会将每条记录截断为其指定的字段,并优先保留最重要的字段(search_cves 会保留 cve_id、severity、cvss_v3_score、echelongraph_score、score_assessed、epss_score、kev_listed 和描述的前 200 个字符等),所有过长的字符串都会以“…”结尾。记录旁的列表会在任何记录从文本中省略前先行截断:check_affected 的 excluded 和 undetermined 样本会保留前 10 个条目,每项包含其 cve_id 和 reason;其 cve_ids(按顺序列出每个匹配项的 cve_id)会保留前 10 个,因此每个 CPE 匹配项都会保留在文本中,且至少包含 cve_id、kev_listed、ransomware、epss_score、effective_score 和 score_assessed(注册表匹配项还包含 fixed_in;接近 200 条上限的注册表列表可能会省略最后几项匹配项,最后省略 KEV 列出的项和勒索软件项,并在说明中注明省略数量和这些项的名称);check_sbom 的 not_sent_purls 会保留前 10 个,说明中会指出未发送的 purl 从输入的哪个位置开始,以及输入的 purl 按什么顺序计数,这样第二次调用时无需读取列表即可发送它们。scan_manifest 会像 check_sbom 一样截断记录,其 not_checked 列表会保留前 20 个条目。cve_remediation 会先精简其公告,然后是 fixed_branches 和 patches,接着将每个包的范围限制在可容纳的最大数量(被截断的包会带有 fixed_branches_truncated,并在说明中列出;说明会提示使用 full: true 读取其修复信息),然后按 data 中的顺序移除 fix_references、patches 和 fixed_branches 记录。当最精简的截断结果仍然太长时,文本中会省略记录(check_sbom 和 scan_manifest 会先省略 not_affected 记录,然后省略 not_assessed 记录;最后省略带有 KEV 列出项或勒索软件匹配项的记录,并按 index 列出所有省略项;这两类记录会先精简到最简形式;如果这样能让其他记录保留其匹配项,它们就会更早被省略;如果不能,则所有记录都会先精简到该级别:参见 docs/tools.md),说明中会指出如何读取这些记录:下次调用所用的 offset、更小的 limit,或者对于公告,使用 vendor_advisories_for_cve。其他任何答案都会保留每个列表的前几项(get_cve 的 cpe_match 和 references)。随后,说明会以一句以 TEXT CUT 开头的话结尾,说明第一个文本块省略了什么,以及哪个工具会返回某条记录(get_cve、get_vendor_advisory、check_affected,以及 cve_intel 返回的某个 CVE 的修复版本):这些内容完整保存在该工具的 structuredContent.data 中,使用 full: true 即可获取,因为该工具自己的第一个文本块也会在超过 30,000 个字符后被截断。能完整放入文本块的答案仍会像以前一样,以美化格式完整发送。同一个答案总是以相同方式截断。cve://{cve_id} 资源会完整读取 get_cve 的记录,并像截断 get_cve 的第一个文本块那样截断其 data,同时会说明这一点:data_truncated: true,truncated 列出每个被截断的列表,说明以 DATA CUT 开头。提示词只会要求文本中保留的内容:kev_weekly_brief 每页读取 50 条 kev_recent 记录,文本会完整保留这些记录;triage_cve 会从 get_cve 读取 CISA 的到期日期;sbom_review 会读取每个匹配项的 fixed_in,而 cve_intel 会读取文本中未保留某个组件匹配项时的 fixed_branches。

结构化结果

自 2.0.0 起,工具返回的每个结果,无论成功还是失败,都包含 structuredContent;每个工具也会在 tools/list 中通过 outputSchema 声明其结构,并带有标题以及注释 readOnlyHint: true、destructiveHint: false、idempotentHint: true 和 openWorldHint: true(这些提示不可信,客户端会将其视为不可信信息)。

字段内容
statemeasured、not_assessed、failed 或 invalid_input(见下文)。
measured_at底层观测的时间,按 API 的表述填写。若答案未说明或没有观测记录,则为 null;绝不会使用 Go 的零值时间。
method数值的生成方式。失败时为 null。
coverage答案涵盖的内容,具体取决于工具:cve_exposure 为 in_scope;search_cves 为列表对其计数的自行说明;exposure_radar 为已返回结果的雷达;check_affected 则为 assessed、not_assessed_reason、查询路径和匹配数量。
freshness生成该结果的雷达上次完成检查的时间(last_run_at),仅在 API 提供此信息时填写;否则为 null。
notes注意事项,每条一句:先说明结果封装本身需要说明的内容,再附上文本块中的说明。
data_truncated仅成功时提供:当 data 被截断(DATA CUT,见“长答案”)时为 true;若答案完整,则为 false。
truncated当 data_truncated 为 true 时,列出每个被截断的列表,使用其在 data 中的路径,并注明 total、returned;若列表项仅保留了部分字段,还需注明 thinned: true。
data仅成功时提供:API 返回的 JSON。若完整,则 full: true;默认情况下,若结构化结果超过 30,000 个字符,则会截断(DATA CUT):第一个文本块包含相同的 JSON;若超过 30,000 个字符,则包含答案整体的截断版本,具体见说明(TEXT CUT)。
error仅失败时提供:kind、path、status 和 message。

每个结果的最后一个文本块都会将此结构化结果序列化为 JSON,但会省略较早文本块中已逐字说明的内容,因为客户端可能只会将 content 传给模型。该文本块包含相同的 state、measured_at、coverage 和 freshness(成功时还包括 data_truncated 和 truncated;失败时则包括 error),字段逐一对应。它不包含 data,因为成功时 data 位于第一个文本块;也不包含说明中的句子,因为这些句子位于其前一个文本块中(失败时为错误消息),且 notes 以这些句子结尾:notes 只包含结果封装对自身的补充说明,没有补充说明时则省略。如果说明逐字引用了 method,它也会省略该字段,例如 cve_exposure 的说明(“Method: …”)。因此,所有文本块合起来就包含了结构化结果;但对于 TEXT CUT 所省略的答案内容(见“长答案”),这些文本块无法提供;而与 DATA CUT 不同,第一个文本块是从完整答案截取的,而不是从截断后的 data 中截取的。

state含义
measured对所询问内容进行了测量。只有当答案说明了所计数内容的观测时间(measured_at)和生成方式(method)时,暴露数量才属于 measured。没有暴露相关答案会说明截至今天的时间,因此两个暴露工具都不会返回 measured。
not_assessed答案没有所询问内容的带日期测量,因此不会将其中的任何数量呈现为测量结果:雷达不会查找此 CVE;答案没有说明雷达是否会查找;或者答案没有说明所计数内容的观测时间。答案仍可传达一个数量,作为来源记录中的未注明日期的数量:exposure_state 为 exposed 时,cve_exposure 的 exposed_hosts;以及 exposure_radar 中标明的总数。说明以及结果中包含的 exposure_state 会说明每个数量的含义。
failed查询未完成。并非调查结果。
invalid_input此服务端或 API 拒绝了输入,因此未进行查询。并非调查结果。
每个工具的 state、measured_at、coverage 和 freshness 分别包含什么,详见
docs/structured-results.md,其中按工具逐一说明。
每个字段都取自 API 发送的内容;如果 API 没有说明,字段值就是 null,并会在备注中说明。

如果成功响应中的字段不符合工具的 outputSchema(字段类型不在架构允许范围内),则会作为失败返回,error.kind 为 unexpected_shape,绝不会转发;唯一例外是:cve_summary 中 poller 字段的 JSON 类型不同时,会将其从 data 中省略,并在备注中指出,同时转发答案的其余部分以及 summary。API 后续新增的字段仍会由所有将 API 的 JSON 作为数据转发的工具转发;而 exposure_radar 和 cve_intel 会转发部分内容,因此会省略这些字段并指出省略了什么。

协议版本

该服务通过 stdio 同时响应新旧两个时期的 Model Context Protocol:

  • 2026-07-28:使用 server/discover 启动的客户端会收到一个 DiscoverResult,其中列出 2026-07-28、工具、提示词和资源能力,以及服务端说明;之后客户端会在每个请求中发送各自的 _meta 信封。
  • 2025 及更早版本:使用 initialize 启动的客户端(所有 1.x SDK 客户端均如此)会协商使用 2025-11-25、2025-06-18、2025-03-26 或 2024-11-05;如果服务端不认识某个版本,则会以 2025-11-25 响应。

连接的第一条消息决定其所属时期,之后会一直保持该时期。两种握手都会携带软件包名称和版本(serverInfo),并且每个 API 请求的 User-Agent 都会包含它们,格式为 echelongraph-mcp/<version>。

两种握手也都会携带服务端说明:数据是公开的;Shodan 数据属于 Shodan;state、measured_at 和 freshness 的含义;每个结果都会在其结构化结果和文本中再次包含这些信息;暴露数量是 ip:port 服务的汇总计数,并非整个互联网的普查结果。

说明和每个工具描述都不超过 2,048 个字符,这是已知客户端会截断的最短长度,因此没有客户端会因为在此处截断而丢失句子。描述会说明工具返回什么,以及哪些规则可避免将零值、false 或失败误读为发现结果;每个字段的完整计数定义都在工具的 outputSchema 中,而结果备注也会针对其转发的数字再次说明。

隐私:数据发送到哪里

npm 软件包(stdio)。 服务在你的计算机上运行,并向一个主机 ECHELONGRAPH_API_BASE(默认为 https://app.echelongraph.io)发送 HTTPS 请求;每次工具调用 API 都会发送一个请求(exposure_radar 会发送五个请求;其他每个工具都会发送一个请求)。没有遥测:它不会向 EchelonGraph 或任何其他对象发送任何额外内容。每个请求都会携带 User-Agent echelongraph-mcp/<version> (+https://echelongraph.io/pulse/mcp);如果你设置了 ECHELONGRAPH_MCP_UA,则该令牌会置于其前,因此 API 的访问日志可以按版本统计使用情况。与任何 HTTPS 请求一样,API 也会收到来自你网络地址的请求。

每个工具的输入会发送到哪里:

输入发送位置
CVE ID(get_cve、cve_exposure、epss_history、cve_intel、cve_remediation、vendor_advisories_for_cve)、CWE ID 和页码(get_cwe)、供应商和公告 ID(get_vendor_advisory)URL 路径。
search_cves:searchX-EG-Search 请求标头,不会放入 URL。严重性、最低 CVSS、排序方式、限制数量和偏移量会放入查询字符串。
search_vendor_advisories:queryX-EG-Advisory-Search 请求标头,不会放入 URL。供应商、严重性、CVE 筛选条件、限制数量和偏移量会放入查询字符串。
check_affected:product、version、ecosystem、packageX-EG-Product、X-EG-Version、X-EG-Ecosystem 和 X-EG-Package 请求标头,不会放入 URL。
cve_remediation:ecosystem、package、versionX-EG-Ecosystem、X-EG-Package 和 X-EG-Version 请求标头,不会放入 URL。CVE ID 会放入 URL 路径。
kev_recent:since、until、ransomware、vendor、limit、cursorX-EG-Since、X-EG-Until、X-EG-Ransomware、X-EG-Vendor、X-EG-Limit 和 X-EG-Cursor 请求标头,不会放入 URL。
check_sbom:purls 或 sbom 文档purls 会放入 POST 请求正文,每个正文最多包含 200 个。CycloneDX 或 SPDX 文档会在你的计算机上读取,只会发送其中的 purls;不会发送文档。(使用托管端点时,文档会发送到 EchelonGraph 的服务器:见下文。)
scan_manifest:files从文件中读取的 purls 会放入 POST 请求正文,每个正文最多包含 200 个;文件名、文件文本以及未检查的条目不会发送到 API。通过 npm 运行时,读取文件的服务在你的计算机上;使用托管端点时,该服务则是 EchelonGraph 的服务器,文件会作为请求正文发送(见下文)。
cve_summary、exposure_radar无输入。

API 会将通过标头传递的查询结果标记为 no-store,因此共享缓存不会保留这些结果;记录 URL 的请求日志和跟踪跨度也不会包含在其中查询的内容。 托管端点。 请求 https://mcp.echelongraph.io/mcp 会先到达 EchelonGraph 的 服务,然后由它调用上述同一个 API。每个请求都会记录 HTTP 方法(GET、 HEAD、POST、PUT、PATCH、DELETE、OPTIONS、CONNECT 或 TRACE,否则为 (other))和路径、状态码、 耗时、等待空位的时间(以及等待大型请求体时段的时间)、同时处理的请求数、占用的大型请求体时段 (以及最早占用的时长)、请求体大小、JSON-RPC 方法(MCP 定义的方法,否则为 (other))和工具或提示词名称、协议版本、是否发送了 Origin 标头、客户端 User-Agent 的第一个单词、客户端地址是否为公网地址(不记录该地址)、客户端是否提前关闭连接,以及请求是否受到限流或拒绝,以及原因。当某个 API 调用失败时,它会记录工具和 JSON-RPC 方法、调用的路由(不含 ID 或查询字符串,例如 /api/v1/public/cves/:id)、失败原因(例如超时、连接重置或 API 返回的状态码)、耗时,以及该请求是否来自我们的监控程序。记录错误时,只记录错误类型、固定的原因标签及其代码,以及请求的 JSON-RPC 方法和协议版本,从不记录错误消息。它从不记录工具参数或查询字符串。check_sbom 文档(或 sbom_review 提示词的文档)在此处和其他工具参数一样:它位于请求体中,因此整个文档都会发送到 EchelonGraph 的服务。服务会在内存中读取其中的 purl,仅将这些 purl 发送给 API,既不记录也不保留该文档。若要让文档留在你的计算机上,请运行 npm 包,或向 check_sbom 传入 purl。scan_manifest 的文件也一样:其全文位于请求体中,在内存中读取其中的 purl,只有这些 purl 会发送给 API;文件既不记录也不保留。若要让锁文件留在你的计算机上,请运行 npm 包。超过每个客户端的限额后,服务会记录该客户端的地址键。它会在一个标头中将客户端的公网地址传给 API;API 仅在验证通过其检查的令牌后才信任该标头,因此 API 的限流会按你的请求计数,而不是按托管服务计数。随后,API 的访问日志会按你的地址(IPv6 地址按其 /64 网段)记录每个此类调用及其 URL 路径:对于 CVE、CWE 或公告查询,还会记录你查询的 ID。它不会记录查询字符串,也不会记录上述通过标头传递的词项(对于 search_cves,会记录是否提供了词项及其长度,但不记录词项内容);对于 check_sbom 和 scan_manifest 的 purl,只记录数量,不记录具体内容。

EchelonGraph 的隐私政策:https://echelongraph.io/privacy。

速率限制

无需 API 密钥,因此 API 会在 60 秒窗口内汇总每个调用方的所有请求,并按单个 IPv4 地址或单个 IPv6 /64 网段进行限流:每分钟对 /api/v1/public/cves 及其下属路径限额 12,000 次;对 CWE、供应商公告、KEV 和 shadow-AI 路径限额 6,000 次;对任何其他公共路径限额 600 次;check_sbom 和 scan_manifest 的批量路由按组件计费,每分钟限额 1,200 个组件。超出限额时,工具会返回失败(state 为 failed,error.status 为 429),绝不会返回空数据;check_sbom 和 scan_manifest 会在单次调用的 50 秒内等待 429 响应的 Retry-After 时间,并返回已获取的结果,其余部分计入 coverage.not_sent。托管端点还会按每个客户端地址限制为每分钟 120 个 MCP 请求,并拒绝超过 64 KiB 的请求体(对于 check_sbom 或 scan_manifest 调用,以及 sbom_review 提示词,限额为 6 MiB)。所有限额按路径列于: docs/rate-limits.md。

配置

npm 包(stdio):

环境变量默认值用途
ECHELONGRAPH_API_BASEhttps://app.echelongraph.io覆盖 API 基地址(自托管/代理)。结果引用该基地址时,URL 中的凭据会被隐藏。
ECHELONGRAPH_API_TIMEOUT_MS15000单次请求的超时时间。较慢的响应会报告为查询失败,而不是空数据。
ECHELONGRAPH_MCP_UA未设置一个产品标识(例如 my-monitor/1.0),会置于此包自身的 User-Agent 前,以便区分监控器等自动调用方与使用该服务的人。若值不是单个标识,则会被忽略。

HTTP 入口 dist/http.js(npm run start:http)通过 POST /mcp,以 Streamable HTTP 提供相同的工具,并通过 GET /health 提供存活检查。在小型容器中,请限制 V8 堆内存(如何设置见 docs/rate-limits.md)。它会读取上述三个变量,以及以下变量:

环境变量默认值用途
PORT8080监听的端口。
MCP_RATE_LIMIT_PER_MIN120每个客户端地址、每个实例每分钟可发出的 MCP 请求数。
MCP_MAX_BODY_BYTES65536可读取的最大请求正文大小,SBOM 除外(见下文)。
MCP_MAX_SBOM_BODY_BYTES6291456tools/call 调用 check_sbom 或 scan_manifest,或 prompts/get 调用 sbom_review 时可读取的最大正文大小。
MCP_LARGE_BODY_SLOTS2可同时读取并处理的、超过 MCP_MAX_BODY_BYTES 的正文数量;超过此数量时,另外两个请求最多等待 MCP_LARGE_BODY_WAIT_MS(15000)以等待空位,之后返回 503 和 Retry-After。
MCP_MAX_IN_FLIGHT64可同时处理的请求数,不包括 subscriptions/listen 流;之后的请求及其正文读取会等待。
MCP_ADMISSION_WAIT_MS10000请求等待处理的最长时间,超时后返回 503 和 Retry-After。
MCP_BODY_IDLE_MS、MCP_REQUEST_TIMEOUT_MS10000、60000读取正文时,若正文在这段时间内没有任何内容,则返回 408;请求整体运行超过此时长则会被停止(见 docs/rate-limits.md)。
MCP_H2C未设置1:提供 HTTP/2 明文(h2c,先验知识),而不是 HTTP/1.1,这是 Cloud Run 的 --use-http2 所要求的;此时 HTTP/1.1 请求不会收到响应。
ECHELONGRAPH_FORWARD_TOKEN、ECHELONGRAPH_FORWARD_HOST、MCP_REQUIRE_FORWARD_TOKEN未设置仅用于 EchelonGraph 托管部署:用于在 API 中标识每个客户端的令牌。自行运行时请保持未设置;此时 API 会将每个请求都计为来自你的服务。

开发

npm install
npm run build      # tsc → dist/
npm test           # build, then the behavioural suite over both protocol eras, against a stub API
npm run smoke      # spawn the server + call cve_exposure against the production API

npm run smoke 会使用此包的 User-Agent 调用生产 API:从我们工作区以外的任何机器调用,都会计为 MCP 使用情况,除非你设置了 ECHELONGRAPH_MCP_UA(见“配置”)。 npm test 不会离开本机。

npm test 会针对 2026-07-28 的 server/discover 和 2025-06-18 的 initialize 运行。若要测试已安装的包而非 dist/,请将 ECHELONGRAPH_MCP_BIN 设置为其 echelongraph-mcp 可执行文件。

版本管理

语义化版本:主版本更新会改变协议行为或移除某个 Node.js 版本;次版本更新会添加工具或字段;补丁版本更新会修正文案或行为,但不改变工具的结构。每次发布都会由公共仓库的发布工作流从标记为 v<version> 的提交发布到 npm,并附带来源证明。各版本的变更: CHANGELOG.md。

自 3.1.0 起,成功响应的 outputSchema 在所有层级均为开放结构:每个对象都允许包含未列出的字段;除 state 外,每个枚举除了列出的值,也允许任意字符串;工具以 null 返回的 coverage 或 freshness 也允许是对象。因此,次版本更新新增的字段或值不会导致使用 3.1.0 或更高版本工具列表的客户端验证失败。失败分支中的所有对象仍为封闭结构,除以下四个枚举外,所有枚举也仍然封闭;这四个枚举原本就接受任意字符串: coverage.not_assessed_reason(check_affected)、coverage.vendor_windows[].history_backfill(vendor_advisories_for_cve、search_vendor_advisories)以及 coverage.vendor_window.history_backfill(get_vendor_advisory)。使用 3.0.2 或更早版本列出工具的客户端必须重新连接一次(CHANGELOG 中列出了相关调用)。如果客户端显示“does not match the tool's output schema”,说明它使用的是旧版架构:重新连接(Claude Code:输入 /mcp,然后重新连接 echelongraph),或重启客户端。

安全

请将漏洞私下报告至 [email protected],不要在公开问题中报告。相关政策、受支持版本和适用范围详见 SECURITY.md。

许可证

代码采用 MIT 许可证。

CVE Pulse 汇编(即 EchelonGraph 如何整合其 CVE 来源及其 EchelonGraph 评分)© EchelonGraph,依据 CVE Pulse 免费访问条款提供;其汇编所用的源记录仍受其发布者的条款约束。

暴露数量根据 Shodan 数据得出。Shodan 数据归 Shodan 所有,版权亦归 Shodan(© Shodan)。EchelonGraph 不主张拥有该数据或其版权。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。