需要 Python 3.10+;必须先到 vulners.com 注册并获取 API key,或设置 VULNERS_API_KEY 环境变量;MCP server 需额外安装 pip install "vulners[mcp]";v4.0 预发布版尚未上 PyPI,需从 v4.0 分支源码安装
api
vulnersComMIT活跃维护Vulners 漏洞情报 API 的官方 Python SDK,可查询 CVE、漏洞利用和公告(含 CVSS/EPSS/KEV),审计软件、主机与 SBOM,并提供同步/异步客户端和内置 MCP 服务供 AI Agent 调用。
Official Python SDK for the Vulners vulnerability-intelligence API — search CVEs, exploits and advisories (CVSS/EPSS/KEV), audit software, Linux/Windows hosts and SBOMs, and stream the whole graph. Typed sync + async clients, 100% v3-compatible, with a built-in MCP server for AI agents.
pip install -U vulnersREADME 未说明,纯 Python 客户端,无 GPU 或显存要求
Vulners 官方 Python SDK,用几行代码查询 CVE、漏洞利用和公告,并审计软件与主机
Vulners 漏洞情报 API 的官方 Python SDK,可查询 CVE、漏洞利用和公告(含 CVSS/EPSS/KEV),审计软件、主机与 SBOM,并提供同步/异步客户端和内置 MCP 服务供 AI Agent 调用。
核心能力
- 用 Lucene 语法查询 CVE、公告和 exploit,结果带 CVSS、EPSS、KEV 上下文
- 审计软件、Linux 主机和 SBOM,找出受影响的漏洞
- 以流式方式拉取整个漏洞图谱归档,无需缓冲数 GB 数据
- 提供同步 Vulners 与异步 AsyncVulners 两套类型化客户端
- 内置 MCP server,把漏洞情报接入 AI agent
容易踩的坑
- v4.5.0最新正式版2026-10-29 · 2026-10-29 08:52 UTC
Vulners Python SDK 4.5.0
A maintenance release — the SDK's own API is unchanged. It moves the dependency set off every release that carried an open advisory, and then on to the newest release of everything.
Security
Four advisories were critical, and all four sit on paths this client actually uses:
Package Was Now Why it matters here brotli 1.2.0 1.2.1 out-of-bounds write in the decoder, which runs on every response a server answers with Content-Encoding: brcertifi 2026.7.22 2026.10.23 the older bundle ships emSign root CAs whose intermediate keys were compromised anyio 4.13.0 4.15.1 TLSStreamencoded host names with IDNA 2003, which enables certificate spoofingauthlib 1.7.2 1.9.1 empty JWS signatures and empty HMAC keys were accepted — signature forgery (reaches this project only through the mcpextra)Also
mcpto 1.30.0,opentelemetry-apito 1.45.1, anddnspythonto 2.9.0 on Python 3.11+ — upstream's fix for that one requires 3.11, so the 3.10 leg of the lockfile stays on 2.8.0.What this means if you just install the package: the entries above are lockfile contents, and the lockfile governs this repository's CI, not your environment —
pip install vulnersresolves these transitively from PyPI and already picked the patched releases up. The exception isbrotli, a declared runtime dependency whose floor still admitted the vulnerable 1.2.0; from this release it isbrotli>=1.2.1. That is the only change to published metadata besides themcpextra below.Changed
- The
mcpextra now accepts fastmcp 4 (fastmcp>=2.0,<5), over the officialmcp2.3.0 SDK. Worth knowing before upgrading: fastmcp 4 rides onhttpx2— the httpx 2.x line, published under that name by Pydantic — sopip install "vulners[mcp]"ends up with two HTTP stacks, fastmcp'shttpx2alongside thehttpx0.28 this SDK uses itself.vulners-mcp, its seven tools and its configuration are unchanged, and the server is exercised against the live API on the new stack.
Fixed
- The 100% branch-coverage gate no longer fails at random. The "a sibling range failed, skip queued work" branch of the parallel archive download was only reached when the event loop happened to interleave the transport's I/O a particular way, so it missed in roughly half of runs — including on the previous dependency set. It is now pinned by a test where the skip is the scheduler's only possible outcome.
Internal
- 63 locked dependencies upgraded, 6 added, 14 removed. Majors among them: mypy 2.4.1, pytest 9.2.0, ruff 0.17.3, msgspec 0.22, rich 15, python-dateutil 3 — none needed a source change. The lockfile's resolution cutoff moved with them and now keeps a one-day quarantine instead of sitting months back.
- Supply-chain review of the refreshed tree: every artifact resolves from pypi.org and is pinned
by sha256, OSV reports no advisory against the locked set other than the dnspython note above,
and each newly added package was checked by hand. Three of them read like typosquats and are
not —
httpx2andhttpcore2are the httpx 2.x line maintained by Pydantic, andhttpx2-jsfetchis its Pyodide transport, which the lockfile markssys_platform == 'emscripten'and therefore never installs off the browser. - Pinned GitHub Actions and the uv toolchain are current:
actions/checkoutv7.0.1 (which clears the last Node 20 deprecation warning),astral-sh/setup-uvv10.3.3, uv 0.13.6 in CI, and theuv_buildband moved to>=0.13.1,<0.14. CONTRIBUTING.mdnow documents the two environment rules this refresh made load-bearing: thecodegengroup cannot share a resolution with thetestgroup or themcpextra, and the lockfile's resolution cutoff is deliberate rather than stale.
Full changelog: https://github.com/vulnersCom/api/blob/master/CHANGELOG.md
- The
- v4.4.02026-10-15 · 2026-10-15 07:50 UTC
查看更新说明
Vulners Python SDK 4.4.0
Added
documents.list_references(id, *, type=..., limit=20, offset=0, fields=...)— page through every bulletin related toidthrough a shared CVE, viaGET /api/v4/search/references. Returns aReferencesPage(async:AsyncReferencesPage, both importable fromvulners):- iterating the page fetches the following pages until the relation is exhausted;
totalandtotal_by_typedescribe the whole relation as visible to your licence, regardless of thetypefilter and of the page;- ids of related documents that no longer exist are listed in
missinginstead ofdata.
from vulners import Vulners with Vulners(api_key="YOUR_API_KEY_HERE") as v: page = v.documents.list_references("CVE-2021-44228", type="exploitdb", limit=100) print(page.total, page.total_by_type) # the whole relation for bulletin in page: # fetches the following pages as needed print(bulletin.id)Documentation
documents.references()and thereferences=Truelookups are capped by the server at 1000 related documents per id; when a list is cut,/api/v3/search/idanswers206 Partial Contentwith the usual body. Both clients already treat 206 as success; usedocuments.list_references()for the full relation.metrics.epssin audit results is a one-element list holding the highest-EPSS CVE as a full record{cve, epss, percentile, date}, the same shape on every audit endpoint; per-CVE scores are incvelistMetrics(or the advisory'sepss[]onsbom_audit).
Full changelog: https://github.com/vulnersCom/api/blob/master/CHANGELOG.md
- v4.3.02026-08-21 · 2026-08-21 08:58 UTC
查看更新说明
Vulners Python SDK 4.3.0
Added
-
audit.metadata(registry, name, version)— look up a package's license and version-range metadata viaPOST /api/v4/audit/metadata(public on all plans). Returns a typedPackageMetadatawithname,version,rangeandlicense(always a list, never a bare string).The SDK handles the details every ad-hoc client used to re-invent:
registryis lower-cased for you;- for Maven the
nameis thegroupId:artifactIdcoordinate — a/is converted to the required:; licenseis read as an array.
PackageMetadata.founddistinguishes a package the registry does not know (the endpoint answers HTTP 200 with an emptyrange) from a known package with no recorded license (foundisTrue,license == []). API and network errors raiseVulnersError— an empty license list is never a silent stand-in for an error.Also exposed on the MCP server as the
audit_metadatatool, and importable asfrom vulners import PackageMetadata.
from vulners import Vulners with Vulners(api_key="YOUR_API_KEY_HERE") as v: print(v.audit.metadata("pypi", "requests", "2.28.0").license) # ['ISC'] print(v.audit.metadata("pypi", "no-such-package", "9.9.9").found) # False print(v.audit.metadata("maven", "com.google.guava:guava", "30.0-jre").license) # ['Apache-2.0']Full changelog: https://github.com/vulnersCom/api/blob/master/CHANGELOG.md
-
- v4.2.02026-08-18 · 2026-08-18 09:10 UTC
查看更新说明
Vulners Python SDK 4.2.0
Support for the Vulners v4 audit API updates.
Added
audit.kb_audit(os_name, kb_list, *, os_version=..., fields=...)now targets the new/api/v4/audit/kbendpoint and returns one finding per missing update: a result withitems(each carrying the fixing packagefixedPackageand the updateadvisories, which list the KBs theysupersedes) plustotalPackages. The deprecated v3 endpoint (flatkbLatest/kbMissed/cvelist) is preserved asaudit.kb_audit_v3(os, kb_list).audit.smart(..., fields=[...])— project which fields each vulnerability carries (e.g.metrics,exploitation,cvelist,cvelistMetrics,epss); an unknown field is rejected by the server with400. Each result now also includesfixedVersion.audit.software(..., cvelist_metrics=True)andaudit.host(..., cvelist_metrics=True)— enrich each finding with per-CVEcvelist/cvelistMetrics. Results carry the resolvingfixed_version, and the applied projection is echoed in theX-Vulners-Applied-Optionsresponse header.audit.linux_audit(..., fields=[...])andaudit.library_audit(..., fields=[...])— apply advisory enrichment options (metrics,cvelistMetrics); the result reports theappliedOptionsthat took effect and anywarningsfor unsupported ones.audit.sbom_audit(..., cvelist_metrics=True)— sent as a query option (the request body carries the uploaded file); the result carriesappliedOptionsandwarnings.
Changed
- Breaking:
audit.kb_auditmoved from the v3 endpoint to/api/v4/audit/kb. Its request now usesos_name(notos) and its response shape changed from a flat CVE list to per-update advisories. Callers that need the old flat shape should useaudit.kb_audit_v3.
Full changelog: https://github.com/vulnersCom/api/blob/master/CHANGELOG.md
- v4.1.02026-08-17 · 2026-08-17 11:20 UTC
查看更新说明
Vulners Python SDK 4.1.0
Added
archive.download_getsploit(path, *, connections=8)— download the getsploit exploit database archive to disk over multiple parallel HTTP range connections, saturating the link while using constant memory, with an automatic fallback to a single stream when the storage does not offer ranges. The write is atomic, and the raw archive (a single-member zip containinggetsploit.db) is what lands on disk. The SDK-owned client transfers the ranges over a dedicated HTTP/1.1 connection pool so each connection opens a real socket (HTTP/2 would multiplex them onto one, throttling throughput); with your ownhttp_client, sethttp2=Falsefor the same benefit. Legacy v3 endpoint.
Changed
archive.download_collection(...)now downloads over multiple parallel range connections (newconnections=8argument) instead of a single stream, sharing the same engine asdownload_getsploit. It falls back to a single stream when the storage does not offer ranges; the output (the raw compressed archive) and the atomic-write behavior are unchanged.
Documentation
- Every public client, resource and model method now carries a complete reference
docstring (arguments, return values and errors), rendered on the documentation site
at https://vulnersCom.github.io/api/ and in
api.md.
Full changelog: https://github.com/vulnersCom/api/blob/master/CHANGELOG.md
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
🛡️ Vulners Python SDK
The official Python client for Vulners — the vulnerability intelligence graph to build on
Query CVEs, exploits and advisories enriched with CVSS, EPSS and exploitation status; assess your software, hosts and SBOMs for the vulnerabilities that affect them; and stream the whole graph for your own pipelines — all from a few lines of typed, async-ready Python.
SDK documentation · Data models · Get an API key · Vulners.com
Why Vulners?
Vulners aggregates 230+ sources — CVEs, exploits, vendor advisories, CISA KEV, EPSS and AI risk scores — into one queryable vulnerability-intelligence graph, so you can prioritize what to fix beyond raw CVSS. It is API-first and needs no agents or network access: send asset data in standard formats, get back risk-prioritized intelligence.
This SDK is the fastest way to build on that graph from Python:
- 🔎 Intelligence — search and enrich CVEs, bulletins and advisories with CVSS, EPSS, KEV and exploitation context
- 🧨 Exploits — track active exploitation and pull proof-of-concept code for a product or CVE
- 🖥️ Assessment — find the vulnerabilities affecting your software, Linux/Windows hosts, KBs, libraries and SBOMs
- 🗄️ Datasets — stream the full graph (and hourly updates) into your own pipelines and mirrors
- 🔔 Alerts — subscribe to new vulnerabilities matching a query and get notified via webhook
- 🤖 AI-ready — a built-in MCP server, typed bulletin models and documented response shapes to ground AI agents on live vulnerability facts
Installation
pip install -U vulners
Requires Python 3.10+. A plain pip install vulners pulls everything needed for fast, modern
transport — httpx, pydantic and
orjson, plus HTTP/2 (h2), response compression
(brotli/zstandard), ISA-L-accelerated gzip (isal) and streaming archive decode
(ijson/stream-unzip) — all with prebuilt wheels, so there is no build step.
From a branch checkout (unreleased)
The latest pre-release lives on the v4.0 branch (not yet on PyPI). Check the branch out
and install it from source:
git clone -b v4.0 https://github.com/vulnersCom/api.git
cd api
pip install -e . # editable install from the checkout
Or install that branch directly, without cloning:
pip install "git+https://github.com/vulnersCom/[email protected]"
Quickstart
from vulners import Vulners
# Get a free API key at https://vulners.com (or export VULNERS_API_KEY).
with Vulners(api_key="YOUR_API_KEY_HERE") as v:
# Look up a CVE — you get back a typed model (or None if it isn't found).
log4shell = v.search.get_bulletin("CVE-2021-44228")
if log4shell is not None and log4shell.cvss is not None:
print(log4shell.id, "—", log4shell.title)
print(log4shell.cvss.score, log4shell.cvss.vector)
# Search with Lucene syntax. `limit` is the page size; read the first page here
# (iterating the page itself auto-paginates the whole result window).
page = v.search.query("type:cve AND cvss.score:[9 TO 10]", limit=10)
for bulletin in page.data:
print(bulletin.id, bulletin.title)
Tip: keep your key out of source code — read it from the environment:
import os from vulners import Vulners v = Vulners(api_key=os.environ["VULNERS_API_KEY"])
Async
The same API is available on AsyncVulners:
import asyncio
from vulners import AsyncVulners
async def main():
async with AsyncVulners(api_key="YOUR_API_KEY_HERE") as v:
page = await v.search.query("Fortinet AND RCE", limit=20)
for bulletin in page.data:
print(bulletin.id, bulletin.title)
asyncio.run(main())
Usage examples
Runnable scripts for every task live under
samples/ — a v4 set and a matching
v3 (legacy) set, side by side.
Find public exploits for a CVE
for exploit in v.search.query("bulletinFamily:exploit AND CVE-2023-20198", limit=10).data:
print(exploit.id, exploit.href)
Audit installed software for known CVEs
# Mix product/version dicts and raw CPE 2.3 strings.
for item in v.audit.software([{"product": "openssl", "version": "1.0.1"},
"cpe:2.3:a:apache:log4j:2.14.1"]):
print(item["matched_criteria"], "->", len(item["vulnerabilities"]), "vulnerabilities")
Audit a Linux host by installed packages
report = v.audit.linux_audit(os_name="debian", os_version="10",
packages=["openssl 1.1.1d-0+deb10u3 amd64"])
for issue in report["issues"]:
print(issue["package"])
Look up a package's license
from vulners import Vulners
with Vulners(api_key="YOUR_API_KEY_HERE") as v:
meta = v.audit.metadata("pypi", "requests", "2.28.0")
print(meta.license) # ['ISC'] — always a list, never a bare string
# An empty license with meta.found is True means "known, but no recorded license".
# meta.found is False when the registry does not know the package name at all.
unknown = v.audit.metadata("pypi", "no-such-package", "9.9.9")
print(unknown.found) # False
# For Maven the name is the "groupId:artifactId" coordinate; the registry name is
# lower-cased for you, so you never touch the colon-vs-slash / casing details.
guava = v.audit.metadata("maven", "com.google.guava:guava", "30.0-jre")
print(guava.license) # ['Apache-2.0']
Stream the archive (lazily, without buffering gigabytes)
for record in v.archive.iter_collection("cve"):
... # each record is yielded as it arrives (a lazily-streamed JSON array)
Handle errors
from vulners import Vulners, APIError, RateLimitError
try:
with Vulners(api_key="YOUR_API_KEY_HERE") as v:
cve = v.search.get_bulletin("CVE-2021-44228")
except RateLimitError as err:
print("slow down; retry after", err.retry_after, "s")
except APIError as err:
print(err.status_code, err.error_code, err.message) # the server's problem description
Data models
Every document the API returns is a bulletin, and the SDK models them in three typed layers, so your editor and type checker know the exact shape at whatever level of detail you need:
Bulletin— the base fields every document carries (id,title,cvss,published, …).- Family models (
CveBulletin,ExploitBulletin,ScannerBulletin, …) — one perbulletinFamily, adding that family's shared fields. - Collection models — one per collection
type, adding the fields specific to that source.
search/archive/audit return the most specific model that fits a document (type →
bulletinFamily → Bulletin). Every field is optional (a missing one is None) and every model
keeps extra="allow", so a field the API adds before the SDK models it is still on the object —
nothing is ever dropped.
from vulners import Vulners, CveBulletin
with Vulners() as v: # reads VULNERS_API_KEY
cve = v.search.get_bulletin("CVE-2021-44228")
if isinstance(cve, CveBulletin):
print(cve.cwe) # typed, cve-specific field — IDE-completed
The full hierarchy — every family and collection with its fields, descriptions and examples, generated from live data — is browsable in the Data models reference.
Proxies
Route traffic through a proxy with proxy=, or let the client pick up the standard proxy
environment variables:
from vulners import Vulners
# explicit (a URL, or httpx.Proxy(..., auth=(user, pass)) for an authenticated proxy)
v = Vulners(api_key="YOUR_API_KEY_HERE", proxy="http://proxy.corp.example:8080")
# or from the environment — HTTPS_PROXY / HTTP_PROXY / ALL_PROXY, honoring NO_PROXY:
# export HTTPS_PROXY="http://proxy.corp.example:8080"
v = Vulners(api_key="YOUR_API_KEY_HERE")
Environment proxies are used when you don't pass proxy= and leave trust_env=True (the
default). See
Proxies, timeouts & retries
for authenticated proxies and combining a proxy with custom TLS.
AI agents (MCP)
Ship live Vulners intelligence to AI agents and copilots via the built-in Model Context Protocol server:
pip install "vulners[mcp]"
VULNERS_API_KEY=... vulners-mcp # run the MCP server
It exposes concise, typed tools — search bulletins, look up a CVE, find exploits, and audit
software/Linux/hosts — that any MCP-compatible client (Claude, IDE agents, …) can call. See
AGENTS.md.
Hosted vs. bundled. For a fully managed, always-on endpoint, use the official hosted server at https://mcp.vulners.com/ — no install required. The
vulners-mcpshipped in this package is a minimal, self-hosted implementation (a core set of tools) for embedding in your own environment.
Backward compatibility
Upgrading from 3.x is a drop-in. The entire v3 API — VulnersApi, VScannerApi, every method,
and all import paths — is preserved unchanged in 4.0:
import vulners
api = vulners.VulnersApi(api_key="YOUR_API_KEY_HERE") # still works exactly as before
cve = api.search.get_bulletin("CVE-2021-44228") # returns a dict, as it always did
New code should prefer the Vulners / AsyncVulners clients above. Migrate at your own pace — see
the migration guide.
Getting an API key
- Create a free account at vulners.com.
- Follow the authentication guide to generate a key.
- Pass it to
Vulners(api_key=...), or exportVULNERS_API_KEYand let the client read it.
Never commit your API key. The SDK authenticates with the X-Api-Key header; a few legacy
endpoints additionally send the key where the server requires it — in the request body (the
subscription and webhook mutations and win_audit) or the query string (webhooks.read()). On
every request it strips the key on cross-origin redirects, refuses redirects to internal
addresses, and keeps it out of exception messages and object reprs.
Documentation
| Resource | Link |
|---|---|
| 📘 SDK documentation | https://vulnersCom.github.io/api/ |
| 🧬 Data models (bulletin hierarchy) | https://vulnersCom.github.io/api/reference/bulletins/ |
| 🔌 SDK API reference (clients, resources, exceptions) | https://vulnersCom.github.io/api/reference/clients/ |
| 🧭 Migration (v3 → v4) | https://vulnersCom.github.io/api/explanation/migration/ |
| 📖 Vulners platform docs | https://docs.vulners.com/docs/ |
| 🧪 Interactive API (Swagger) | https://docs.vulners.com/docs/api/swagger/ |
| 🔑 Authentication / API keys | https://docs.vulners.com/docs/quickstart/authentication/ |
| 💡 Examples | samples/ |
| 🤝 Contributing | CONTRIBUTING.md |
| 🔒 Security policy | SECURITY.md |
Compatibility
- Python: 3.10, 3.11, 3.12, 3.13, 3.14
- Platforms: Linux, macOS, Windows
- Vulners API: v3 and v4 endpoints
Contributing
Issues and pull requests are welcome! Please open an issue to discuss substantial changes first. The project uses uv:
uv sync
make check # lint + typecheck + unasync-check + tests
See CONTRIBUTING.md for the full workflow.
Security
Found a security issue in the SDK? Please report it privately — see SECURITY.md. Do not open a public issue for vulnerabilities.
License
Distributed under the MIT License. See LICENSE.
Built by the Vulners team. If this SDK helps secure your stack, please ⭐ the repo — it helps others find it.
Keywords: vulnerability intelligence · CVE · exploit intelligence · CVSS · EPSS · CISA KEV · risk prioritization · security advisories · SBOM · vulnerability assessment · vulnerability scanner · threat intelligence · vulnerability database · AI security agents · MCP · MSSP · DevSecOps · Python security · infosec