G
YouTube TikTok Games
Skip to content
FazminPublic

About

Local security intelligence for CVE triage and remediation, with built-in SBOM functionality. 46 data sources and 42 tools, risk scores, fix plans for what you run, and an MCP server for AI agents - all built in native Rust. Private by default.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

147 stars

Watchers

0 watching

Forks

CVE Intel

Know which vulnerabilities matter, and what to do about them.
A private desktop app for vulnerability triage and scanning, written in native Rust, with a CLI, REST API and MCP server for developers and AI agents.
42 MCP tools, 46 data sources, SBOMs in and out, on-device AI.

Rust Tauri 2 MCP compatible License: MIT OR Apache-2.0

What it is · Getting started · Features · Install · Local AI · Data sources · Developer notes · Citing

Sped-up screen recording of CVE Intel on macOS: triage of CVE-2024-6387 and its How to fix it card, then the Remediation Lab: the plan for openssh on Ubuntu 22.04 with Ubuntu's own build first, ticking the fix and opening its runbook, ticking Ubuntu's mitigation instead and watching the SSVC decision move from Attend to Track, saving that as a decision and finding it in the ledger, then PAN-OS 10.2.8 with its hotfix and workaround, RHEL 8 as not affected, log4j-core, and Plan fix from a scan of lodash 4.17.20

Sped-up demo on macOS (video, or the full-length recording): from a triage result to a remediation plan for what you run, its runbook, a mitigation tried in What if and saved as a decision, and Plan fix from a scan. A second demo, of the landscape, decisions, scans and the watchlist, is under Features.

What is CVE Intel?

Every known software vulnerability gets a public ID, such as CVE-2024-3400. For each one, security, IT and development teams face the same question: does this affect us, and do we fix it now or can it wait? Answering it usually means checking NVD, CISA, FIRST, GitHub and vendor advisories by hand, one browser tab at a time.

Why it matters now

CVE publication keeps rising (48,185 in 2025, 20.6% more than 2024, and over 86,000 by 27 October 2026), and in April 2026 NIST said the National Vulnerability Database cannot keep up, so it will enrich CVEs in CISA's Known Exploited Vulnerabilities (KEV) catalog, federal-use software and critical software first, and move its unenriched backlog from before 1 March 2026 to "Not Scheduled". Meanwhile, Mandiant's M-Trends 2026 estimates the mean time to exploit at −7 days, so exploitation routinely begins before a patch is released, and exploits were the most common initial infection vector for the sixth year running (32% of intrusions).

What it does

Give CVE Intel a CVE ID, a project folder, a lockfile or SBOM, a container image, the software on this computer, your own domains, or a suspicious IP address, file hash or domain. It queries up to 46 public sources, including CISA KEV, FIRST's EPSS and ENISA's EU Vulnerability Database alongside NVD, and returns what the vulnerability is, a risk score from 0 to 100, whether attackers are already using it, the evidence behind each signal and what to do next. It also shows what changed this week across those sources, and watches the vendors, products and packages you run.

  • 46 data sources for vulnerability, exploit, network and threat intelligence, listed under Data sources. Many need no API key.
  • 42 MCP tools for AI agents and coding assistants. The same program is also a command line and a REST API (see Developer notes).
  • SBOMs in and out. It reads CycloneDX and SPDX SBOMs along with lockfiles, and Save SBOM (or scan deps . --format cyclonedx) writes any scan as a CycloneDX 1.5 SBOM with the findings, their risk signals and your recorded decisions.
  • Local. There is no CVE Intel account or server. Lookups go straight from your computer to the public sources, and the AI assistant runs on a local model unless you choose a remote provider.

It is for security analysts, IT and operations teams, developers checking their dependencies, and anyone learning vulnerability management.

What it helps you do

  • Decide whether to patch now: a 0–100 risk score, a plain recommendation and the evidence behind it.
  • Fix it on what you run: the Remediation Lab ranks the fixes and workarounds for your distribution, product or package, each with its source.
  • Put a list of CVEs in order: paste up to 10 from a scanner report and get the patch order.
  • Check your dependencies: drop a project folder, lockfile or SBOM and see the vulnerable packages, riskiest first, with the version that fixes each.
  • Check what you run and ship: this computer's apps and OS, a container image, or what public sources know about your own domains.
  • See what changed this week across CISA KEV, EPSS, ENISA, the exploit databases and CISA advisories.
  • Watch the products you run and hear about new CVEs, KEV listings, exploits and fixes.
  • Remember what you decided and hear when the reasons stop holding.
  • Search by product or KEV: every CVE for a product and version, or CISA's exploited list filtered by vendor, ransomware use or date.
  • Investigate something suspicious: an IP address, file hash, domain or URL.
  • Ask in plain English: the assistant looks up the facts first and shows its sources.
  • Give AI coding assistants the same knowledge through MCP.

Terms you'll see

Term What it means
CVE A public ID for one known vulnerability, such as CVE-2021-44228 (Log4Shell).
CVSS A 0–10 severity score: how bad the flaw is if someone exploits it. It says nothing about how likely an attack is.
EPSS The probability that a vulnerability will be exploited in the next 30 days, published daily by FIRST.
CISA KEV The US government's catalog of vulnerabilities known to be exploited by attackers. A CVE on this list is urgent.
ENISA EUVD The EU vulnerability database. Its own "exploited" flag is independent of CISA KEV and can raise the SSVC Exploitation input.
Exploit / PoC Public code that demonstrates or carries out an attack. A Metasploit module means the attack is packaged and easy to use.
SSVC A decision method from CISA and CERT/CC that ends in one of four actions: Act, Attend, Track* or Track.
SBOM / lockfile A list of every package your software uses, with exact versions.
MCP Model Context Protocol, the standard way AI assistants call outside tools.

The risk score combines these signals: severity (CVSS), the chance of exploitation (EPSS), confirmed exploitation (CISA KEV) and public exploit code. Anything on CISA KEV is always CRITICAL. See Risk score for the formula.

CVE Intel helps you decide what to patch. It does not probe, port-scan or attack anything, and it does not apply fixes. Scans read what is already on your machine (dependency files, the software installed on this computer, a container image you choose) and send only package and product names and versions to OSV.dev and NVD. The exposure check is passive: it asks public sources (Shodan, certificate transparency logs) what they already know about domains and addresses you own, and sends nothing to them. Results are only as current as the public sources.

Getting started

You don't need an account or any API keys to start. Most people are looking at their first result within a couple of minutes:

  1. Download the app for your operating system and open it. The Landscape view loads first: what changed this week across the public sources.
  2. Open CVE Triage, type a CVE ID such as CVE-2024-3400 and press Triage, or click one of the examples under the search box. Press Watch CVE (or Watch next to the vendor) to be told when it changes.
  3. Drag a project folder onto the window to check its dependencies, or open Scan and choose This computer to check the software installed on this machine. Findings come back ranked by real-world risk, with the version that fixes each one.
  4. Press ⌘K (Ctrl+K on Windows and Linux) to open Quick Find. Paste anything there (a CVE, IP address, file hash, domain, URL or package:ecosystem:version) and CVE Intel picks the right lookup.
  5. Optional: in Settings → Data source API keys, add free API keys for faster lookups and more exploit data. See API keys.
  6. Optional: open Local Model and download a model to use Ask AI with answers that never leave your computer.
  7. Optional: open MCP Server to connect your AI coding assistant.

The buttons at the bottom of the sidebar switch between the light and dark themes and make the text larger or smaller. The version you are running is shown below them.

Everything up to Developer notes is about the desktop app. To use CVE Intel from a terminal, a script, a CI pipeline or another program, go straight to that section.

Features

Sped-up screen recording of CVE Intel on macOS: the threat landscape, CVE Triage of CVE-2024-3400 and recording a decision, the decision ledger with stale, expired and review-due examples, a dependency scan with attack chains and a CycloneDX SBOM, and the watchlist

Sped-up demo on macOS (1080p video): the threat landscape, triage and recording a decision, the decision ledger, a scan with attack chains and an SBOM, and the watchlist.

The short version of each feature is below. For every option and caveat, see Features in detail.

Threat landscape

What changed recently across independent sources: new CISA KEV entries, CVEs ENISA marks exploited that KEV doesn't list, the biggest EPSS rises, new Metasploit modules and PoCs, new critical CVEs, Project Zero's in-the-wild zero-days and CISA advisories. Your watchlist comes first, then CVEs that several panels agree on. Copy as Markdown for a weekly note.

Threat landscape for the last 7 days: tiles for watchlist changes, KEV additions, exploitation ENISA reports but KEV does not list, new exploits and PoCs, EPSS risers, new critical CVEs, this year's zero-days and CISA advisories, above the watchlist panel with a chip for each watched item and its latest changes, such as Palo Alto Networks and Ivanti CVEs added to CISA KEV

Watchlist

Watch the vendors, products, packages and CVEs you run. Each refresh records what changed: new CVEs, KEV listings, EPSS jumps, new exploits, CVSS changes and newly available fixes. While the app is open it refreshes every 6 hours (change it in Settings). The list stays on this machine.

Watchlist of Fortinet, Palo Alto Networks, Ivanti, Citrix, Apache Tomcat 9.0.80, lodash 4.17.20 and CVE-2024-3400, with what a refresh recorded: Palo Alto Networks, Ivanti and Fortinet CVEs added to CISA KEV in October, new KEV-listed CVEs for Fortinet and Citrix, and four EPSS jumps, one from 9.1% to 94.0%

Decisions

Record what you decided on a CVE (patch now, defer until a date, accept, not affected, mitigated) and the assumptions behind it, such as "not in CISA KEV" or "not internet-facing". Every refresh re-checks them:

  • Stale: an assumption broke. The CVE entered KEV, an exploit or fix appeared, or EPSS crossed your threshold.
  • Expired / review due: a deferral passed its date, or a manual assumption passed its review date.
  • Calibration: how your past calls held up, such as how many CVEs you held back later entered KEV or gained an exploit, and how soon.

Export the ledger as OpenVEX or CycloneDX VEX. It stays on this machine; AI agents can read it but never change it.

CVE Triage

One lookup across NVD, CVE.org, EPSS, CISA KEV, ENISA EUVD and the exploit databases gives a 0–100 risk score, a recommendation and the evidence behind it. Deep triage adds CISA's SSVC decision. Two panels go further:

  • Who says what: the sources side by side, and where they disagree (scores 2+ points apart, NVD hasn't analysed it, a distribution says "not affected"). Marked Sources agree, Sources disagree or Thin evidence.
  • Exploit speed: how soon an exploit is likely (Hours, Days, Weeks), estimated from the public fix commit, the weakness type and the CVSS vector, with every reason shown.

Neither changes the risk score.

Deep CVE Triage for CVE-2024-3400 in the dark theme: a 100/100 CRITICAL score, CISA KEV and ENISA exploited flags, a weaponized exploit, the exploit-speed tile and CISA's SSVC "Act" decision

Ask in plain language

Ask "Which is worse: CVE-2024-3400 or CVE-2023-44487?" CVE Intel runs the lookups first, then the model explains the results and names the tools it used. Small local models can get details wrong, so check anything you will act on in CVE Triage.

Compare and prioritise

Paste 2 to 10 CVE IDs and get a patch order: CISA KEV first, then the risk score, with ties broken by ransomware use, EPSS and exploit maturity. Each CVE says why it sits above the next. The side-by-side table highlights the riskier values, and a summary shows what the CVEs share (same product, reachable without sign-in, public exploits).

Compare CVEs running the KEV vs. CVSS example: Log4Shell and HTTP/2 Rapid Reset, both in CISA KEV, ranked above curl's CVSS 9.8 SOCKS5 flaw, with the reason each one sits above the next

Remediation plans

Say what you run (a distribution package, a vendor product and version, or a library) and the Remediation Lab merges every source's advice into one ranked plan:

  • Fixes: your distribution's own build first (Ubuntu and Red Hat backport fixes), then the vendor's update or the upstream version.
  • Workarounds and mitigations in the vendor's words, with general controls ranked last.
  • Every option names its source. Nothing is made up, and a source that could not be reached is listed as a gap, not as "no advisory".

Open it with Open in Remediation Lab on a triage result, or Plan fix on a scan finding.

cve-intel remediate CVE-2024-6387 --distro ubuntu:jammy --package openssh@1:8.9p1-3ubuntu0.6
cve-intel remediate CVE-2024-3400 --product "PAN-OS@10.2.8"
cve-intel remediate CVE-2020-28500 --package npm:lodash@4.17.20

Remediation Lab for CVE-2024-6387 with openssh 1:8.9p1-3ubuntu0.6 on Ubuntu jammy: a fix exists; Ubuntu's own build 1:8.9p1-3ubuntu0.10 is first and marked "For what you run", citing Ubuntu Security, OSV.dev and USN-6859-1, with the packages to install and why it sits above the next option; Ubuntu's mitigation is ticked second; beside them the What if panel shows SSVC moving from Attend to Track with exposure controlled and mission impact low, what remains exposed, and the decision it amounts to, "Defer until 2026-12-13"

What if. Tick the options you are considering to see what stays exposed and how the SSVC decision changes, then Save as decision… (`--apply

--record` on the command line).

Runbooks. Runbook… (--runbook) turns the options you chose into steps: what to run, how to check it took, and how to back it out. CVE Intel never runs them.

Written by What leaves your computer
Fixed rules (the default) Nothing
The local model (adds a summary) Nothing
A cloud provider under Remote AI (--runbook --ai) The CVE, the kind of system, the options you chose and their public advisory text

A model's steps are checked against the plan's evidence, and risky commands (piping a download into a shell, turning off a firewall) are rejected.

Runbook dialog for that fix, made by fixed rules with no AI: the apt-get commands that upgrade openssh-client and openssh-server, the version each package should then be at, a reminder to restart what uses the package, and the dpkg-query command that checks it took, with buttons to copy the runbook or save it as Markdown

Scan dependencies

Drop a project folder on the window, or paste a lockfile, SBOM or package list. CVE Intel finds the npm, Yarn, Python, Rust, Go, PHP, Ruby and Maven files and CycloneDX or SPDX SBOMs, and checks the packages with OSV.dev. Only package names and versions leave your computer.

  • Ranked by real risk: Log4Shell in an old log4j-core comes first; a CVSS 9.8 nobody exploits does not. Each finding shows the version that fixes it.
  • History: scan again to see what is new, resolved or riskier. Tick Monitor to rescan daily, or Watch all affected to add the packages to the watchlist.
  • Chains: links findings into attack chains and names the break point, the one fix that cuts the most chains.
  • Save SBOM: writes the scan as a CycloneDX 1.5 SBOM with the findings, their risk signals and your decisions.

To run the same scan in a CI pipeline, see CI and automation.

Scan of a demo project with four dependency files, findings ranked by risk: Log4Shell in log4j-core first, with CISA KEV, ransomware and weaponized-exploit signals, then HTTP/2 Rapid Reset in golang.org/x/net, a second Log4j flaw and Spring4Shell, each with the version that fixes it

Scan History after the demo project was scanned again: log4j-core upgraded to 2.17.1 and lodash to 4.17.21 and ws added, so the row shows 3 new and 6 resolved findings, with the Monitor switch, Scan again and Forget, and each resolved CVE marked as fixed by an upgrade

Scan this computer

Scan → This computer checks the OS and installed apps: from the registry on Windows, Applications and Homebrew on macOS, and the package database on Linux. Apps CVE Intel recognises are checked with NVD; Linux packages with OSV.dev (Arch with the Arch Linux Security Tracker, matched locally). Apps it doesn't recognise are listed as not checked. List installed software shows what would be checked without contacting anything.

Scan a container image

Scan → Container image checks a docker save or OCI archive without Docker. Its OS packages and any lockfiles inside are checked with OSV.dev. Distributions OSV doesn't cover are listed as not checked, never reported clean.

docker save myapp:latest -o myapp.tar
cve-intel scan image myapp.tar --fail-on kev

Check your public exposure

Scan → Public exposure shows what public sources already know about domains and addresses you own. It finds your host names in certificate transparency logs, then asks Shodan what services, versions and CVEs have been seen on them. It is passive: CVE Intel never connects to or port-scans the targets.

cve-intel scan exposure example.com --authorized

Databases and data sources

Every upstream source, what it provides, whether it needs a key and how long results are cached. Check connectivity probes them all live.

Databases view: 46 upstream sources, 30 of them free without a key, the local cache and downloaded model, and a connectivity check with 35 of 46 sources reachable and 7 waiting on an API key

MCP server for AI agents

Give Claude Code, Cursor, VS Code, Claude Desktop, Windsurf or any MCP client CVE Intel's 42 tools. Start the server from the app and copy the setup steps, already filled in. Agents connect over HTTP (local only, port 8000 by default) or launch their own copy over stdio, and use your saved API keys. To set it up by hand, see MCP server setup.

MCP Server view in the dark theme with the server running on port 8000, setup steps for Claude Code over HTTP, and the 42 tools it offers

Also included

  • Quick Find (⌘K or Ctrl+K): paste a CVE, IP, hash, domain, URL or package:ecosystem:version and the right lookup runs.
  • Fixed versions: the version that fixes every known vulnerability in a package. Quick Find lodash:npm:4.17.15 to see it.
  • Product and KEV search: every CVE for a product and version, and filters over the CISA KEV catalog.
  • MITRE ATT&CK mapping for KEV-listed CVEs, plus inferred techniques, labelled as inferred.
  • IP, hash and domain intelligence from AbuseIPDB, GreyNoise, Shodan, VirusTotal, MalwareBazaar, crt.sh and more.
  • Activity: a searchable local history of your lookups and of the tool calls agents made.
  • Local Model: install the runtime and download a model in one click.

Common uses

Situation What to do in the app
What happened this week? Open Landscape, or ask "What's new this week?" in Ask AI.
A new CVE is in the news. Do we drop everything? Enter it in CVE Triage, or ask "Should we patch CVE-2024-3400 this weekend?" in Ask AI.
We run Fortinet (or another vendor). Tell me when something new hits it. Add the vendor on Watchlist, or press Watch next to the vendor on a triage result.
How do we fix this CVE on Ubuntu 22.04, or on the PAN-OS version we run? Press Open in Remediation Lab on the triage result and say what you run. The plan puts the fix for your release or branch first and names its sources.
The fix can't go in this week, or there isn't one yet. What do we do meanwhile? In Remediation Lab, tick the vendor's workaround to see what it leaves exposed, then Save as decision…. A deferral is re-checked until its date, and if no fix existed you hear when one ships. Runbook… gives you the steps.
We decided not to patch something yet. Tell me if that stops being safe. Press Record decision on the triage result and tick the reasons. Decisions marks it stale the moment one of them breaks.
A scanner reported 40 findings. Which come first? Paste the IDs into Compare CVEs, up to 10 at a time.
Checking dependencies before a release. Drop the project folder on Scan, or paste the lockfile or SBOM. Press Watch all affected to follow them, or Monitor in History to have it scanned again daily.
Is anything installed on this laptop being exploited? Scan → This computer, then Check. Findings in CISA KEV come first.
Is the image we ship affected by a new KEV entry? docker save it and drop the .tar on Scan → Container image.
What does the internet see on our servers? Scan → Public exposure with your domain; passive, nothing connects to your hosts.
Which version of a library fixes everything? Open Quick Find and paste lodash:npm:4.17.15.
What is known about the Tomcat version we run? Ask "Which CVEs affect Apache Tomcat 9.0.80?" in Ask AI.¹
Is anything from a vendor being exploited right now? Ask "Which Fortinet vulnerabilities are in CISA KEV?" in Ask AI.¹
An unknown IP appears in firewall or login logs. Paste it into Quick Find.
EDR flags an unknown file. Paste its SHA-256 hash into Quick Find.
You work in an AI coding tool. Open MCP Server, start the server and copy the setup steps for your agent.
You are new to vulnerability management. Ask "Explain EPSS and CISA KEV like I'm new."

¹ For these questions the model has to pick the right lookup itself, which larger local models and cloud providers do more reliably. The same searches are always available from the terminal (see Recipes).

Install

Download the file for your OS from the latest release. The desktop app, CLI, MCP server and REST API are all one executable, with nothing else to install.

OS File How to run
Windows CVE-Intel_<version>_windows-x64-setup.exe (or …-portable.exe) Run the installer, then open CVE Intel
macOS (Apple Silicon and Intel) CVE-Intel_<version>_macos-universal.dmg Drag CVE Intel to Applications
Linux CVE-Intel_<version>_linux-x64.AppImage (or .deb) chmod +x the file and run it

Each file has a .sha256 checksum next to it. Builds are not code-signed yet, so Windows SmartScreen and macOS Gatekeeper warn on first launch. On macOS, right-click the app and choose Open.

To build it yourself, run the headless server in Docker, or run the desktop app in a container and use it from your browser (no install), see Build from source and Docker.

Local AI

Ask AI uses a small language model that runs on your computer, so your questions stay private. Before the model runs, CVE Intel finds the CVE IDs, IPs, hashes and domains in your question, runs the matching lookups and gives the model the results as facts to rely on. If no model is running, Ask returns those lookup results directly, so it is useful before any download finishes.

Open the Local Model view to install the llama.cpp runtime and download a model, one click each (files go under ~/.cve-intel/). The default is Qwen 2.5 3B Instruct, a ~1.9 GB download that needs 6 GB of RAM; the 1B and 1.5B models need 4 GB and Qwen 2.5 7B needs 10 GB. On Apple silicon the view also offers two MLX models that run on the GPU and answer faster. The model server listens on 127.0.0.1 only. Already running Ollama, LM Studio or your own llama-server? See Use your own model server.

Remote providers (opt-in)

For stronger answers, open Configure → Remote AI and choose OpenAI, Anthropic, Google Gemini, or any OpenAI-compatible endpoint: a LiteLLM proxy, vLLM, Azure OpenAI, OpenRouter, Together, Groq, Ollama behind HTTPS… Paste a key (and for an OpenAI-compatible endpoint, its base URL), then pick a model. Save & use enables the provider and tests it; Save without switching keeps your current choice. You can switch back to the local model at any time.

Provider Default model Environment variables
OpenAI gpt-4o OPENAI_API_KEY
Anthropic claude-opus-5 ANTHROPIC_API_KEY
Google Gemini gemini-2.5-flash GEMINI_API_KEY
OpenAI-compatible endpoint (LiteLLM, vLLM, …) (the server's model name) CUSTOM_LLM_BASE_URL, CUSTOM_LLM_API_KEY (optional)

Models come from the provider itself: once a key is saved, the model list is fetched live from the provider's /models endpoint, so it shows every model your key can use (for OpenAI and Gemini, embedding, speech and image models are left out). Press ↻ to refresh it, or choose Other to type any model ID. Until a key is saved, a few suggestions are shown. The same settings work from a terminal:

cve-intel ai list                                   # every provider, where it sends requests, what it still needs
cve-intel ai set anthropic --key                    # hidden prompt
cve-intel ai models anthropic                       # every model the key can use, fetched live
cve-intel ai set anthropic --model claude-opus-5 --use
cve-intel ai set custom --url https://litellm.example.com/v1 --key --model claude-sonnet-5 --use   # LiteLLM, vLLM, …
cve-intel ai test                                   # one tiny request to the provider in use
cve-intel ai use local                              # back to the on-device model

--key reads the key from a hidden prompt (or stdin when piped), never from the command line.

  • Off by default. When a remote provider is selected, each question and the lookup results gathered for it are sent to that endpoint under its operator's terms. The Ask view shows a banner while this is on. A remediation runbook is written by the provider only when you ask for one, after the dialog (or the terminal) has shown exactly what would be sent.
  • Where requests go. OpenAI, Anthropic and Gemini use built-in HTTPS addresses. An OpenAI-compatible endpoint must be https://; plain http:// is accepted only to this machine (localhost, 127.0.0.1). A saved key is tied to its URL: changing the URL forgets the key, so it is never sent to a new host without being entered again. A key saved while the URL comes from CUSTOM_LLM_BASE_URL is saved with that URL, and CUSTOM_LLM_API_KEY is only sent to CUSTOM_LLM_BASE_URL. Requests to a loopback address skip HTTPS_PROXY.
  • Keys stay local. Keys are stored in ~/.cve-intel/settings.db with owner-only permissions. They are never shown again in the UI and never logged. You can use environment variables instead. See SECURITY.md.
  • No vendor SDK. Every provider here offers an OpenAI-compatible chat API with tool calling. Anthropic describes its compatible endpoint as intended mainly for evaluation; for Claude-specific features, use CVE Intel through MCP in a Claude client.

Data sources

The Databases view lists all 46 sources, and the CLI, REST API and MCP server report the same list.

Category Sources
Vulnerability intelligence NVD, NVD change history, CVE.org, CISA Vulnrichment, EPSS (FIRST) and its daily score files, CISA KEV, ENISA EUVD, VulnCheck NVD++, VulnCheck KEV, MSRC, Red Hat, Ubuntu, and CSAF advisories from Red Hat (VEX), SUSE (VEX), Cisco, Siemens and CISA ICS
Exploit intelligence GitHub PoC search, PoC-in-GitHub (nomi-sec), Exploit-DB, Metasploit modules, Nuclei templates, GitHub commits and pull requests (fix size for the exploit-speed estimate), Project Zero 0day In the Wild
Network intelligence AbuseIPDB, GreyNoise, Shodan, crt.sh, CIRCL Passive DNS
Threat intelligence VirusTotal, MalwareBazaar, ThreatFox, URLScan, CISA advisories (RSS), CIRCL Vulnerability-Lookup sightings, Ransomwhere, CIRCL hashlookup
DevSecOps and reference OSV.dev, Arch Linux Security Tracker, GitHub Advisories, MITRE ATT&CK (STIX), CTID KEV → ATT&CK mappings, MITRE CAPEC, HIBP Pwned Passwords

Many tools need no API key at all: EPSS and its daily files, KEV, ENISA EUVD, CVE.org and CISA Vulnrichment, OSV, the Arch Linux Security Tracker, CVSS, Exploit-DB, Metasploit, PoC-in-GitHub, Project Zero, CISA advisories, CIRCL sightings, ATT&CK, CAPEC, crt.sh, Ransomwhere, hashlookup, Pwned Passwords, and NVD at a lower rate limit. Large feeds (EPSS daily files, Exploit-DB, Metasploit, ATT&CK, CAPEC, the CTID mappings) are downloaded once, reduced to a small index, and refreshed daily or every few hours.

Risk score

Risk = CVSS×0.20 + EPSS×0.35 + KEV×0.30 + PoC×0.15   (boosters up to ×1.27, capped at 100)
  • KEV override: a CVE in CISA KEV is confirmed exploited, so it is always CRITICAL with a score of at least 76. Only CISA KEV earns the KEV points and the override.
  • EPSS measures the probability of exploitation. CVSS is treated as severity, not likelihood.
  • PoC is the strongest public exploit evidence. A Metasploit exploit module counts as weaponized (the full 15 points); Exploit-DB entries and VulnCheck XDB exploits count as public exploits.
  • Deep triage also returns the SSVC v2 CISA Deployer decision: Act, Attend, Track* or Track. Its inputs come from CISA's published SSVC assessment when there is one. Because that assessment is a snapshot, newer evidence can raise Exploitation: a CISA KEV, VulnCheck KEV or ENISA EUVD exploited listing, or an EPSS of 0.90 or more, makes it active. EUVD and VulnCheck do not change the risk score.
  • Bands: 0–25 LOW, 26–50 MEDIUM, 51–75 HIGH, 76–100 CRITICAL.
  • This is scoring version 1.1, reported as scoring_version in results.

API keys

Keys are optional. Each one unlocks more data or raises a rate limit. In the app, open Settings → Data source API keys, press Get a key to open the sign-up page, paste the key and press Save. The key is used on the next lookup, with no restart needed.

Key What it unlocks Get it
NVD API key 10× faster CVE lookups nvd.nist.gov
GitHub token (no scopes) Exploit search, Nuclei templates and advisory fixed versions (5,000 instead of 60 requests/hour) github.com/settings/tokens
VulnCheck token VulnCheck KEV (exploitation reports and XDB exploit links), and backup CVE data if NVD is down vulncheck.com
AbuseIPDB key IP abuse score abuseipdb.com
GreyNoise key Whether an IP is harmless background noise docs.greynoise.io
Shodan key Open ports and services on an IP account.shodan.io
VirusTotal key 70+ antivirus verdicts for a file hash virustotal.com
URLScan key Higher limits for URL checks urlscan.io
abuse.ch Auth-Key MalwareBazaar and ThreatFox lookups auth.abuse.ch
CIRCL passive DNS login Historical DNS records (access by request) circl.lu

Keys are stored in ~/.cve-intel/settings.db with owner-only permissions and shared by the app, CLI, MCP server and REST API on the same machine. A key saved in the app takes precedence over an environment variable. Free tiers and sign-up steps are set by each vendor, so check their pages. To manage keys from a terminal or with environment variables, see Terminal configuration.

Privacy and security

  • All network traffic is outbound HTTPS: to the data sources, to the cloud AI provider if you opt in to one, and for the model and runtime downloads you start (Hugging Face, the llama.cpp release on GitHub and, for MLX, uv and a Python 3.12 build from GitHub plus mlx-lm from PyPI).
  • API keys are never logged, cached, shown in the UI or returned by any tool.
  • Private and reserved IPs are rejected before any network lookup.
  • The local model server and the app's MCP server bind to loopback only.
  • SQLite files are created on first use: cache.db, a disposable lookup cache; ~/.cve-intel/settings.db, which holds keys, provider settings and the watchlist auto-refresh interval; and ~/.cve-intel/watch.db, the local watchlist (items, snapshots and change events). Clearing the cache never touches settings or the watchlist.
  • While the app is open, an optional background task can refresh the watchlist (every 6 hours by default). It only contacts the public sources needed for the items you watch, and you can turn it off in Settings. Nothing runs while the app is closed.
  • The desktop app keeps an activity log in ~/.cve-intel/activity.db (owner-only). It records what you look up and ask, the answers, setting and model changes, the tools agents call through the app's MCP server, and which hosts each action contacted. API keys are never recorded, only key names. Upstream requests are stored as host and path, without query strings. Open Activity to search it, pause it or clear it. It keeps the latest 20,000 entries. The CLI and cve-intel mcp record nothing.

See SECURITY.md for the full security model and how to report a vulnerability.

Developer notes

Everything in this section is for using CVE Intel from a terminal, scripts, CI pipelines, other programs or AI agents, and for building it yourself. The desktop app needs none of it.

The cve-intel executable

The desktop app and the command-line tool are the same file. Double-clicking it opens the app; running it with any argument starts the CLI, the MCP server or the REST server instead.

OS Executable
macOS /Applications/CVE Intel.app/Contents/MacOS/cve-intel
Windows (default per-user install) %LOCALAPPDATA%\CVE Intel\cve-intel.exe
Linux /usr/bin/cve-intel (.deb), or the downloaded .AppImage
# macOS
"/Applications/CVE Intel.app/Contents/MacOS/cve-intel" triage CVE-2024-3400
# Linux
./CVE-Intel_<version>_linux-x64.AppImage triage CVE-2024-3400
# Windows (default per-user install)
"%LOCALAPPDATA%\CVE Intel\cve-intel.exe" triage CVE-2024-3400

On Windows the executable is a windowed program, so the terminal does not wait for it. To see the output in order, use start /wait "" "…\cve-intel.exe" triage CVE-2024-3400, or in PowerShell & "…\cve-intel.exe" … | Out-Host. MCP clients start it directly and are not affected.

For servers and containers there is also a headless build without the GUI (cargo build --release -p cve-server, which produces target/release/cve-intel). From a source checkout, replace cve-intel with cargo run -p cve-server --. The examples below assume cve-intel is on your PATH.

Command line (CLI)

cve-intel triage CVE-2024-3400 --depth deep
cve-intel ask "Should we patch CVE-2021-44228?" --model qwen2.5-3b
cve-intel quick-find 185.220.101.34
cve-intel scan deps .                          # every lockfile, manifest and SBOM here, ranked by risk
cve-intel scan deps . --fail-on kev            # exit 3 if anything is in CISA KEV
cve-intel fix lodash npm 4.17.15               # version that fixes every known vulnerability
cve-intel remediate CVE-2024-6387 --distro ubuntu:jammy --package openssh@1:8.9p1-3ubuntu0.6
cve-intel product confluence_data_center --vendor atlassian --version 8.5.0
cve-intel kev-search --vendor microsoft --ransomware-only --epss
cve-intel landscape --days 7                    # what's new; --markdown for a ticket
cve-intel watch add vendor fortinet
cve-intel watch refresh && cve-intel watch changes --unread
cve-intel decide record CVE-2025-12345 --verdict defer --until 2026-12-31 --auto --note "waiting for the vendor"
cve-intel decide list --state needs_attention   # decisions whose reasons stopped holding
cve-intel decide calibration                    # how your decisions held up
cve-intel compare CVE-2024-3400 CVE-2023-44487
cve-intel password-check                       # hidden prompt; only a 5-character hash prefix is sent to HIBP
cve-intel sources --probe                      # every data source, with live status
cve-intel tls-check                            # HTTPS diagnosis: proxy, CA store, certificate chain, verdict
Command What it does
triage <CVE> [--depth quick|standard|deep] Risk score, recommendation, KEV, EPSS and exploit evidence; deep adds SSVC
lookup <CVE> The NVD and CVE.org record
search <keyword> [--severity …] [--limit N] Keyword search in NVD
compare <CVE> <CVE> … [--json] Compare 2–10 CVEs: patch order with the reason for each place, and what they have in common
epss <CVE,CVE,…> EPSS scores
kev <CVE> CISA KEV status, and VulnCheck KEV with a token
kev-search [--vendor] [--product] [--keyword] [--ransomware-only] [--added-since] [--due-before] [--epss] Filter the CISA KEV catalog, newest first
landscape [--days N] [--markdown] Threat briefing for the last 1–30 days
watch add vendor|product|package|cve … Watch a vendor, product, package or CVE
watch list|remove|refresh|changes List items, stop watching, refresh, or show recorded changes
product <name> [--vendor] [--version] [--cpe] CVEs affecting a product, KEV-listed first
fix <package> <ecosystem> <version> The version that fixes every known vulnerability
remediate <CVE> [--distro …] [--package …] [--product …] [--apply <option id>]… [--record] [--runbook [--ai] [--out file.md]] [--json] The remediation plan for what you run: fixes, workarounds and mitigations in order, each with its sources. --apply shows what the options would change, --record saves the choice as a decision, --runbook writes the steps
scan deps <path>… [--format text|json|sarif|markdown|cyclonedx] [--fail-on …] [--fail-on-severity …] Scan files or folders (- for stdin); findings ranked by risk; cyclonedx writes an SBOM with the findings in it. See CI and automation
scan-deps <file> [--sarif] Scan one lockfile, SBOM, manifest or package list; prints JSON
scan exposure <domain|ip>… --authorized [--no-subdomains] [--max-ips N] [--list-only] Passive public exposure: certificate logs, DNS, and what Shodan or InternetDB has seen on your addresses
scan image <file or folder> [--platform os/arch] [--list-only] A container image (docker save, OCI archive or folder): OS packages and lockfiles, checked with OSV
scan host [--list-only] [--lookup-unknown] [--max-products N] This computer's OS and installed apps, checked with NVD; --list-only contacts nothing
scans list|show <id|latest>|forget <key> Saved scans (scan … --save and the app), each with what changed since the scan before
cvss <vector> Score a CVSS vector
quick-find <anything> Detect the input type and run the right lookup
ip <address>, hash <hash>, domain <name> Threat intelligence for an IP, file hash or domain
password-check Check a password against HIBP Pwned Passwords
ask "<question>" [--model …] [--provider …] Ask a question; --provider openai|anthropic|gemini|custom uses a remote model
ai list|set|models|use|remove-key|test Configure remote AI for ask: OpenAI, Anthropic, Gemini or any OpenAI-compatible endpoint such as LiteLLM; models lists what your key can use (see Remote providers)
models list|download|remove, llama status|install|install-mlx Set up the local model and its runtime (install-mlx on Apple silicon)
keys list|links|set|remove Manage API keys (see Terminal configuration)
sources [--probe], health, clear-cache Data sources, health check, clear the lookup cache
tls-check [host…] [--json] For each host (default: the core sources): the proxy used, the CA store read, the certificate chain presented and whether it verifies. See HTTPS, proxies and private CAs
mcp, serve Start the MCP server over stdio, or the HTTP server (MCP and REST)

triage, fix, remediate, product, kev-search, landscape, watch, sources and ask print readable text; add --json for JSON. lookup, epss and kev print text, and the other lookup commands print JSON, ready for jq. Run cve-intel <command> --help for every option.

Recipes

Situation Command
What happened this week? cve-intel landscape --days 7 (add --markdown for a ticket)
Watch Fortinet and see what changed cve-intel watch add vendor fortinet then cve-intel watch refresh and cve-intel watch changes --unread
A new CVE is in the news. Do we drop everything? cve-intel triage CVE-2024-3400 --depth deep
A scanner reported 40 findings. Which come first? cve-intel compare CVE-… CVE-…
Which version of a library fixes everything? cve-intel fix lodash npm 4.17.15
How do I fix this CVE on what I run? cve-intel remediate CVE-2024-3400 --product "PAN-OS@10.2.8" (or --distro ubuntu:jammy --package name@version, or --package npm:name@version)
What is known about the Tomcat version we run? cve-intel product tomcat --vendor apache --version 9.0.80
Is anything from a vendor being exploited right now? cve-intel kev-search --vendor fortinet --added-since 2026-01-01
An unknown IP appears in firewall or login logs. cve-intel ip 185.220.101.34
EDR flags an unknown file. cve-intel hash <sha256> checks MalwareBazaar, VirusTotal and CIRCL hashlookup.
Checking dependencies before a release. cve-intel scan deps .

CI and automation

Fail a CI build on the findings that matter. scan deps takes files and folders (searched like the app does), ranks the findings by risk and exits with code 3 when a gate trips:

cve-intel scan deps . --fail-on kev                 # anything in CISA KEV
cve-intel scan deps . --fail-on exploited           # in KEV, or a public or weaponized exploit
cve-intel scan deps . --fail-on high                # risk HIGH or CRITICAL
cve-intel scan deps . --fail-on-severity critical   # the advisory's own rating, ignoring risk
Exit code Meaning
0 No gate tripped
1 An error; or --strict and something could not be checked; or a KEV-based gate when CISA KEV could not be loaded
2 Wrong command-line arguments
3 A gate tripped (change it with --exit-code N)

The risk score weighs exploitation, so a CVSS 9.8 that nobody exploits can rank LOW. Use --fail-on-severity to gate on advisory severity instead, or both. Without --strict, anything that could not be checked (a package OSV rejected, EPSS or the exploit indexes unreachable) is reported on stderr and does not fail the build. --enrich basic skips the exploit indexes (about 50 MB, downloaded once a day); on CI runners, cache CACHE_DB_PATH to avoid fetching them on every run.

--format markdown writes a summary table for $GITHUB_STEP_SUMMARY or a pull request comment, --format json the full result for jq, --format cyclonedx a CycloneDX 1.5 SBOM of everything scanned with each finding, its risk signals and your decisions attached (for Dependency-Track, a release artifact or an auditor; it works for scan image and scan host too), and -o FILE writes to a file:

cve-intel scan deps . --format markdown >> "$GITHUB_STEP_SUMMARY"
cve-intel scan deps requirements.txt --format json | jq '.summary'
cve-intel scan deps . --format cyclonedx -o sbom.cdx.json

Show the findings in GitHub code scanning (the Security tab and pull request annotations) by uploading SARIF:

# .github/workflows/dependencies.yml
on: [push, pull_request]
permissions:
  contents: read
  security-events: write
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Scan the dependencies with CVE Intel
        run: cve-intel scan deps . --format sarif -o cve-intel.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: cve-intel.sarif
          category: cve-intel

This assumes cve-intel is on the runner's PATH (for example the release AppImage, or cargo build --release -p cve-server). Each vulnerability is a rule with an OSV link and a security-severity. Each result points at the file and line that declares the package, names the advisory and the fixed version, and carries the risk score, KEV status and EPSS. Findings in KEV or with HIGH or CRITICAL risk are errors whatever the advisory's own rating.

Get a machine-readable verdict for a ticket or dashboard:

cve-intel triage CVE-2024-3400 --depth deep --json | jq '.risk | {risk_score, risk_label, urgency}'

REST API

cve-intel serve starts an HTTP server on 127.0.0.1:8000 (set HOST and PORT to change it, and see Serving HTTPS for TLS) with the REST API under /api/v1 and MCP at /mcp. The server the desktop app starts from MCP Server serves the same endpoints.

Method and path Returns
GET /health Version, scoring version, NVD and KEV status (with OAuth on, just {"status":"ok"})
GET /api/v1/health The same report, always in full
GET /api/v1/triage/{cve_id}?depth=quick|standard|deep The full triage report
GET /api/v1/cves/{cve_id} The NVD and CVE.org record
GET /api/v1/remediation/{cve_id}?distro=…&package=…&product=…&exposure=… The remediation plan, for what you run when a context is given
GET /api/v1/search?q=…&severity=…&limit=… NVD keyword search
POST /api/v1/quick-find with {"input": "…"} Auto-detected lookup
GET /api/v1/kev CISA KEV catalog summary
GET /api/v1/landscape?days=7 The threat-landscape briefing (format=markdown for Markdown)
GET /api/v1/watch The local watchlist (read-only)
GET /api/v1/watch/changes?unread_only=true Recorded watchlist changes (read-only)
GET /api/v1/scans, GET /api/v1/scans/{id}, GET /api/v1/scans/findings?min_risk=HIGH Saved scans and their findings (read-only; only on the server the app starts)
GET /api/v1/tools The tools with their input schemas: 42 on the server the app starts, 37 from cve-intel serve, which leaves out the tools that read your saved scans and decisions
POST /api/v1/tools/{name} with the tool's arguments Runs any tool
GET /api/v1/sources, POST /api/v1/sources/probe The source catalog, and live connectivity checks
DELETE /api/v1/cache Clears the lookup cache
GET /api/v1/models The local model catalog
POST /api/v1/ask with {"question": "…"} An Ask answer from the local model
POST /mcp MCP over streamable HTTP

Errors return HTTP 400 with {"error": "…"}.

curl -s "http://127.0.0.1:8000/api/v1/triage/CVE-2024-3400?depth=deep" | jq '.risk'

curl -s -X POST http://127.0.0.1:8000/api/v1/tools/find_fixed_version \
  -H 'content-type: application/json' \
  -d '{"package": "lodash", "ecosystem": "npm", "version": "4.17.15"}'

curl -s -X POST http://127.0.0.1:8000/api/v1/tools/get_attack_mapping \
  -H 'content-type: application/json' -d '{"cve_id": "CVE-2024-34102"}'
  • /api/v1/ask only uses the local model (or CVE_LLM_BASE_URL), never a remote provider, so a caller cannot spend your remote-AI key.
  • By default cve-intel serve has no authentication and allows cross-origin requests, so browser front ends can call it. That also means any web page open in your browser can reach it while it runs, so by default it only binds to loopback. To serve other machines, turn on OAuth (see Securing the HTTP server). The server the desktop app starts refuses web pages instead (see below).

Securing the HTTP server

To run cve-intel serve for a team or in production, put it behind your organisation's identity provider. The server then acts as an OAuth 2.1 resource server: every request needs an access token except /health and the discovery document, and MCP clients (Claude Code, Cursor, VS Code, …) discover where to log in from the server itself (RFC 9728 protected-resource metadata, as the MCP authorization spec requires). /health stays open for load balancers but only answers {"status":"ok"}; the full health report (NVD and KEV status, which API keys are set) moves to GET /api/v1/health, which needs a token. Each accepted request is logged with the user and client it came from, and each MCP tool call with the tool's name.

The server never issues tokens, never sees a password and needs no client secret. It checks each token's signature against the issuer's published keys (JWKS, found through OIDC discovery and cached), and its iss, aud, exp, nbf, iat, sub and optional scopes. Only asymmetric algorithms (RS256/384/512, PS256/384/512, ES256, ES384, EdDSA) are accepted, and a token with a crit header is refused. So is an OpenID Connect ID token: one with a Keycloak typ other than Bearer, a Cognito token_use other than access, or a nonce, at_hash, c_hash or s_hash claim. The check relies on those markers alone, so an ID token that has none of them gets in if its aud matches. That can only happen when the expected audience is the ID of a client that users sign in to, which is easy to set up by accident with Entra ID (see the Entra note below).

Variable Meaning
CVE_INTEL_OAUTH_ISSUER The authorization server's issuer, exactly as in its tokens' iss (keep or omit a trailing slash to match). Setting it turns OAuth on.
CVE_INTEL_OAUTH_RESOURCE The public URL of the MCP endpoint, e.g. https://cve.example.com/mcp. Required with the issuer.
CVE_INTEL_OAUTH_AUDIENCE Expected aud, comma-separated for several. Default: the resource URL.
CVE_INTEL_OAUTH_REQUIRED_SCOPES Scopes every token must carry (403 insufficient_scope otherwise), separated by spaces or commas. Default: none. Set but empty ("", ,) is an error.
CVE_INTEL_OAUTH_SCOPES_SUPPORTED Scopes advertised to clients, separated by spaces or commas. Default: openid plus the required scopes.
CVE_INTEL_OAUTH_REQUIRED_ROLES Who may use the server: roles or groups, separated by commas (a name may contain spaces, e.g. CVE Admin,/Security Team); a user needs any one of them. Default: none, so any valid token gets in. Set but empty ("", ,) is an error.
CVE_INTEL_OAUTH_JWKS_URI Use this JWKS instead of discovering it.
CVE_INTEL_OAUTH_LEEWAY_SECS Clock-skew allowance for exp, nbf and iat, 0–600 seconds. Default 60.
CVE_INTEL_ALLOW_UNAUTHENTICATED 1 to serve a non-loopback HOST without OAuth, for example behind your own authenticating proxy.

Without OAuth, cve-intel serve refuses to start on a non-loopback address (including Docker's 0.0.0.0) unless CVE_INTEL_ALLOW_UNAUTHENTICATED=1 is set. At startup with OAuth on, it fetches the issuer's discovery document and keys, and refuses to start if they can't be loaded, if none of the keys can verify tokens, or if the issuer in the discovery document doesn't match CVE_INTEL_OAUTH_ISSUER exactly. Keys the server doesn't understand (an ES512, ECDH-ES or ML-DSA key, say) are skipped. The keys are refetched every hour and when a token names an unknown key; if the issuer moves its keys, discovery runs again. While the issuer is unreachable, the keys already held keep working for up to four hours; after that, requests get 503 until it is back.

Each connection must send a complete request header within 10 seconds of connecting (or of its previous response), and the server holds at most 512 connections at once, counting those still in the TLS handshake. At the limit it stops accepting until one closes, and logs a warning at most once a minute. The connection limit is fixed.

The same 10 seconds also close an idle keep-alive connection. A load balancer that keeps idle connections to the server open longer (AWS ALB does for 60 seconds by default) can send a request on one just as the server closes it, and answer that request with a 502. Behind one, set CVE_INTEL_HEADER_TIMEOUT_SECS (1–3600 seconds) above the load balancer's idle timeout, e.g. 65 for an ALB. A longer timeout also gives a client that never finishes its header longer to hold a connection, so raise it only when a proxy or load balancer stands between the server and its clients. serve prints the value at startup when it isn't the default.

Keycloak example. With a realm acme at https://sso.example.com and the server at https://cve.example.com/mcp:

  1. Create a client for the resource server, e.g. cve-intel (no secret needed; it only represents the audience). Create a client scope, e.g. cve-intel-audience, with an Audience mapper whose Included Custom Audience is exactly https://cve.example.com/mcp. Without it, Keycloak's tokens carry aud: account and are rejected.

  2. Let your MCP clients register (dynamic client registration) or create a public client for them with that scope available.

  3. Configure the server:

    export CVE_INTEL_OAUTH_ISSUER=https://sso.example.com/realms/acme   # no trailing slash
    export CVE_INTEL_OAUTH_RESOURCE=https://cve.example.com/mcp
    export CVE_INTEL_OAUTH_SCOPES_SUPPORTED="openid offline_access profile cve-intel-audience"
    HOST=0.0.0.0 cve-intel serve

    Or put the three settings in .env (without export and without the comment), since cve-intel reads it at startup.

  4. Check it:

    curl -s https://cve.example.com/.well-known/oauth-protected-resource/mcp
    curl -si -X POST https://cve.example.com/mcp -d '{}' | grep -i www-authenticate
    claude mcp add --transport http cve-intel https://cve.example.com/mcp   # then /mcp to log in

Troubleshooting. cve-intel serve logs each rejected token's reason (wrong audience, token expired, …). cve-intel --debug serve logs the whole exchange: its discovery and JWKS fetches (URLs, status, the advertised issuer and endpoints, each key's id, type and algorithm), the metadata it served, and for every request the client, the token's header and standard claims (iss, aud, sub, azp, scope, times; control characters and bidi overrides shown as \u{..}), what the server expected, each check's result and the challenge it sent back. Tokens appear only as a fingerprint (tok: and 12 hex digits of their SHA-256) so one token can be followed across lines; the token, its signature and the Authorization header are never logged. A Keycloak token with aud="account" in that log means the audience mapper or the <client>-audience scope is missing, and not an access token means the client sent its ID token instead. Without --debug, only cve-intel's own lines appear; messages from the TLS, HTTP and proxy libraries (a scanner's illegal SNI, say) need --debug.

Notes for other providers: Entra ID puts scopes in scp (accepted) and uses api://<app-id> or the app ID as audience, so set CVE_INTEL_OAUTH_AUDIENCE; Auth0's issuer ends in /. Serve the public URL over HTTPS, from cve-intel itself (Serving HTTPS) or from a proxy in front of it; the URLs in the metadata and the WWW-Authenticate challenge come from CVE_INTEL_OAUTH_RESOURCE, never from request headers. If the proxy does its own authentication, exempt /mcp, /api/v1 and /.well-known/oauth-protected-resource* so its challenge doesn't replace the server's.

Entra ID and ID tokens. An Entra ID token's aud is the client ID of the app the user signed in to, and one from the code exchange carries no at_hash or c_hash, and no nonce unless the client sent one. If the MCP client signs in with the API's own app registration, so that CVE_INTEL_OAUTH_AUDIENCE is that client's ID, its ID token passes every check. Prevent it in one of two ways:

  • Give the API its own app registration, separate from the clients'. A client's ID token then carries the client's ID, not the API's, and fails the audience check.
  • Set CVE_INTEL_OAUTH_REQUIRED_SCOPES to a scope the API exposes (e.g. access_as_user). Entra puts scp only in access tokens issued to users, so an ID token never has it. This also refuses app-only (client-credentials) tokens, which carry roles instead of scp.

CVE_INTEL_OAUTH_REQUIRED_ROLES doesn't help here, because Entra puts the user's app roles in ID tokens too.

Who may use it. Without CVE_INTEL_OAUTH_REQUIRED_ROLES, any valid token for this server gets in. Set it to restrict the server to users who hold one of the listed roles or groups:

CVE_INTEL_OAUTH_REQUIRED_ROLES=cve-intel-user,secops

Separate entries with commas only, because role and group names may contain spaces (CVE Admin,/Security Team is two entries).

Each entry is matched exactly (case-sensitive) against the token's:

Claim Write it as Comes from
realm_access.roles cve-intel-user Keycloak realm roles (the roles client scope)
resource_access.<client>.roles cve-intel:admin (client:role) Keycloak client roles; only that client's roles count
groups secops or /org/secops Keycloak's group membership mapper (the microprofile-jwt scope, or a mapper you add), Okta; a top-level group's leading / is optional, a nested group needs its full path
roles CveIntel.User Entra ID app roles

A user who authenticates but holds none of them gets a plain 403 access_denied, with no bearer challenge (logging in again wouldn't help) and without the list of allowed roles. The server logs who was refused, and --debug shows which role and group claims the token carried. For Keycloak, make sure the clients your users connect with receive the roles scope (or your group mapper), or the claims won't be in the token; adding roles to CVE_INTEL_OAUTH_SCOPES_SUPPORTED asks clients for it. Saved scans and decisions are never served by cve-intel serve, so a permitted user can use every tool the server offers.

Serving HTTPS

OAuth providers and MCP clients expect the server's URL to be https://. cve-intel serve can serve HTTPS itself, with no reverse proxy, given a certificate and its private key:

Variable Meaning
CVE_INTEL_TLS_CERT The certificate chain in PEM: the server's certificate first, then any intermediates (certbot's fullchain.pem).
CVE_INTEL_TLS_KEY Its private key in PEM, unencrypted (certbot's privkey.pem): RSA of 2048 bits or more, ECDSA P-256 or P-384, or Ed25519.
CVE_INTEL_TLS_CERT=/etc/cve-intel/tls/fullchain.pem \
CVE_INTEL_TLS_KEY=/etc/cve-intel/tls/privkey.pem \
HOST=0.0.0.0 PORT=8443 cve-intel serve
# [cve-intel] MCP at https://0.0.0.0:8443/mcp · …
# [cve-intel] HTTPS on: certificate "/etc/cve-intel/tls/fullchain.pem" (SHA-256 3F:A2:…), reloaded when it changes
  • Set both or neither. If only one is set, a file can't be read, or the key doesn't belong to the certificate, serve refuses to start rather than fall back to plain HTTP. With TLS on, the port speaks only HTTPS.
  • The files are read again every minute, and a renewed certificate is used for new connections without a restart; the log shows its fingerprint (compare with openssl x509 -noout -fingerprint -sha256 -in <file>). If the new files don't load, for example while the certificate has been replaced but the key not yet, the server logs why once and keeps serving the previous certificate.
  • HTTPS protects the connection, not who may use it: a non-loopback HOST still needs OAuth (or CVE_INTEL_ALLOW_UNAUTHENTICATED=1).
  • Clients must trust the certificate, so use a public CA such as Let's Encrypt, or your organisation's CA installed on each client (Node-based clients also read NODE_EXTRA_CA_CERTS). A self-signed certificate works only where each client is set up to trust it. The certificate's names must include the host in CVE_INTEL_OAUTH_RESOURCE.
  • cve-intel doesn't obtain certificates itself. Get them with certbot (a standalone or DNS challenge), your CA or cert-manager. The user running cve-intel must be able to read the key, and certbot's keys are readable only by root, so copy them on each renewal, for example with certbot certonly … --deploy-hook 'install -m 0640 -g cve-intel "$RENEWED_LINEAGE/fullchain.pem" "$RENEWED_LINEAGE/privkey.pem" /etc/cve-intel/tls/'.
  • Ports below 1024 need privileges. Use a high port with a port forward (Docker: -p 443:8000), or on Linux grant the binary cap_net_bind_service with setcap.
  • TLS 1.2 and 1.3 only (rustls). cve-intel --debug serve logs each failed handshake and its reason, such as a client that doesn't trust the certificate.

MCP server setup

MCP is an open protocol and works with many clients, not only Claude. The easiest setup is the MCP Server view in the desktop app (see MCP server for AI agents). To configure it by hand:

# HTTP: connect to the server started from the app, or from `cve-intel serve`
claude mcp add --transport http cve-intel http://127.0.0.1:8000/mcp

# stdio: the agent launches its own copy (macOS app path shown)
claude mcp add cve-intel -- "/Applications/CVE Intel.app/Contents/MacOS/cve-intel" mcp

# stdio, using the headless binary
claude mcp add cve-intel -- /absolute/path/to/target/release/cve-intel mcp

Ready-made configs for Claude Code, Claude Desktop, Cursor, VS Code and other clients are in examples/mcp/.

The server exposes 42 tools, resources (kev://catalog, epss://scores/{cve_id}, manifest://tool-hash) and prompts (patch_decision, compare_and_prioritize, dependency_triage, remediation_runbook). It never registers a sampling handler or issues sampling/createMessage. Older tool names that duplicated other tools (prioritize_cves, check_exploit_availability, scan_container_packages, scan_repo_secrets) are no longer listed but still work. The watchlist tools (list_watchlist, get_watchlist_changes) are read-only: agents cannot add, remove or refresh items. The scan history tools (list_scans, get_scan_findings) are read-only too, and only answer local callers: MCP over stdio and the server the app starts. cve-intel serve accepts requests from any web page, so it does not serve saved scans.

The server started from the app always binds to 127.0.0.1 and checks the Host, Origin and Sec-Fetch-Site headers to refuse cross-site browser requests, which protects against DNS rebinding. It has no sign-in, so any program on the same computer can use it with your saved keys. Stop it when you don't need it.

Terminal configuration

Manage API keys without the app:

cve-intel keys list                          # which keys are set and where from (never prints values)
cve-intel keys links                         # where to get each key
cve-intel keys set SHODAN_KEY                # hidden prompt, keeps the key out of shell history
echo "$KEY" | cve-intel keys set SHODAN_KEY  # or pipe it in from a script
cve-intel keys remove SHODAN_KEY

For headless use, copy .env.example to .env, or set environment variables. Everything works without keys, with fewer results. A key saved in the app takes precedence over an environment variable.

In .env, one KEY=value per line, optionally after export. Quote a value that contains #: unquoted, a # after whitespace starts a comment (PASS=#abc keeps its #). Inside double quotes, \" and \\ stand for " and \; single quotes are literal. If a line is ignored, or text is cut from a value (a comment, or text after the closing quote), cve-intel prints a warning naming the line and key, never the value.

Purpose Variables
Data sources NVD_API_KEY, GITHUB_TOKEN, VULNCHECK_TOKEN, ABUSEIPDB_KEY, VIRUSTOTAL_KEY, SHODAN_KEY, GREYNOISE_API_KEY, URLSCAN_KEY, CIRCL_PDNS_USER, CIRCL_PDNS_PASS, ABUSECH_AUTH_KEY
Remote AI OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, CUSTOM_LLM_BASE_URL, CUSTOM_LLM_API_KEY
Local AI CVE_LLM_BASE_URL, CVE_LLM_MODEL, LLAMA_SERVER_BIN, MLX_LM_SERVER_BIN
Storage and server CACHE_DB_PATH, CVE_INTEL_HOME, HOST, PORT, CVE_INTEL_HEADER_TIMEOUT_SECS, REQUEST_TIMEOUT

HTTPS, proxies and private CAs

Certificates are checked by the operating system's verifier, so a CA you installed in the OS is trusted, including the CA of a TLS-inspecting proxy: the macOS keychains, the Windows certificate store, or on Linux the system bundle (update-ca-trust on RHEL/Amazon Linux, update-ca-certificates on Debian/Ubuntu). SSL_CERT_FILE / SSL_CERT_DIR replace the Linux bundle. HTTPS_PROXY, ALL_PROXY and NO_PROXY are honoured.

If a lookup fails with invalid peer certificate: UnknownIssuer, run cve-intel tls-check. It shows the issuer at the top of the chain the server sent, which is the CA missing from your store. Add --debug to any command to log TLS and connection details to stderr.

Use your own model server

Set CVE_LLM_BASE_URL to any OpenAI-compatible endpoint, such as Ollama (http://127.0.0.1:11434/v1), LM Studio or your own llama-server, and optionally CVE_LLM_MODEL to the model name. Ask then uses it instead of the built-in runtime. To use a llama-server or mlx_lm.server you installed yourself, set LLAMA_SERVER_BIN or MLX_LM_SERVER_BIN to its path. To use a remote provider from the CLI, configure it with cve-intel ai (see Remote providers), then cve-intel ask "Should we patch CVE-2024-3400?" --provider anthropic.

Build from source and Docker

# Desktop app (debug)
cargo build -p cve-intel-desktop
./target/debug/cve-intel-desktop

# Installable bundle (.dmg / .exe / .AppImage)
cargo install tauri-cli --version "^2" --locked
cd apps/desktop/src-tauri && cargo tauri build

# Headless binary only (servers, Docker)
cargo build --release -p cve-server

Docker runs the headless MCP server over HTTP, plus the REST API. The container listens on 0.0.0.0, so it needs OAuth, or an explicit opt-out when only this machine can reach it:

docker build -t cve-intel .
# Production: OAuth settings in .env (see "Securing the HTTP server")
docker run --rm -p 8000:8000 --env-file .env cve-intel
# Local only: published on the host's loopback, no sign-in
docker run --rm -p 127.0.0.1:8000:8000 -e CVE_INTEL_ALLOW_UNAUTHENTICATED=1 --env-file .env cve-intel
# HTTPS from the container itself (see "Serving HTTPS")
docker run --rm -p 443:8000 --env-file .env \
  -v /etc/cve-intel/tls:/tls:ro --group-add "$(getent group cve-intel | cut -d: -f3)" \
  -e CVE_INTEL_TLS_CERT=/tls/fullchain.pem -e CVE_INTEL_TLS_KEY=/tls/privkey.pem cve-intel

For HTTPS, mount the directory that holds the certificate and key, not the files themselves: a renewal replaces the files, and a single-file mount keeps showing the old one. The container runs as an unprivileged user, so --group-add gives it the group that may read the key.

To run the desktop app without installing it, use the container below and open http://127.0.0.1:6080 to see it over noVNC:

docker build -f Dockerfile.desktop -t cve-intel-desktop .
docker run --rm -p 127.0.0.1:6080:6080 --env-file .env -v cve-intel-data:/home/app cve-intel-desktop
  • noVNC asks for a password. The container prints a random one to its log at start-up. To pick your own, pass -e VNC_PASSWORD=... (VNC only checks the first 8 characters).
  • Keep 127.0.0.1: in the -p flag. Without it, anyone on your network can reach the app.

Architecture

crates/cve-core     Harness-agnostic engine: the source clients, risk scorer,
                    SSVC, CVSS, validators, lockfile/SBOM parsers, SARIF
                    and CycloneDX output, SQLite cache, settings DB, activity log and
                    watchlist, decisions, landscape briefing, source catalog,
                    remediation evidence, plans and runbooks, the CSAF
                    reader, llama.cpp and MLX manager, cloud-provider
                    settings and the Ask agent. No MCP, Tauri or CLI types.
crates/cve-server   The cve-intel binary: MCP (stdio and streamable HTTP),
                    REST (/api/v1) and the CLI, as thin adapters over cve-core.
apps/desktop        Tauri app linking cve-core and cve-server natively. The
                    same executable runs the GUI, the CLI and the MCP server,
                    and can host MCP over HTTP in-process. The model server
                    (llama-server, or mlx_lm.server on Apple silicon) is the
                    only child process.
examples/mcp        Client configs for common MCP clients.

Development and tests

cargo test -p cve-core -p cve-server   # scorer, SSVC, CVSS, validators, cache, parsers, agent routing, source catalog
cargo test -p cve-core -p cve-server -- --ignored   # live checks against the real sources (network)
cargo build --release                  # cve-intel and the desktop binary

See CONTRIBUTING.md for the full development setup and the checks CI runs.

Citing and attribution

Citing results in a report or ticket

CVE Intel gathers facts from public sources; it is not the source. When you record a decision, cite the primary source and the retrieval date, not the app or the AI's wording:

Example (illustrative values): CVE-2021-44228: CVSS 10.0 (NVD); listed in CISA KEV, added 2021-12-10 (CISA); EPSS 0.94 as of 2026-10-18 (FIRST). Retrieved 2026-10-18 with CVE Intel 0.3.0, scoring v1.1.

  • Scores change. EPSS updates daily, KEV grows and NVD entries are revised. Results are cached for minutes to hours, and up to a day for some feeds. The Databases view shows each source's cache time.
  • The risk score is CVE Intel's own. Cite it as "CVE Intel risk score (scoring v1.1)" alongside the underlying CVSS, EPSS and KEV values. cve-intel health and the System view show the version.
  • An AI answer is not evidence. Local or cloud, a model can be wrong. Cite the data shown beside the answer and verify it against the source.

Citing this software

@software{cve_intel,
  title   = {CVE Intel: local security intelligence for CVE triage},
  author  = {{CVE Intel contributors}},
  year    = {2026},
  version = {0.3.0},
  url     = {https://github.com/Fazmin/cve-intel},
  license = {MIT OR Apache-2.0},
  note    = {Native Rust desktop app, CLI, MCP server and REST API}
}

Use the version you ran (cve-intel --version).

Data source terms

CVE Intel only queries these services. It does not own or republish their data, and their terms apply to anything you copy out of the app. Check each provider's current terms, especially before commercial use. This is not legal advice.

Source Credit and terms
NVD (NIST) Products using the NVD API should state: "This product uses data from the NVD API but is not endorsed or certified by the NVD." See the terms of use.
EPSS (FIRST) Attribute FIRST and link first.org/epss. Daily score files are hosted at epss.empiricalsecurity.com.
CVSS (FIRST) first.org/cvss
CISA KEV Credit CISA: Known Exploited Vulnerabilities Catalog.
ENISA EUVD EU Vulnerability Database: euvd.enisa.europa.eu. Subject to ENISA's terms.
CISA advisories RSS feed of CISA alerts and ICS advisories: cisa.gov.
PoC-in-GitHub Repository index by nomi-sec/PoC-in-GitHub. Repositories are listed, not scanned.
Project Zero 0day In the Wild Google Project Zero's public spreadsheet: 0day.html.
CIRCL Vulnerability-Lookup Sightings from vulnerability.circl.lu.
CVE.org CVE records are provided under the CVE Terms of Use. CVE® is a registered trademark of The MITRE Corporation.
CISA Vulnrichment CISA's ADP enrichment (SSVC, CVSS, CWE), released under CC0 1.0: github.com/cisagov/vulnrichment.
SSVC CERT/CC and CISA: github.com/CERTCC/SSVC
VulnCheck KEV, XDB and NVD++ Shown with VulnCheck's attribution, "VulnCheck KEV (VulnCheck Known Exploited Vulnerabilities), https://vulncheck.com/kev". Use is subject to VulnCheck's terms.
Metasploit Framework Module metadata from rapid7/metasploit-framework, BSD-3-Clause.
MITRE ATT&CK® Registered trademark of The MITRE Corporation. See the terms of use.
MITRE CAPEC™ Attack patterns from capec.mitre.org; see the terms of use.
CTID Mappings Explorer KEV → ATT&CK mappings by the Center for Threat-Informed Defense, Apache-2.0: mappings-explorer.
Arch Linux Security Tracker Advisory groups published by the Arch Linux Security Team at security.archlinux.org.
OSV.dev, GitHub Advisory Database Attribution varies by database; the GitHub Advisory Database is CC BY 4.0. See osv.dev and github.com/advisories.
abuse.ch (MalwareBazaar, ThreatFox) Community data; see abuse.ch.
Others VirusTotal, Shodan, AbuseIPDB, GreyNoise, URLScan, CIRCL, Red Hat, Ubuntu, Microsoft MSRC, crt.sh, Exploit-DB, Ransomwhere and HIBP each have their own terms and rate limits. Free tiers are often limited to non-commercial use.

Local AI models are not part of this project and carry their own licences, such as the Llama 3.2 Community License and size-dependent Qwen licences. Read the model's page before commercial use. GGUF files come from the Hugging Face repositories listed in crates/cve-core/src/llm.rs (the vendors' own for Qwen, bartowski's builds for Llama), and MLX builds from the mlx-community conversions. The runtimes are llama.cpp (MIT) and, on Apple silicon, mlx-lm (MIT).

Community

License

Copyright 2024-2025 Fazmin Nizam. Licensed under either of

at your option. See also NOTICE.

These licenses cover the CVE Intel code. Data and models the app downloads keep their own terms; see Data source terms.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Local security intelligence for CVE triage and remediation, with built-in SBOM functionality. 46 data sources and 42 tools, risk scores, fix plans for what you run, and an MCP server for AI agents - all built in native Rust. Private by default.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

147 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages