KernelScan
Linux kernel CVE analyzer: upload a .config, get a CycloneDX VEX report of affecting CVEs.
我该使用它吗
质量与安全性
发现(2)
- HIGH
- MEDIUM在 create_product 中
基于对工具定义和协议合规性的自动分析。
上下文开销
这是每次将服务器的工具加载到模型上下文窗口时所消耗的大致 token 数。数值越高,可用于其他任务的注意力就越少。
安装
一键安装
将以下内容添加到你的 `claude_desktop_config.json` 文件中:
{
"mcpServers": {
"kernelscan": {
"url": "https://kernelscan.io/mcp/"
}
}
}远程端点
https://kernelscan.io/mcp/streamable-http它能做什么
工具清单
工具(11)
🟢search_cves(query, severity, cvss_min, published_after, limit)
Search Linux kernel CVEs. No API key required: keyless callers get the free public tier — recent high-severity Linux kernel CVEs (capped at 25 results). Free *keyed* callers see only CVEs published in the last 60 days; basic+ keyed callers get the full corpus. ``query`` matches against CVE id and description (case-insensitive). ``severity`` filters by effective severity (``critical``/``high``/``medium``/``low``). ``cvss_min`` filters by effective CVSS score. ``published_after`` (ISO 8601) returns only CVEs newer than that date. Returns up to ``limit`` (max 100) CVEs, newest first.
输入模式
{
"type": "object",
"properties": {
"query": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Query"
},
"severity": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Severity"
},
"cvss_min": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"default": null,
"title": "Cvss Min"
},
"published_after": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Published After"
},
"limit": {
"default": 25,
"title": "Limit",
"type": "integer"
}
},
"title": "search_cvesArguments"
}🟡get_cve(cve_id)
Fetch a single Linux kernel CVE by ID (e.g. ``CVE-2024-12345``). No API key required: keyless callers get the public representation of a CVE, but only for CVEs in the public set (recent high-severity); any other id returns ``not found``. Free *keyed* callers get a 404 for CVEs published more than 60 days ago. AI risk-summary / analysis fields are included for any keyed user on CVEs in the public set, and for pro / enterprise on every assessed CVE.
输入模式
{
"type": "object",
"properties": {
"cve_id": {
"title": "Cve Id",
"type": "string"
}
},
"required": [
"cve_id"
],
"title": "get_cveArguments"
}🔴list_products
List the calling user's products with denormalized analysis stats. Paid plans only (basic / pro / enterprise). Free callers get a clear upgrade message.
输入模式
{
"type": "object",
"properties": {},
"title": "list_productsArguments"
}输出模式
{
"type": "object",
"properties": {
"result": {
"items": {
"additionalProperties": true,
"type": "object"
},
"title": "Result",
"type": "array"
}
},
"required": [
"result"
],
"title": "list_productsOutput"
}🟢get_product(product_id)
Fetch one product owned by the caller, including the CVE breakdown. Returns 404 (not 403) if the product belongs to another user, so product existence isn't leaked across accounts.
输入模式
{
"type": "object",
"properties": {
"product_id": {
"title": "Product Id",
"type": "string"
}
},
"required": [
"product_id"
],
"title": "get_productArguments"
}🟢get_product_vex(product_id)
Return the VEX MANIFEST for one of the caller's products — metadata, not the document. Multi-megabyte CycloneDX documents (up to 8,000+ vulnerability entries) are not safe model-context payloads, so this tool returns a bounded manifest: CycloneDX format/spec version, product id, generated/expires timestamps, the VEX hash and the composite ETag identity, the uncompressed size in bytes, total + per-status vulnerability counts, and the authenticated REST download path. Reads from the 24h ProductVexCache; if the cache is empty/expired the next call to ``get_product`` (or the REST endpoint) will regenerate it. The MANIFEST carries the same ``kernelscan.io:exploit_maturity`` / ``kernelscan.io:kev`` overlay identity as the REST download (backend#337), so ETags compare across transports. To inspect the entries themselves, use ``list_product_vex_entries``. To retrieve the COMPLETE CycloneDX document, use the authenticated REST endpoint ``GET /api/products/{product_id}/vex`` (same ks_live_ key) — that is the canonical way to retrieve the full artifact; no MCP tool returns it.
输入模式
{
"type": "object",
"properties": {
"product_id": {
"title": "Product Id",
"type": "string"
}
},
"required": [
"product_id"
],
"title": "get_product_vexArguments"
}🟢list_product_vex_entries(product_id, statuses, severities, kev, exploit_maturity, ...)
Page through the VEX vulnerability entries of one of the caller's products. Returns COMPLETE CycloneDX vulnerability objects for one bounded page — never the root document, never all entries — plus ``returned``, ``total_matching``, and a ``next_cursor`` to continue with. Every result is bounded to 256 KiB: the page stops before the byte limit and returns a cursor when necessary. Entries are ordered by CVE id (ascending) and carry the same live ``kernelscan.io:exploit_maturity`` / ``kernelscan.io:kev`` properties as the REST download (backend#337). Filters (all optional, combinable): - ``statuses``: ``affected`` / ``not_affected`` / ``in_triage`` - ``severities``: ``critical`` / ``high`` / ``medium`` / ``low`` / ``none`` - ``kev``: true/false — CISA KEV listing only / non-KEV only - ``exploit_maturity``: ``poc`` / ``weaponized`` - ``cve_ids``: exact-match list of CVE ids ``limit`` defaults to 25, maximum 100. ``cursor`` is the opaque continuation token from a previous page — it is tied to the product, the active filters, AND the current document + threat-overlay revision: changing filters, a regenerated cache, or a KEV/PoC signal that moved since the last page invalidates it (start a fresh page without a cursor — re-using a stale one is rejected, never silently re-applied). Within one revision, concatenating all pages yields each matching CVE exactly once. The COMPLETE multi-megabyte CycloneDX document is served by the authenticated REST endpoint ``GET /api/products/{product_id}/vex`` (same ks_live_ key) — the canonical way to retrieve the full artifact.
输入模式
{
"type": "object",
"properties": {
"product_id": {
"title": "Product Id",
"type": "string"
},
"statuses": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Statuses"
},
"severities": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Severities"
},
"kev": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"title": "Kev"
},
"exploit_maturity": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Exploit Maturity"
},
"cve_ids": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Cve Ids"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
},
"limit": {
"default": 25,
"title": "Limit",
"type": "integer"
}
},
"required": [
"product_id"
],
"title": "list_product_vex_entriesArguments"
}🔴create_product(name, kernel_version, arch, config_upload_id, description, ...)
Create a new product, run analysis, and return its initial stats. ``config_upload_id`` references a previously-staged .config that the caller POSTed to ``/api/configs/uploads`` over plain HTTP — the LLM does NOT emit the config text itself (a real kernel .config is ~100–200 KB and exceeds a single tool-call output budget). Workflow: 1. Caller / wrapper script: ``curl -H "Authorization: Bearer ks_live_..." \ -F "[email protected]" \ https://kernelscan.io/api/configs/uploads`` returns ``{config_upload_id, sha256, size_bytes, expires_at}``. 2. Pass that ``config_upload_id`` into this tool. Uploads are per-user, single-use, and expire 30 minutes after upload. Same gates as POST /api/products: free can't create products; paid plans are capped at their resolved product limit — read it (and any per-account override) from ``whoami.product_limit`` rather than assuming a fixed per-tier number. ``factor_ids`` are silently ignored unless the plan allows security factors (``whoami.can_use_factors``). Re-using a product name returns 409. Creating a product RUNS an analysis, so it spends one unit of the team's SHARED monthly analysis allowance (``whoami.monthly_analyses_used`` / ``monthly_analyses_limit``). When the allowance is exhausted the tool fails with "Monthly analysis limit reached (…/month) [429]". This is a durable monthly quota — NOT the transient per-call rate limit that also surfaces as 429: it will not clear until next month, so report it to the user instead of retrying. Check ``whoami`` before a batch of creates.
输入模式
{
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"kernel_version": {
"title": "Kernel Version",
"type": "string"
},
"arch": {
"title": "Arch",
"type": "string"
},
"config_upload_id": {
"title": "Config Upload Id",
"type": "string"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Description"
},
"factor_ids": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Factor Ids"
}
},
"required": [
"name",
"kernel_version",
"arch",
"config_upload_id"
],
"title": "create_productArguments"
}🟡update_product(product_id, name, description, kernel_version, arch, ...)
Update a product owned by the caller. Re-runs analysis if the kernel_version, arch, or referenced .config changed. To change the .config, first POST the new file to ``/api/configs/uploads`` (see ``create_product`` for the curl recipe) and pass the returned ``config_upload_id`` here. Leave ``config_upload_id`` as ``None`` to keep the existing .config. ``factor_ids=None`` leaves factor selections untouched; an empty list clears them. Same tier gates as PUT /api/products/{id}. A change that re-runs analysis (``kernel_version``, ``arch``, or the ``.config``) spends one unit of the team's shared monthly analysis allowance and can fail with the same durable "Monthly analysis limit reached … [429]" quota error as ``create_product`` (distinct from the transient rate-limit 429 — don't retry it). A rename / description / factor-only edit runs no analysis and is free.
输入模式
{
"type": "object",
"properties": {
"product_id": {
"title": "Product Id",
"type": "string"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Name"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Description"
},
"kernel_version": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Kernel Version"
},
"arch": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Arch"
},
"config_upload_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Config Upload Id"
},
"factor_ids": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Factor Ids"
}
},
"required": [
"product_id"
],
"title": "update_productArguments"
}🟢whoami
Return the caller's identity, plan, and quota state. Works without an API key: keyless callers get a lightweight public-tier payload (no account) describing how to request access.
输入模式
{
"type": "object",
"properties": {},
"title": "whoamiArguments"
}🟢request_access(email, name, reason)
Explain how to get a KernelScan account (no API key needed). Self-registration is open — there is no invitation to wait for and no admin in the loop. The user signs up on kernelscan.io themselves (email + password, accepting the terms), confirms the verification mail, and mints a ks_live_ API key on their account page. This tool only hands that path back: it files nothing and sends no mail. ``email`` / ``name`` / ``reason`` are still accepted so older clients don't break, but they are ignored — never tell the user that a request was submitted on their behalf.
输入模式
{
"type": "object",
"properties": {
"email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Email"
},
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Name"
},
"reason": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Reason"
}
},
"title": "request_accessArguments"
}🟡submit_support_report(category, subject, message, cve_id, product_id, ...)
Send a support / dispute report to KernelScan staff. Use this when an automated CVE or factor assessment looks wrong, or when you need to hand human-needed context back to the team. The caller's API-key user is attached automatically (id, email, plan) so support can look the account up. ``category`` should be one of: - ``cve_assessment`` — wrong AI verdict / CVSS / CWE on a CVE - ``factor_assessment`` — wrong factor verdict for a product - ``bug`` — broken behavior in the API or UI - ``other`` — anything else ``cve_id`` / ``product_id`` / ``assessment_id`` are optional but recommended — they let support jump straight to the relevant row.
输入模式
{
"type": "object",
"properties": {
"category": {
"title": "Category",
"type": "string"
},
"subject": {
"title": "Subject",
"type": "string"
},
"message": {
"title": "Message",
"type": "string"
},
"cve_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cve Id"
},
"product_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Product Id"
},
"assessment_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Assessment Id"
}
},
"required": [
"category",
"subject",
"message"
],
"title": "submit_support_reportArguments"
}推荐提示词
search_cvessearch_cvesget_cveget_cvelist_products社区
证据