Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,070Paid calls: 1,528Letters: 13Defects: 1,322counted 2 min ago
teppi

Server definition

Hash
sha256:8ff182d582c13edcc20bf93c0ac8a6b0728b9e065f37cb8982323b9b5f5e5bae
What it is
What a remote MCP server returned when asked what it offers: 11 tools

The blob, as servednamed by its sha256

{ "instructions": "KernelScan exposes the Linux kernel CVE database and per-user product analyses (CycloneDX VEX) over MCP. No API key required to get started: keyless callers get a free public tier covering recent high-severity Linux kernel CVEs — browse it with search_cves and get_cve. Registration is open and needs no invitation: the user signs up at https://kernelscan.io/?auth=register and mints their own key (request_access just spells that out). Authenticate for everything else either by connecting through the client's own sign-in (OAuth: the user approves once in the browser, no key to copy) or via `Authorization: Bearer ks_live_<key>` — manage keys at /api/auth/api-keys and connected clients at /account. Either credential unlocks the full CVE corpus (free keyed callers see CVEs published in the last 60 days; basic / pro / enterprise plans add the full feed plus product-analysis tools). create_product / update_product take a `config_upload_id` — kernel .config files are too large to emit as tool arguments, so ask the user to first POST the file to /api/configs/uploads (a normal HTTP multipart request, same ks_live_ Bearer auth) and pass the returned id here. Product VEX documents reach multi-megabyte sizes, so they are served bounded over MCP: get_product_vex returns a manifest (format, counts, size, ETag identity, REST download path) and list_product_vex_entries pages through filtered vulnerability entries (max 256 KiB per call, continuation cursor). The complete CycloneDX document is never returned as a tool result — fetch it from the authenticated REST endpoint GET /api/products/{id}/vex (same key), the canonical way to retrieve the full artifact. These MCP tools are the canonical programmatic interface; the equivalent REST API is described by a public OpenAPI schema at https://kernelscan.io/openapi.json (no separate spec to discover).", "tools": [ { "description": "Create a new product, run analysis, and return its initial stats.\n\n ``config_upload_id`` references a previously-staged .config that the\n caller POSTed to ``/api/configs/uploads`` over plain HTTP — the LLM\n does NOT emit the config text itself (a real kernel .config is\n ~100–200 KB and exceeds a single tool-call output budget). Workflow:\n\n 1. Caller / wrapper script:\n ``curl -H \"Authorization: Bearer ks_live_...\" \\\n -F \"[email protected]\" \\\n https://kernelscan.io/api/configs/uploads``\n returns ``{config_upload_id, sha256, size_bytes, expires_at}``.\n 2. Pass that ``config_upload_id`` into this tool.\n\n Uploads are per-user, single-use, and expire 30 minutes after upload.\n Same gates as POST /api/products: free can't create products; paid\n plans are capped at their resolved product limit — read it (and any\n per-account override) from ``whoami.product_limit`` rather than assuming\n a fixed per-tier number. ``factor_ids`` are silently ignored unless the\n plan allows security factors (``whoami.can_use_factors``). Re-using a\n product name returns 409.\n\n Creating a product RUNS an analysis, so it spends one unit of the\n team's SHARED monthly analysis allowance (``whoami.monthly_analyses_used``\n / ``monthly_analyses_limit``). When the allowance is exhausted the tool\n fails with \"Monthly analysis limit reached (…/month) [429]\". This is a\n durable monthly quota — NOT the transient per-call rate limit that also\n surfaces as 429: it will not clear until next month, so report it to the\n user instead of retrying. Check ``whoami`` before a batch of creates.\n ", "inputSchema": { "properties": { "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" }, "kernel_version": { "title": "Kernel Version", "type": "string" }, "name": { "title": "Name", "type": "string" } }, "required": [ "name", "kernel_version", "arch", "config_upload_id" ], "title": "create_productArguments", "type": "object" }, "name": "create_product", "outputSchema": null }, { "description": "Fetch a single Linux kernel CVE by ID (e.g. ``CVE-2024-12345``).\n\n No API key required: keyless callers get the public representation of a\n CVE, but only for CVEs in the public set (recent high-severity); any\n other id returns ``not found``. Free *keyed* callers get a 404 for CVEs\n published more than 60 days ago. AI risk-summary / analysis fields are\n included for any keyed user on CVEs in the public set, and for pro /\n enterprise on every assessed CVE.\n ", "inputSchema": { "properties": { "cve_id": { "title": "Cve Id", "type": "string" } }, "required": [ "cve_id" ], "title": "get_cveArguments", "type": "object" }, "name": "get_cve", "outputSchema": null }, { "description": "Fetch one product owned by the caller, including the CVE breakdown.\n\n Returns 404 (not 403) if the product belongs to another user, so\n product existence isn't leaked across accounts.\n ", "inputSchema": { "properties": { "product_id": { "title": "Product Id", "type": "string" } }, "required": [ "product_id" ], "title": "get_productArguments", "type": "object" }, "name": "get_product", "outputSchema": null }, { "description": "Return the VEX MANIFEST for one of the caller's products — metadata,\n not the document.\n\n Multi-megabyte CycloneDX documents (up to 8,000+ vulnerability entries)\n are not safe model-context payloads, so this tool returns a bounded\n manifest: CycloneDX format/spec version, product id, generated/expires\n timestamps, the VEX hash and the composite ETag identity, the\n uncompressed size in bytes, total + per-status vulnerability counts,\n and the authenticated REST download path. Reads from the 24h\n ProductVexCache; if the cache is empty/expired the next call to\n ``get_product`` (or the REST endpoint) will regenerate it.\n\n The MANIFEST carries the same ``kernelscan.io:exploit_maturity`` /\n ``kernelscan.io:kev`` overlay identity as the REST download\n (backend#337), so ETags compare across transports.\n\n To inspect the entries themselves, use ``list_product_vex_entries``.\n To retrieve the COMPLETE CycloneDX document, use the authenticated\n REST endpoint ``GET /api/products/{product_id}/vex`` (same ks_live_\n key) — that is the canonical way to retrieve the full artifact; no\n MCP tool returns it.\n ", "inputSchema": { "properties": { "product_id": { "title": "Product Id", "type": "string" } }, "required": [ "product_id" ], "title": "get_product_vexArguments", "type": "object" }, "name": "get_product_vex", "outputSchema": null }, { "description": "Page through the VEX vulnerability entries of one of the caller's products.\n\n Returns COMPLETE CycloneDX vulnerability objects for one bounded page\n — never the root document, never all entries — plus ``returned``,\n ``total_matching``, and a ``next_cursor`` to continue with. Every\n result is bounded to 256 KiB: the page stops before the byte limit and\n returns a cursor when necessary. Entries are ordered by CVE id\n (ascending) and carry the same live ``kernelscan.io:exploit_maturity``\n / ``kernelscan.io:kev`` properties as the REST download (backend#337).\n\n Filters (all optional, combinable):\n - ``statuses``: ``affected`` / ``not_affected`` / ``in_triage``\n - ``severities``: ``critical`` / ``high`` / ``medium`` / ``low`` / ``none``\n - ``kev``: true/false — CISA KEV listing only / non-KEV only\n - ``exploit_maturity``: ``poc`` / ``weaponized``\n - ``cve_ids``: exact-match list of CVE ids\n\n ``limit`` defaults to 25, maximum 100. ``cursor`` is the opaque\n continuation token from a previous page — it is tied to the product,\n the active filters, AND the current document + threat-overlay\n revision: changing filters, a regenerated cache, or a KEV/PoC signal\n that moved since the last page invalidates it (start a fresh page\n without a cursor — re-using a stale one is rejected, never silently\n re-applied). Within one revision, concatenating all pages yields\n each matching CVE exactly once.\n\n The COMPLETE multi-megabyte CycloneDX document is served by the\n authenticated REST endpoint ``GET /api/products/{product_id}/vex``\n (same ks_live_ key) — the canonical way to retrieve the full artifact.\n ", "inputSchema": { "properties": { "cursor": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Cursor" }, "cve_ids": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Cve Ids" }, "exploit_maturity": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Exploit Maturity" }, "kev": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ], "default": null, "title": "Kev" }, "limit": { "default": 25, "title": "Limit", "type": "integer" }, "product_id": { "title": "Product Id", "type": "string" }, "severities": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Severities" }, "statuses": { "anyOf": [ { "items": { "type": "string" }, "type": "array" }, { "type": "null" } ], "default": null, "title": "Statuses" } }, "required": [ "product_id" ], "title": "list_product_vex_entriesArguments", "type": "object" }, "name": "list_product_vex_entries", "outputSchema": null }, { "description": "List the calling user's products with denormalized analysis stats.\n\n Paid plans only (basic / pro / enterprise). Free callers get a clear\n upgrade message.\n ", "inputSchema": { "properties": {}, "title": "list_productsArguments", "type": "object" }, "name": "list_products", "outputSchema": { "properties": { "result": { "items": { "additionalProperties": true, "type": "object" }, "title": "Result", "type": "array" } }, "required": [ "result" ], "title": "list_productsOutput", "type": "object" } }, { "description": "Explain how to get a KernelScan account (no API key needed).\n\n Self-registration is open — there is no invitation to wait for and no\n admin in the loop. The user signs up on kernelscan.io themselves (email\n + password, accepting the terms), confirms the verification mail, and\n mints a ks_live_ API key on their account page.\n\n This tool only hands that path back: it files nothing and sends no\n mail. ``email`` / ``name`` / ``reason`` are still accepted so older\n clients don't break, but they are ignored — never tell the user that a\n request was submitted on their behalf.\n ", "inputSchema": { "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", "type": "object" }, "name": "request_access", "outputSchema": null }, { "description": "Search Linux kernel CVEs.\n\n No API key required: keyless callers get the free public tier — recent\n high-severity Linux kernel CVEs (capped at 25 results). Free *keyed*\n callers see only CVEs published in the last 60 days; basic+ keyed\n callers get the full corpus.\n ``query`` matches against CVE id and description (case-insensitive).\n ``severity`` filters by effective severity (``critical``/``high``/``medium``/``low``).\n ``cvss_min`` filters by effective CVSS score.\n ``published_after`` (ISO 8601) returns only CVEs newer than that date.\n Returns up to ``limit`` (max 100) CVEs, newest first.\n ", "inputSchema": { "properties": { "cvss_min": { "anyOf": [ { "type": "number" }, { "type": "null" } ], "default": null, "title": "Cvss Min" }, "limit": { "default": 25, "title": "Limit", "type": "integer" }, "published_after": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Published After" }, "query": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Query" }, "severity": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Severity" } }, "title": "search_cvesArguments", "type": "object" }, "name": "search_cves", "outputSchema": null }, { "description": "Send a support / dispute report to KernelScan staff.\n\n Use this when an automated CVE or factor assessment looks wrong, or\n when you need to hand human-needed context back to the team. The\n caller's API-key user is attached automatically (id, email, plan)\n so support can look the account up.\n\n ``category`` should be one of:\n - ``cve_assessment`` — wrong AI verdict / CVSS / CWE on a CVE\n - ``factor_assessment`` — wrong factor verdict for a product\n - ``bug`` — broken behavior in the API or UI\n - ``other`` — anything else\n\n ``cve_id`` / ``product_id`` / ``assessment_id`` are optional but\n recommended — they let support jump straight to the relevant row.\n ", "inputSchema": { "properties": { "assessment_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Assessment Id" }, "category": { "title": "Category", "type": "string" }, "cve_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Cve Id" }, "message": { "title": "Message", "type": "string" }, "product_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Product Id" }, "subject": { "title": "Subject", "type": "string" } }, "required": [ "category", "subject", "message" ], "title": "submit_support_reportArguments", "type": "object" }, "name": "submit_support_report", "outputSchema": null }, { "description": "Update a product owned by the caller. Re-runs analysis if the\n kernel_version, arch, or referenced .config changed.\n\n To change the .config, first POST the new file to\n ``/api/configs/uploads`` (see ``create_product`` for the curl recipe)\n and pass the returned ``config_upload_id`` here. Leave\n ``config_upload_id`` as ``None`` to keep the existing .config.\n ``factor_ids=None`` leaves factor selections untouched; an empty\n list clears them. Same tier gates as PUT /api/products/{id}.\n\n A change that re-runs analysis (``kernel_version``, ``arch``, or the\n ``.config``) spends one unit of the team's shared monthly analysis\n allowance and can fail with the same durable \"Monthly analysis limit\n reached … [429]\" quota error as ``create_product`` (distinct from the\n transient rate-limit 429 — don't retry it). A rename / description /\n factor-only edit runs no analysis and is free.\n ", "inputSchema": { "properties": { "arch": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Arch" }, "config_upload_id": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Config Upload Id" }, "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" }, "kernel_version": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Kernel Version" }, "name": { "anyOf": [ { "type": "string" }, { "type": "null" } ], "default": null, "title": "Name" }, "product_id": { "title": "Product Id", "type": "string" } }, "required": [ "product_id" ], "title": "update_productArguments", "type": "object" }, "name": "update_product", "outputSchema": null }, { "description": "Return the caller's identity, plan, and quota state.\n\n Works without an API key: keyless callers get a lightweight public-tier\n payload (no account) describing how to request access.\n ", "inputSchema": { "properties": {}, "title": "whoamiArguments", "type": "object" }, "name": "whoami", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:8ff182d582c13edcc20bf93c0ac8a6b0728b9e065f37cb8982323b9b5f5e5bae | sha256sum